diff --git a/.github/workflows/maven-publish-snapshot.yml b/.github/workflows/maven-publish-snapshot.yml new file mode 100644 index 00000000..27628dd4 --- /dev/null +++ b/.github/workflows/maven-publish-snapshot.yml @@ -0,0 +1,42 @@ +# This workflow will build a package using Maven and then publish it to GitHub packages when a PR is accepted/new content is pushed +# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path + +name: Maven Publish Snapshot + +on: + workflow_dispatch: + push: + branches: + - development + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Build with Maven + run: mvn -B package --file pom.xml + + - name: Delete old sdk package + uses: actions/delete-package-versions@v3 + continue-on-error: true + with: + package-name: 'org.eclipse.basyx.basyx.sdk' + + - name: Publish to GitHub Packages Apache Maven + run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.gitignore b/.gitignore index e0e5af10..42281a30 100644 --- a/.gitignore +++ b/.gitignore @@ -69,4 +69,7 @@ local.properties # Scala IDE specific (Scala & Java development for Eclipse) .cache-main .scala_dependencies -.worksheet \ No newline at end of file +.worksheet + +.idea +*.iml diff --git a/LICENSE b/LICENSE index e23ece2c..014071fd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,277 +1,18 @@ -Eclipse Public License - v 2.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 content - 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 changes or additions to the Program that - are not Modified Works. - -"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 -or any Secondary License (as applicable), including Contributors. - -"Derivative Works" shall mean any work, whether in Source Code or other -form, that is based on (or derived from) the Program and for which the -editorial revisions, annotations, elaborations, or other modifications -represent, as a whole, an original work of authorship. - -"Modified Works" shall mean any work in Source Code or other form that -results from an addition to, deletion from, or modification of the -contents of the Program, including, for purposes of clarity any new file -in Source Code form that contains any contents of the Program. Modified -Works shall not include works that contain only declarations, -interfaces, types, classes, structures, or files of the Program solely -in each case in order to link to, bind by name, or subclass the Program -or Modified Works thereof. - -"Distribute" means the acts of a) distributing or b) making available -in any manner that enables the transfer of a copy. - -"Source Code" means the form of a Program preferred for making -modifications, including but not limited to software source code, -documentation source, and configuration files. - -"Secondary License" means either the GNU General Public License, -Version 2.0, or any later versions of that license, including any -exceptions or additional permissions as identified by the initial -Contributor. - -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. - - 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 or other 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. - - e) Notwithstanding the terms of any Secondary License, no - Contributor makes additional grants to any Recipient (other than - those set forth in this Agreement) as a result of such Recipient's - receipt of the Program under the terms of a Secondary License - (if permitted under the terms of Section 3). - -3. REQUIREMENTS - -3.1 If a Contributor Distributes the Program in any form, then: - - a) the Program must also be made available as Source Code, in - accordance with section 3.2, and the Contributor must accompany - the Program with a statement that the Source Code for the Program - is available under this Agreement, and informs Recipients how to - obtain it in a reasonable manner on or through a medium customarily - used for software exchange; and - - b) the Contributor may Distribute the Program under a license - different than this Agreement, provided that such license: - i) effectively disclaims on behalf of all other 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 other Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - - iii) does not attempt to limit or alter the recipients' rights - in the Source Code under section 3.2; and - - iv) requires any subsequent distribution of the Program by any - party to be under a license that satisfies the requirements - of this section 3. - -3.2 When the Program is Distributed as Source Code: - - a) it must be made available under this Agreement, or if the - Program (i) is combined with other material in a separate file or - files made available under a Secondary License, and (ii) the initial - Contributor attached to the Source Code the notice described in - Exhibit A of this Agreement, then the Program may be made available - under the terms of such Secondary Licenses, and - - b) a copy of this Agreement must be included with each copy of - the Program. - -3.3 Contributors may not remove or alter any copyright, patent, -trademark, attribution notices, disclaimers of warranty, or limitations -of liability ("notices") contained within the Program from any copy of -the Program which they Distribute, provided that Contributors may add -their own appropriate notices. - -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, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, 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, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, 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. Nothing in this Agreement is intended -to be enforceable by any entity that is not a Contributor or Recipient. -No third-party beneficiary rights are created under this Agreement. - -Exhibit A - Form of Secondary Licenses Notice - -"This Source Code may also be made available under the following -Secondary Licenses when the conditions for such availability set forth -in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), -version(s), and exceptions or additional permissions here}." - - Simply including a copy of this Agreement, including this Exhibit A - is not sufficient to license the Source Code under Secondary Licenses. - - If it is not possible or desirable to put the notice in a particular - file, then You may include the notice in a location (such as a LICENSE - file in a relevant directory) where a recipient would be likely to - look for such a notice. - - You may add additional accurate notices of copyright ownership. \ No newline at end of file +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/NOTICE b/NOTICE index 41bc3278..e0fe73c7 100644 --- a/NOTICE +++ b/NOTICE @@ -6,10 +6,26 @@ of Education and Research (BMBF), grant number 01IS16022. ## Declared Project Licenses -This program and the accompanying materials are made available under the terms of the Eclipse Public License v. 2.0 which is available at -https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html - -SPDX-License-Identifier: EPL-2.0 +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. + +SPDX-License-Identifier: MIT ## Source Code diff --git a/README.md b/README.md index d3150a7e..33a30dc6 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,4 @@ Additionally, you can also find videos explaining the BaSyx middleware on youtub If you would like to contribute, please notice the [contribution guidelines](CONTRIBUTING.md). The overall process is described in the [Eclipse wiki](https://wiki.eclipse.org/BaSyx_/_Developer_/_Contributing). -This GitHub project is migrated from the Eclipse infrastructure. For the archived history, see the [previous repository](https://git.eclipse.org/c/basyx/basyx.git/). +This GitHub project is migrated from the Eclipse infrastructure. For the archived history, see the [previous repository](https://git.eclipse.org/c/basyx/basyx.git/). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 29433b27..b197dbc6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,15 +5,15 @@ org.eclipse.basyx basyx.sdk - 1.0.2 + 1.1.0 BaSyx SDK BaSyx Software Development Kit https://www.eclipse.org/basyx/ - Eclipse Public License 2.0 - https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + MIT + https://opensource.org/licenses/MIT @@ -33,11 +33,20 @@ https://github.com/eclipse-basyx/basyx-java-sdk + + + github + GitHub Eclipse BaSyx Apache Maven Packages + https://maven.pkg.github.com/eclipse-basyx/basyx-java-sdk + + + jar UTF-8 UTF-8 + 5.5.3 @@ -46,11 +55,6 @@ Eclipse Paho Repo https://repo.eclipse.org/content/repositories/paho-releases/ - - - bintray - https://jcenter.bintray.com - @@ -168,12 +172,20 @@ 4.13.1 test - + + + + org.mockito + mockito-core + 4.1.0 + test + + io.moquette moquette-broker - 0.12.1 + 0.15 test @@ -187,14 +199,14 @@ org.eclipse.milo sdk-client - 0.3.6 + 0.6.1 org.eclipse.milo sdk-server - 0.3.6 + 0.6.1 @@ -241,9 +253,9 @@ - ch.qos.logback - logback-classic - 1.2.3 + ch.qos.logback + logback-classic + 1.2.3 @@ -267,7 +279,63 @@ 2.8.5 + + + commons-io + commons-io + 2.6 + + + + + commons-fileupload + commons-fileupload + 1.4 + + + + + org.apache.httpcomponents + httpmime + 4.5.13 + + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.springframework.security + spring-security-oauth2-resource-server + + + org.springframework.security + spring-security-oauth2-jose + + + + + + org.springframework.security + spring-security-bom + ${spring-security-version} + pom + import + + + + @@ -318,7 +386,6 @@ true - diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java b/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java index c3f7810b..0b56404e 100644 --- a/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregator.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.aggregator; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; @@ -23,9 +38,10 @@ import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory; +import org.eclipse.basyx.submodel.aggregator.SubmodelAggregatorFactory; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; -import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; @@ -33,63 +49,64 @@ /** * An implementation of the IAASAggregator interface using maps internally - * + * * @author conradi, schnicke * */ public class AASAggregator implements IAASAggregator { - protected Map aasProviderMap = new HashMap<>(); + protected Map aasProviderMap = new LinkedHashMap<>(); protected IAASRegistry registry; /** * Store AAS API Provider. By default, uses the VAB API Provider */ - protected IAASAPIFactory aasApiProvider; + protected IAASAPIFactory aasApiFactory; + + protected ISubmodelAggregatorFactory submodelAggregatorFactory; + + public AASAggregator(IAASAPIFactory aasApiFactory, ISubmodelAggregatorFactory submodelAggregatorFactory) { + this.aasApiFactory = aasApiFactory; + this.submodelAggregatorFactory = submodelAggregatorFactory; + } + + public AASAggregator(IAASAPIFactory aasApiFactory, ISubmodelAggregatorFactory submodelAggregatorFactory, IAASRegistry registry) { + this(aasApiFactory, submodelAggregatorFactory); + this.registry = registry; + } /** - * Store Submodel API Provider. By default, uses the VAB Submodel Provider + * Constructs AAS Aggregator using the passed registry. This registry is used to + * resolve requests for remote submodels. Additionally takes custom API + * providers; */ - protected ISubmodelAPIFactory smApiProvider; + public AASAggregator(IAASAPIFactory aasApiFactory, ISubmodelAPIFactory submodelApiFactory, IAASRegistry registry) { + this(aasApiFactory, new SubmodelAggregatorFactory(submodelApiFactory), registry); + } /** * Constructs default AAS Aggregator */ public AASAggregator() { - this.aasApiProvider = new VABAASAPIFactory(); - this.smApiProvider = new VABSubmodelAPIFactory(); + this(new VABAASAPIFactory(), new SubmodelAggregatorFactory()); } /** * Constructs an AAS aggregator with custom API providers */ - public AASAggregator(IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider) { - this.aasApiProvider = aasApiProvider; - this.smApiProvider = smApiProvider; + public AASAggregator(IAASAPIFactory aasApiFactory, ISubmodelAPIFactory submodelApiFactory) { + this(aasApiFactory, new SubmodelAggregatorFactory(submodelApiFactory)); } /** * Constructs AAS Aggregator using the passed registry. This registry is used to * resolve requests for remote submodels - * + * * @param registry */ public AASAggregator(IAASRegistry registry) { - this.registry = registry; - this.aasApiProvider = new VABAASAPIFactory(); - this.smApiProvider = new VABSubmodelAPIFactory(); - } - - /** - * Constructs AAS Aggregator using the passed registry. This registry is used to - * resolve requests for remote submodels. Additionally takes custom API providers; - */ - public AASAggregator(IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider, - IAASRegistry registry) { - this.registry = registry; - this.aasApiProvider = aasApiProvider; - this.smApiProvider = smApiProvider; + this(new VABAASAPIFactory(), new SubmodelAggregatorFactory(), registry); } @SuppressWarnings("unchecked") @@ -128,16 +145,21 @@ public void createAAS(AssetAdministrationShell aas) { @Override public void updateAAS(AssetAdministrationShell aas) { - aasProviderMap.put(aas.getIdentification().getId(), createMultiSubmodelProvider(aas)); + MultiSubmodelProvider oldProvider = (MultiSubmodelProvider) getAASProvider(aas.getIdentification()); + IAASAPI aasApi = aasApiFactory.create(aas); + AASModelProvider contentProvider = new AASModelProvider(aasApi); + IConnectorFactory connectorFactory = oldProvider.getConnectorFactory(); + + MultiSubmodelProvider updatedProvider = new MultiSubmodelProvider(contentProvider, registry, connectorFactory, aasApiFactory, oldProvider.getSmAggregator()); + + aasProviderMap.put(aas.getIdentification().getId(), updatedProvider); } private MultiSubmodelProvider createMultiSubmodelProvider(AssetAdministrationShell aas) { - IConnectorFactory connProvider = new HTTPConnectorFactory(); - IAASAPI aasApi = aasApiProvider.getAASApi(aas); + IConnectorFactory connectorFactory = new HTTPConnectorFactory(); + IAASAPI aasApi = aasApiFactory.create(aas); AASModelProvider contentProvider = new AASModelProvider(aasApi); - MultiSubmodelProvider multiAASProvider = new MultiSubmodelProvider(contentProvider, registry, - connProvider, smApiProvider, aasApiProvider); - return multiAASProvider; + return new MultiSubmodelProvider(contentProvider, registry, connectorFactory, aasApiFactory, submodelAggregatorFactory.create()); } @Override @@ -152,7 +174,7 @@ public IModelProvider getAASProvider(IIdentifier aasId) { if (provider == null) { throw new ResourceNotFoundException("AAS with Id " + aasId.getId() + " does not exist"); } - return provider; } + } diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregatorAPIHelper.java b/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregatorAPIHelper.java new file mode 100644 index 00000000..6481fe5a --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregatorAPIHelper.java @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.aggregator; + +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; + +/** + * API helper for AAS Aggregator + * + * @author haque + * + */ +public class AASAggregatorAPIHelper { + public static final String AAS_SUFFIX = "aas"; + + public static String getAggregatorPath() { + return AASAggregatorProvider.PREFIX; + } + + /** + * Retrieves access path for creating, updating, deleting single AAS + * + * @param aasId + * @return + */ + public static String getAASEntryPath(IIdentifier aasId) { + return VABPathTools.concatenatePaths(getAggregatorPath(), VABPathTools.encodePathElement(aasId.getId())); + } + + /** + * Retrieves access path for getting single AAS + * + * @param aasId + * @return + */ + public static String getAASAccessPath(IIdentifier aasId) { + return VABPathTools.concatenatePaths(getAASEntryPath(aasId), AASAggregatorAPIHelper.AAS_SUFFIX); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregatorFactory.java b/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregatorFactory.java new file mode 100644 index 00000000..b0760bb1 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/AASAggregatorFactory.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.aggregator; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregatorFactory; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; + +/** + * + * Factory that constructs a AASAggregator with the given API + * + * @author fried + * + */ +public class AASAggregatorFactory implements IAASAggregatorFactory { + + private IAASAPIFactory aasApiFactory; + private ISubmodelAggregatorFactory submodelAggregatorFactory; + private IAASRegistry registry; + private ISubmodelAPIFactory submodelApiFactory; + + public AASAggregatorFactory() { + } + + public AASAggregatorFactory(IAASAPIFactory aasApiFactory, ISubmodelAggregatorFactory submodelAggregatorFactory) { + this.aasApiFactory = aasApiFactory; + this.submodelAggregatorFactory = submodelAggregatorFactory; + } + + public AASAggregatorFactory(IAASAPIFactory aasApiFactory, ISubmodelAggregatorFactory submodelAggregatorFactory, IAASRegistry registry) { + this.aasApiFactory = aasApiFactory; + this.submodelAggregatorFactory = submodelAggregatorFactory; + this.registry = registry; + } + + public AASAggregatorFactory(IAASAPIFactory aasApiFactory, ISubmodelAPIFactory submodelApiFactory) { + this.aasApiFactory = aasApiFactory; + this.submodelApiFactory = submodelApiFactory; + } + + public AASAggregatorFactory(IAASAPIFactory aasApiFactory, ISubmodelAPIFactory submodelApiFactory, IAASRegistry registry) { + this.aasApiFactory = aasApiFactory; + this.submodelApiFactory = submodelApiFactory; + this.registry = registry; + } + + public AASAggregatorFactory(IAASRegistry registry) { + this.registry = registry; + } + + @Override + public IAASAggregator create() { + return constructAASAggregatorWithGivenArguments(); + } + + private IAASAggregator constructAASAggregatorWithGivenArguments() { + if (isRegistrySet() && isAasApiAndSubmodelAggregatorSet()) { + return new AASAggregator(aasApiFactory, submodelAggregatorFactory, registry); + } else if (isRegistrySet() && isAasApiAndSubmodelApiSet()) { + return new AASAggregator(aasApiFactory, submodelApiFactory, registry); + } else if (isOnlyRegistrySet()) { + return new AASAggregator(registry); + } else if (isAasApiAndSubmodelAggregatorSet()) { + return new AASAggregator(aasApiFactory, submodelAggregatorFactory); + } else if (isAasApiAndSubmodelApiSet()) { + return new AASAggregator(aasApiFactory, submodelApiFactory); + } else { + return new AASAggregator(); + } + } + + private boolean isRegistrySet() { + return registry != null; + } + + private boolean isAasApiAndSubmodelAggregatorSet() { + return aasApiFactory != null && submodelAggregatorFactory != null; + } + + private boolean isAasApiAndSubmodelApiSet() { + return aasApiFactory != null && submodelApiFactory != null; + } + + private boolean isOnlyRegistrySet() { + return isRegistrySet() && aasApiFactory == null && submodelAggregatorFactory == null && submodelApiFactory == null; + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java b/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java index a8241e25..20ec9ade 100644 --- a/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregator.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.aggregator.api; @@ -17,7 +32,6 @@ import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; - /** * Interface for the Asset Administration Shell Aggregator API
* It is used to manage multiple AASs at the same endpoint @@ -26,26 +40,28 @@ * */ public interface IAASAggregator { - + /** * Retrieves all Asset Administration Shells from the endpoint * * @return a List of all found Asset Administration Shells */ public Collection getAASList(); - + /** * Retrieves a specific Asset Administration Shell * - * @param aasId the ID of the AAS + * @param aasId + * the ID of the AAS * @return the requested AAS */ public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException; - + /** * Retrieves the provider for a specific Asset Administration Shell * - * @param aasId the ID of the AAS + * @param aasId + * the ID of the AAS * @return the requested AAS provider */ public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException; @@ -53,21 +69,24 @@ public interface IAASAggregator { /** * Creates a new Asset Administration Shell at the endpoint * - * @param aas the AAS to be created + * @param aas + * the AAS to be created */ public void createAAS(AssetAdministrationShell aas); - + /** * Updates a specific Asset Administration Shell * - * @param aas the updated AAS + * @param aas + * the updated AAS */ public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException; - + /** * Deletes a specific Asset Administration Shell * - * @param aasId the ID of the AAS to be deleted + * @param aasId + * the ID of the AAS to be deleted */ public void deleteAAS(IIdentifier aasId); diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregatorFactory.java b/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregatorFactory.java new file mode 100644 index 00000000..e86fca03 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/api/IAASAggregatorFactory.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.aggregator.api; + +/** + * + * Interface for providing an AASAggregator + * + * @author fried + * + */ +public interface IAASAggregatorFactory { + /** + * Creates an AASAggregator for the Factory + * + * @return constructed AASAggregator + */ + public IAASAggregator create(); +} diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/observing/IAASAggregatorObserver.java b/src/main/java/org/eclipse/basyx/aas/aggregator/observing/IAASAggregatorObserver.java new file mode 100644 index 00000000..a455bbf0 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/observing/IAASAggregatorObserver.java @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.aggregator.observing; + +import org.eclipse.basyx.submodel.observer.IObserver; + +/** + * Interface for an observer of {@link ObservableAASAggregator} + * + * @author haque + * + */ +public interface IAASAggregatorObserver extends IObserver { + + /** + * Is called when an AAS is created + * + * @param aasId + * id of the created AAS + */ + public void aasCreated(String aasId); + + /** + * Is called when an AAS is updated + * + * @param aasId + * id of the updated AAS + */ + public void aasUpdated(String aasId); + + /** + * Is called when an AAS is deleted + * + * @param aasId + * id of the deleted AAS + */ + public void aasDeleted(String aasId); +} diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/observing/ObservableAASAggregator.java b/src/main/java/org/eclipse/basyx/aas/aggregator/observing/ObservableAASAggregator.java new file mode 100644 index 00000000..43b5a1dd --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/observing/ObservableAASAggregator.java @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.aggregator.observing; + +import java.util.Collection; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.observer.Observable; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; + +/** + * + * Implementation of {@link IAASAggregator} that calls back registered + * {@link IAASAggregatorObserver} when changes on AAS occur + * + * @author haque + * + */ +public class ObservableAASAggregator extends Observable implements IAASAggregator { + + private IAASAggregator aasAggregator; + + public ObservableAASAggregator(IAASAggregator aggregator) { + this.aasAggregator = aggregator; + } + + @Override + public Collection getAASList() { + return aasAggregator.getAASList(); + } + + @Override + public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException { + return aasAggregator.getAAS(aasId); + } + + @Override + public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException { + return aasAggregator.getAASProvider(aasId); + } + + @Override + public void createAAS(AssetAdministrationShell aas) { + aasAggregator.createAAS(aas); + observers.stream().forEach(o -> o.aasCreated(aas.getIdentification().getId())); + } + + @Override + public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException { + aasAggregator.updateAAS(aas); + observers.stream().forEach(o -> o.aasUpdated(aas.getIdentification().getId())); + } + + @Override + public void deleteAAS(IIdentifier aasId) { + aasAggregator.deleteAAS(aasId); + observers.stream().forEach(o -> o.aasDeleted(aasId.getId())); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java b/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java index c3fc9a72..cc44d33f 100644 --- a/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/proxy/AASAggregatorProxy.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.aggregator.proxy; @@ -13,6 +28,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.basyx.aas.aggregator.AASAggregatorAPIHelper; import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; @@ -29,9 +45,9 @@ import org.slf4j.LoggerFactory; public class AASAggregatorProxy implements IAASAggregator { + protected IModelProvider provider; private static Logger logger = LoggerFactory.getLogger(AASRegistryProxy.class); - private IModelProvider provider; - + /** * Constructor for an AAS aggregator proxy based on a HTTP connection * @@ -53,19 +69,19 @@ public AASAggregatorProxy(IModelProvider provider) { } /** - * Adds the "/shells" suffix if it does not exist + * Removes the "/shells" suffix if it exists * * @param url * @return */ - private static String harmonizeURL(String url) { - return VABPathTools.harmonizePathWithSuffix(url, AASAggregatorProvider.PREFIX); + protected static String harmonizeURL(String url) { + return VABPathTools.stripFromPath(url, AASAggregatorProvider.PREFIX); } @SuppressWarnings("unchecked") @Override public Collection getAASList() { - Collection> collection = (Collection>) provider.getValue(""); + Collection> collection = (Collection>) provider.getValue(AASAggregatorAPIHelper.getAggregatorPath()); logger.debug("Getting all AAS"); return collection.stream().map(m -> AssetAdministrationShell.createAsFacade(m)).map(aas -> getConnectedAAS(aas.getIdentification(), aas)).collect(Collectors.toList()); } @@ -89,38 +105,32 @@ private ConnectedAssetAdministrationShell getConnectedAAS(IIdentifier aasId, Ass return new ConnectedAssetAdministrationShell(proxy, localCopy); } - private VABElementProxy getAASProxy(IIdentifier aasId) { - String path = VABPathTools.concatenatePaths(getEncodedIdentifier(aasId), "aas"); + String path = AASAggregatorAPIHelper.getAASAccessPath(aasId); VABElementProxy proxy = new VABElementProxy(path, provider); return proxy; } @Override public void createAAS(AssetAdministrationShell aas) { - provider.setValue(getEncodedIdentifier(aas.getIdentification()), aas); + provider.setValue(AASAggregatorAPIHelper.getAASEntryPath(aas.getIdentification()), aas); logger.info("AAS with Id " + aas.getIdentification().getId() + " created"); } @Override public void updateAAS(AssetAdministrationShell aas) { - provider.setValue(getEncodedIdentifier(aas.getIdentification()), aas); + provider.setValue(AASAggregatorAPIHelper.getAASEntryPath(aas.getIdentification()), aas); logger.info("AAS with Id " + aas.getIdentification().getId() + " updated"); } @Override public void deleteAAS(IIdentifier aasId) { - provider.deleteValue(getEncodedIdentifier(aasId)); + provider.deleteValue(AASAggregatorAPIHelper.getAASEntryPath(aasId)); logger.info("AAS with Id " + aasId.getId() + " deleted"); } @Override public IModelProvider getAASProvider(IIdentifier aasId) { - return new VABElementProxy(getEncodedIdentifier(aasId), provider); + return new VABElementProxy(AASAggregatorAPIHelper.getAASEntryPath(aasId), provider); } - - private String getEncodedIdentifier(IIdentifier aasId) { - return VABPathTools.encodePathElement(aasId.getId()); - } - } diff --git a/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java b/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java index 1c751ece..739638da 100644 --- a/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java +++ b/src/main/java/org/eclipse/basyx/aas/aggregator/restapi/AASAggregatorProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.aggregator.restapi; @@ -33,7 +48,7 @@ */ public class AASAggregatorProvider implements IModelProvider { - private IAASAggregator aggregator; + protected IAASAggregator aggregator; public static final String PREFIX = "shells"; @@ -49,7 +64,7 @@ public AASAggregatorProvider(IAASAggregator aggregator) { * @return * @throws MalformedRequestException */ - private String stripPrefix(String path) throws MalformedRequestException { + protected String stripPrefix(String path) throws MalformedRequestException { path = VABPathTools.stripSlashes(path); if (!path.startsWith(PREFIX)) { throw new MalformedRequestException("Path " + path + " not recognized as aggregator path. Has to start with " + PREFIX); diff --git a/src/main/java/org/eclipse/basyx/aas/bundle/AASBundle.java b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundle.java new file mode 100644 index 00000000..1ee4ccdc --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundle.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.bundle; + +import java.util.Objects; +import java.util.Set; + +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; + +/** + * Helper class to bundle an AAS with its corresponding submodels, e.g. for + * passing them to a server environment + * + * @author schnicke + * + */ +public class AASBundle { + private IAssetAdministrationShell aas; + private Set submodels; + + public AASBundle(IAssetAdministrationShell aas, Set submodels) { + super(); + this.aas = aas; + this.submodels = submodels; + } + + public IAssetAdministrationShell getAAS() { + return aas; + } + + public Set getSubmodels() { + return submodels; + } + + @Override + public int hashCode() { + return Objects.hash(aas, submodels); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AASBundle other = (AASBundle) obj; + return Objects.equals(this.aas, other.aas) && Objects.equals(this.submodels, other.submodels); + } + + @Override + public String toString() { + return "AASBundle [aas=" + aas + ", submodels=" + submodels + "]"; + } + +} diff --git a/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleDescriptorFactory.java b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleDescriptorFactory.java new file mode 100644 index 00000000..66d0d741 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleDescriptorFactory.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.bundle; + +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; + +/** + * Helper class that supports AASDescriptor utilization for an AASBundle + * + * @author schnicke + * + */ +public class AASBundleDescriptorFactory { + /** + * Creates the AASDescriptor for the given bundle and aasAggregatorPath + * aasAggregatorPath is normalized before the descriptor is created + * + * @param bundle + * @param aasAggregatorPath + * @return + */ + public static AASDescriptor createAASDescriptor(AASBundle bundle, String aasAggregatorPath) { + String nHostBasePath = normalizeAggregatorPrefix(aasAggregatorPath); + return createAASDescriptorUnchecked(bundle, nHostBasePath); + } + + private static String normalizeAggregatorPrefix(String aasAggregatorPath) { + String nHostBasePath = VABPathTools.stripSlashes(aasAggregatorPath); + if (AASAggregatorProvider.PREFIX.equals(VABPathTools.getLastElement(nHostBasePath))) + return nHostBasePath; + return VABPathTools.append(nHostBasePath, AASAggregatorProvider.PREFIX); + } + + private static AASDescriptor createAASDescriptorUnchecked(AASBundle bundle, String nHostBasePath) { + String endpointId = bundle.getAAS().getIdentification().getId(); + endpointId = VABPathTools.encodePathElement(endpointId); + String aasBase = VABPathTools.concatenatePaths(nHostBasePath, endpointId, "aas"); + AASDescriptor desc = new AASDescriptor(bundle.getAAS(), aasBase); + bundle.getSubmodels().stream().forEach(s -> { + SubmodelDescriptor smDesc = new SubmodelDescriptor(s, VABPathTools.concatenatePaths(aasBase, "submodels", s.getIdShort(), "submodel")); + desc.addSubmodelDescriptor(smDesc); + }); + return desc; + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleFactory.java b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleFactory.java new file mode 100644 index 00000000..623d0c76 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleFactory.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.aas.bundle; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory for creation of AASBundles from Sets of AAS, Submodels and Assets + * + * @author schnicke + * + */ +public class AASBundleFactory { + private static Logger logger = LoggerFactory.getLogger(AASBundleFactory.class); + + /** + * Creates from a collection of AAS, Submodels and Assets the appropriate set of + * AASBundles + * + * @param shells + * @param submodels + * @param assets + * @return + */ + public Set create(Collection shells, Collection submodels, Collection assets) { + Set bundles = new HashSet<>(); + + for (IAssetAdministrationShell shell : shells) { + if (shouldSetAsset(shell)) { + setAsset(assets, shell); + } + + // Retrieve submodels + Set currentSM = retrieveSubmodelsForAAS(submodels, shell); + bundles.add(new AASBundle(shell, currentSM)); + } + + return bundles; + } + + private boolean shouldSetAsset(IAssetAdministrationShell shell) { + return shell.getAsset() == null && shell.getAssetReference() != null; + } + + private void setAsset(Collection assets, IAssetAdministrationShell shell) { + // Retrieve asset + try { + IReference assetRef = shell.getAssetReference(); + IAsset asset = getByReference(assetRef, assets); + ((AssetAdministrationShell) shell).setAsset((Asset) asset); + } catch (ResourceNotFoundException e) { + // Enables parsing external aasx-files without any keys in assetref + if (shell.getAssetReference().getKeys().size() > 0) { + logger.warn("Can't find asset with id " + shell.getAssetReference().getKeys().get(0).getValue() + " for AAS " + shell.getIdShort() + "; If the asset is not provided in another way, this is an error!"); + } else { + logger.warn("Can't find asset for AAS " + shell.getIdShort() + "; If the asset is not provided in another way, this is an error!"); + } + } + } + + /** + * Retrieves the Submodels belonging to an AAS + * + * @param submodels + * @param shell + * @return + */ + private Set retrieveSubmodelsForAAS(Collection submodels, IAssetAdministrationShell shell) { + Set currentSM = new HashSet<>(); + + for (IReference submodelRef : shell.getSubmodelReferences()) { + try { + ISubmodel sm = getByReference(submodelRef, submodels); + currentSM.add(sm); + logger.debug("Found Submodel " + sm.getIdShort() + " for AAS " + shell.getIdShort()); + } catch (ResourceNotFoundException e) { + // If there's no match, the submodel is assumed to be provided by different + // means, e.g. it is already being hosted + logger.warn("Could not find Submodel " + submodelRef.getKeys().get(0).getValue() + " for AAS " + shell.getIdShort() + "; If it is not hosted elsewhere this is an error!"); + } + } + return currentSM; + } + + /** + * Retrieves an identifiable from a list of identifiable by its reference + * + * @param submodelRef + * @param identifiable + * @return + * @throws ResourceNotFoundException + */ + private T getByReference(IReference ref, Collection identifiable) throws ResourceNotFoundException { + IKey lastKey = null; + // It may be that only one key fits to the Submodel contained in the XML + for (IKey key : ref.getKeys()) { + lastKey = key; + // There will only be a single submodel matching the identification at max + Optional match = identifiable.stream().filter(s -> s.getIdentification().getId().equals(key.getValue())).findFirst(); + if (match.isPresent()) { + return match.get(); + } + } + if (lastKey == null) { + throw new ResourceNotFoundException("Could not resolve reference without keys"); + } else { + throw new ResourceNotFoundException("Could not resolve reference with last key '" + lastKey.getValue() + "'"); + } + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleHelper.java b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleHelper.java new file mode 100644 index 00000000..fb8b35db --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/bundle/AASBundleHelper.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.bundle; + +import java.util.Collection; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.SubmodelProvider; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class can be used to check if all required resources are present on a + * server
+ * (e.g. after a restart) and upload them if necessary. + * + * @author conradi + * + */ +public class AASBundleHelper { + + private static Logger logger = LoggerFactory.getLogger(AASBundleHelper.class); + + /** + * Checks (by ID) if all AASs/SMs contained
+ * in the given AASBundles exist in the AASAggregator.
+ * Adds missing ones to the Aggregator.
+ * If a given object already exists in the Aggregator it will NOT be replaced. + * + * @param aggregator + * the Aggregator to be populated + * @param bundles + * the AASBundles + * @return true if an AAS/SM was uploaded; false otherwise + */ + public static boolean integrate(IAASAggregator aggregator, Collection bundles) { + + if (aggregator == null || bundles == null) { + throw new RuntimeException("'aggregator' and 'bundles' must not be null."); + } + + boolean objectUploaded = false; + + for (AASBundle bundle : bundles) { + IAssetAdministrationShell aas = bundle.getAAS(); + + try { + aggregator.getAAS(aas.getIdentification()); + // If no ResourceNotFoundException occurs, AAS exists on server + // -> no further action required + } catch (ResourceNotFoundException e) { + // AAS does not exist and needs to be pushed to the server + // Cast Interface to concrete class + if (aas instanceof AssetAdministrationShell) { + aggregator.createAAS((AssetAdministrationShell) aas); + objectUploaded = true; + } else { + throw new RuntimeException("aas Objects in bundles need to be instance of 'AssetAdministrationShell'"); + } + } + + IModelProvider provider = aggregator.getAASProvider(aas.getIdentification()); + for (ISubmodel sm : bundle.getSubmodels()) { + try { + provider.getValue("/aas/submodels/" + sm.getIdShort() + "/" + SubmodelProvider.SUBMODEL); + // If no ResourceNotFoundException occurs, SM exists on server + // -> no further action required + } catch (ResourceNotFoundException e) { + // AAS does not exist and needs to be pushed to the server + // Check if ISubmodel is a concrete Submodel + if (sm instanceof Submodel) { + provider.setValue("/aas/submodels/" + sm.getIdShort(), sm); + objectUploaded = true; + } else { + throw new RuntimeException("sm Objects in bundles need to be instance of 'Submodel'"); + } + } + } + } + return objectUploaded; + } + + /** + * Registers a given set of bundles with the registry + * + * @param registry + * the registry to register with + * @param bundles + * the bundles to register + * @param aasAggregatorPath + * the aggregator path, e.g. http://localhost:4000/shells + */ + public static void register(IAASRegistry registry, Collection bundles, String aasAggregatorPath) { + bundles.stream().map(b -> AASBundleDescriptorFactory.createAASDescriptor(b, aasAggregatorPath)).forEach(registry::register); + } + + /** + * Deregisters a given set of bundles from a given registry + * + * @param registry + * the registry to deregister from + * @param bundles + * the AASBundles to be deregistred + */ + public static void deregister(IAASRegistry registry, Collection bundles) { + if (registry != null && bundles != null) { + for (AASBundle bundle : bundles) { + IAssetAdministrationShell aas = bundle.getAAS(); + + try { + registry.delete(aas.getIdentification()); + } catch (ProviderException e) { + logger.info("The AAS '" + aas.getIdShort() + "' can't be deregistered. It was not found in registry."); + // Just continue if deregistration failed + } + + for (ISubmodel sm : bundle.getSubmodels()) { + try { + registry.delete(sm.getIdentification()); + } catch (ProviderException e) { + logger.info("The SM '" + sm.getIdShort() + "' can't be deregistered. It was not found in registry."); + // Just continue if deregistration failed + } + } + } + } + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java index a09d971e..a610daa3 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXFactory.java @@ -1,309 +1,37 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.aasx; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.UUID; -import java.util.stream.Collectors; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.stream.StreamResult; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.PackagingURIHelper; -import org.apache.poi.openxml4j.opc.RelationshipSource; -import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart; -import org.eclipse.basyx.aas.factory.xml.MetamodelToXMLConverter; -import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; -import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; -import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; -import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription; -import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; -import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; -import org.eclipse.basyx.vab.modelprovider.VABPathTools; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - /** - * This class can be used to generate an .aasx file from - * Metamodel Objects and the Files referred to in the Submodels + * This class can be used to generate an .aasx file from Metamodel Objects and + * the Files referred to in the Submodels * + * @deprecated Replaced by {@link MetamodelToAASXConverter} * @author conradi * */ -public class AASXFactory { - - private static Logger logger = LoggerFactory.getLogger(AASXFactory.class); - - private static final String MIME_PLAINTXT = "text/plain"; - private static final String MIME_XML = "application/xml"; - - private static final String ORIGIN_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aasx-origin"; - private static final String ORIGIN_PATH = "/aasx/aasx-origin"; - private static final String ORIGIN_CONTENT = "Intentionally empty."; - - - private static final String AASSPEC_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec"; - private static final String XML_PATH = "/aasx/xml/content.xml"; - - - private static final String AASSUPPL_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-suppl"; - - - - /** - * Generates the .aasx file and writes it to the given OutputStream - * - * @param aasList the AASs to be saved in the .aasx - * @param assetList the Assets to be saved in the .aasx - * @param conceptDescriptionList the ConceptDescriptions to be saved in the .aasx - * @param submodelList the Submodels to be saved in the .aasx - * @param files the files referred to in the Submodels - * @param os the OutputStream the resulting .aasx is written to - * @throws IOException - * @throws TransformerException - * @throws ParserConfigurationException - */ - public static void buildAASX(Collection aasList, Collection assetList, - Collection conceptDescriptionList, Collection submodelList, Collection files, OutputStream os) throws IOException, TransformerException, ParserConfigurationException { - - prepareFilePaths(submodelList, files); - - OPCPackage rootPackage = OPCPackage.create(os); - - // Create the empty aasx-origin file - PackagePart origin = createAASXPart(rootPackage, rootPackage, ORIGIN_PATH, MIME_PLAINTXT, ORIGIN_RELTYPE, ORIGIN_CONTENT.getBytes()); - - // Convert the given Metamodels to XML - String xml = convertToXML(aasList, assetList, conceptDescriptionList, submodelList); - - // Save the XML to aasx/xml/content.xml - PackagePart xmlPart = createAASXPart(rootPackage, origin, XML_PATH, MIME_XML, AASSPEC_RELTYPE, xml.getBytes()); - - storeFilesInAASX(submodelList, files, rootPackage, xmlPart); - - saveAASX(os, rootPackage); - } - - /** - * Stores the files from the Submodels in the .aasx file - * - * @param submodelList the Submodels - * @param files the content of the files - * @param rootPackage the OPCPackage - * @param xmlPart the Part the files should be related to - */ - private static void storeFilesInAASX(Collection submodelList, Collection files, - OPCPackage rootPackage, PackagePart xmlPart) { - - for(ISubmodel sm: submodelList) { - for(File file: findFileElements(sm.getSubmodelElements().values())) { - String filePath = file.getValue(); - try { - InMemoryFile content = findFileByPath(files, filePath); - logger.trace("Writing file '" + filePath + "' to .aasx."); - createAASXPart(rootPackage, xmlPart, filePath, file.getMimeType(), AASSUPPL_RELTYPE, content.getFileContent()); - } catch (ResourceNotFoundException e) { - // Log that a file is missing and continue building the .aasx - logger.warn("Could not add File '" + filePath + "'. It was not contained in given InMemoryFiles."); - } - } - } - } - - /** - * Saves the OPCPackage to the given OutputStream - * - * @param os the Stream to be saved to - * @param rootPackage the Package to be saved - * @throws IOException - */ - private static void saveAASX(OutputStream os, OPCPackage rootPackage) throws IOException { - rootPackage.flush(); - rootPackage.save(os); - } - - /** - * Generates a UUID. Every element of the - * .aasx needs a unique Id according to the specification - * - * @return UUID - */ - private static String createUniqueID() { - // only letters or underscore as start of id allowed - // https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-qualnames - // - // old AASX Package Explorer versions expect a leading R - return "Rid_" + UUID.randomUUID().toString(); - } - - /** - * Creates a Part (a file in the .aasx) of the .aasx and adds it to the Package - * - * @param root the OPCPackage - * @param relateTo the Part of the OPC the relationship of the new Part should be added to - * @param path the path inside the .aasx where the new Part should be created - * @param mimeType the mime-type of the file - * @param relType the type of the Relationship - * @param content the data the new part should contain - * @return the created PackagePart; Returned in case it is needed late as a Part to relate to - */ - private static PackagePart createAASXPart(OPCPackage root, RelationshipSource relateTo, String path, String mimeType, String relType, byte[] content) { - if(mimeType == null || mimeType.equals("")) { - throw new RuntimeException("Could not create AASX Part '" + path + "'. No MIME_TYPE specified."); - } - - PackagePartName partName = null; - MemoryPackagePart part = null; - try { - partName = PackagingURIHelper.createPartName(path); - part = new MemoryPackagePart(root, partName, mimeType); - } catch (InvalidFormatException e) { - // This occurs if the given MIME-Type is not valid according to RFC2046 - throw new RuntimeException("Could not create AASX Part '" + path + "'", e); - } - writeDataToPart(part, content); - root.registerPartAndContentType(part); - // set TargetMode to EXTERNAL to force absolute file paths - // this step is necessary for compatibility reasons with AASXPackageExplorer - relateTo.addRelationship(partName, TargetMode.EXTERNAL, relType, createUniqueID()); - return part; - } - - /** - * Writes the content of a byte[] to a Part - * - * @param part the Part to be written to - * @param content the content to be written to the part - */ - private static void writeDataToPart(PackagePart part, byte[] content) { - try(OutputStream ostream = part.getOutputStream();) { - ostream.write(content); - ostream.flush(); - } catch (Exception e) { - throw new RuntimeException("Failed to write content to AASX Part '" + part.getPartName().getName() + "'", e); - } - } - - /** - * Uses the MetamodelToXMLConverter to generate the XML - */ - private static String convertToXML(Collection aasList, Collection assetList, - Collection conceptDescriptionList, Collection submodelList) throws TransformerException, ParserConfigurationException { - - StringWriter writer = new StringWriter(); - MetamodelToXMLConverter.convertToXML(aasList, assetList, conceptDescriptionList, submodelList, new StreamResult(writer)); - - return writer.toString(); - } - - /** - * Gets the File elements from a collection of elements - * Also recursively searches in SubmodelElementCollections - * - * @param elements the Elements to be searched for File elements - * @return the found Files - */ - private static Collection findFileElements(Collection elements) { - Collection files = new ArrayList<>(); - - for(ISubmodelElement element: elements) { - if(element instanceof File) { - files.add((File) element); - } else if(element instanceof SubmodelElementCollection) { - // Recursive call to deal with SubmodelElementCollections - files.addAll(findFileElements(((SubmodelElementCollection) element).getSubmodelElements().values())); - } - } - - return files; - } - - /** - * Find files which has a valid in memory file path - * @param elements - * @param inMemoryFiles - * @return - */ - private static Collection findInMemoryFileElements(Collection elements, Collection inMemoryFiles) { - Collection files = findFileElements(elements); - return files.stream().filter(f -> - isInMemoryFile(inMemoryFiles, f.getValue())) - .collect(Collectors.toList()); - } - - /** - * Replaces the path in File Elements which has an in memory file with the result of preparePath - * - * @param submodels the Submodels - */ - private static void prepareFilePaths(Collection submodels, Collection inMemoryFiles) { - submodels.stream() - .forEach(sm -> findInMemoryFileElements(sm.getSubmodelElements().values(), inMemoryFiles).stream().forEach(f -> f.setValue(preparePath(f.getValue())))); - } - - /** - * Removes the serverpart from a path and ensures it starts with a slash - * - * @param path the path to be prepared - * @return the prepared path - */ - private static String preparePath(String path) { - String newPath = VABPathTools.getPathFromURL(path); - if(!newPath.startsWith("/")) { - newPath = "/" + newPath; - } - return newPath; - } - - /** - * Finds an InMemoryFile by its path - * - * @param files the InMemoryFiles - * @param path the path of the wanted file - * @return the InMemoryFile if it was found; else null - */ - private static InMemoryFile findFileByPath(Collection files, String path) { - for(InMemoryFile file: files) { - if(preparePath(file.getPath()).equals(path)) { - return file; - } - } - throw new ResourceNotFoundException("The wanted file '" + path + "' was not found in the given files."); - } - - /** - * Finds an InMemoryFile by its path - * - * @param files the InMemoryFiles - * @param path the path of the wanted file - * @return the InMemoryFile if it was found; else null - */ - private static boolean isInMemoryFile(Collection files, String path) { - for(InMemoryFile file: files) { - if(VABPathTools.stripSlashes(file.getPath()).equals(VABPathTools.stripSlashes(path))) { - return true; - } - } - return false; - } +@Deprecated +public class AASXFactory extends MetamodelToAASXConverter { } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXPackageExplorerConformantHelper.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXPackageExplorerConformantHelper.java index e159845c..17650e2a 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXPackageExplorerConformantHelper.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXPackageExplorerConformantHelper.java @@ -1,17 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.aasx; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; + import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; import org.eclipse.basyx.aas.metamodel.map.AasEnv; @@ -31,13 +47,12 @@ * */ public class AASXPackageExplorerConformantHelper { - - static int counter = 0; + /** * Converts meta model elements so that the AASXPackageExplorer can load their - * serialized AASX. This method modifies the passed parameter Asset Administration Shell List. - * As the passed Asset Administration Shell List contains objects as references thatswhy original - * List is modified. + * serialized AASX. This method modifies the passed parameter Asset + * Administration Shell List. As the passed Asset Administration Shell List + * contains objects as references thatswhy original List is modified. * * @param aasList * @param assetList @@ -45,11 +60,9 @@ public class AASXPackageExplorerConformantHelper { * @param submodelList * @return */ - public static AasEnv adapt(Collection aasList, Collection assetList, - Collection conceptDescriptionList, Collection submodelList) { + public static AasEnv adapt(Collection aasList, Collection assetList, Collection conceptDescriptionList, Collection submodelList) { - Collection convertedAASs = aasList.stream() - .map(AASXPackageExplorerConformantHelper::removeFirstKeyFromSubmodelReferences).collect(Collectors.toList()); + Collection convertedAASs = aasList.stream().map(AASXPackageExplorerConformantHelper::removeFirstKeyFromSubmodelReferences).collect(Collectors.toList()); return new AasEnv(convertedAASs, assetList, conceptDescriptionList, submodelList); } @@ -62,13 +75,11 @@ public static AasEnv adapt(Collection aasList, Collec * @return */ public static AasEnv adapt(AasEnv env) { - return adapt(env.getAssetAdministrationShells(), env.getAssets(), env.getConceptDescriptions(), - env.getSubmodels()); + return adapt(env.getAssetAdministrationShells(), env.getAssets(), env.getConceptDescriptions(), env.getSubmodels()); } private static IAssetAdministrationShell removeFirstKeyFromSubmodelReferences(IAssetAdministrationShell shell) { - Collection convertedReferences = shell.getSubmodelReferences().stream() - .map(AASXPackageExplorerConformantHelper::removeFirstKeyElement).collect(Collectors.toList()); + Collection convertedReferences = shell.getSubmodelReferences().stream().map(AASXPackageExplorerConformantHelper::removeFirstKeyElement).collect(Collectors.toList()); ((AssetAdministrationShell) shell).setSubmodelReferences(convertedReferences); @@ -78,9 +89,9 @@ private static IAssetAdministrationShell removeFirstKeyFromSubmodelReferences(IA private static IReference removeFirstKeyElement(IReference reference) { List keys = reference.getKeys(); - if(!keys.isEmpty() && keys.get(0).getType().equals(KeyElements.ASSETADMINISTRATIONSHELL)) { + if (!keys.isEmpty() && keys.get(0).getType().equals(KeyElements.ASSETADMINISTRATIONSHELL)) { keys.remove(0); - + return new Reference(keys); } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java new file mode 100644 index 00000000..1fbc61a3 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.aas.factory.aasx; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import javax.xml.parsers.ParserConfigurationException; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; +import org.apache.poi.openxml4j.opc.PackagingURIHelper; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.bundle.AASBundleFactory; +import org.eclipse.basyx.aas.factory.xml.XMLToMetamodelConverter; +import org.eclipse.basyx.aas.metamodel.map.AasEnv; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +/** + * The AASX package converter converts a aasx package into a list of aas, a list + * of submodels a list of assets, a list of Concept descriptions + * + * The aas provides the references to the submodels and assets + * + * @author zhangzai, conradi + * + */ +public class AASXToMetamodelConverter { + + private static final String XML_TYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec"; + private static final String AASX_ORIGIN = "/aasx/aasx-origin"; + + private String aasxPath; + private OPCPackage aasxRoot; + private InputStream aasxInputStream; + + private Set bundles; + + private AasEnv aasEnv; + + private static Logger logger = LoggerFactory.getLogger(AASXToMetamodelConverter.class); + + public AASXToMetamodelConverter(String path) { + this.aasxPath = path; + } + + public AASXToMetamodelConverter(InputStream stream) { + this.aasxInputStream = stream; + } + + public AasEnv retrieveAasEnv() throws ParserConfigurationException, SAXException, IOException, InvalidFormatException { + if (aasEnv != null) { + return aasEnv; + } + + loadAASX(); + + String xmlContent = getXMLResourceString(aasxRoot); + XMLToMetamodelConverter converter = new XMLToMetamodelConverter(xmlContent); + closeOPCPackage(); + return converter.parseAasEnv(); + } + + @SuppressWarnings("unchecked") + public Set retrieveAASBundles() throws IOException, ParserConfigurationException, SAXException, InvalidFormatException { + + // If the XML was already parsed return cached Bundles + if (bundles != null) { + return (Set) bundles; + } + + loadAASX(); + + AasEnv localAasEnv = retrieveAasEnv(); + + bundles = new AASBundleFactory().create(localAasEnv.getAssetAdministrationShells(), localAasEnv.getSubmodels(), localAasEnv.getAssets()); + + closeOPCPackage(); + + return (Set) bundles; + } + + private void loadAASX() throws IOException, InvalidFormatException { + if (aasxInputStream == null) { + aasxInputStream = FileLoaderHelper.getInputStream(aasxPath); + } + + if (aasxRoot == null) { + aasxRoot = OPCPackage.open(aasxInputStream); + } + } + + private void closeOPCPackage() throws IOException { + aasxRoot.close(); + } + + /** + * Return the Content of the XML file in the aasx-package as String + * + * @param aasxPackage + * - the root package of the AASX + * @return Content of XML as String + * @throws InvalidFormatException + * @throws IOException + */ + private String getXMLResourceString(OPCPackage aasxPackage) throws InvalidFormatException, IOException { + + // Get the "/aasx/aasx-origin" Part. It is Relationship source for the + // XML-Document + PackagePart originPart = aasxPackage.getPart(PackagingURIHelper.createPartName(AASX_ORIGIN)); + + // Get the Relation to the XML Document + PackageRelationshipCollection originRelationships = originPart.getRelationshipsByType(XML_TYPE); + + // If there is more than one or no XML-Document that is an error + if (originRelationships.size() > 1) { + throw new RuntimeException("More than one 'aasx-spec' document found in .aasx"); + } else if (originRelationships.size() == 0) { + throw new RuntimeException("No 'aasx-spec' document found in .aasx"); + } + + // Get the PackagePart of the XML-Document + PackagePart xmlPart = originPart.getRelatedPart(originRelationships.getRelationship(0)); + + // Read the content from the PackagePart + InputStream stream = xmlPart.getInputStream(); + StringWriter writer = new StringWriter(); + IOUtils.copy(stream, writer, StandardCharsets.UTF_8); + return writer.toString(); + } + + /** + * Load the referenced filepaths in the submodels such as PDF, PNG files from + * the package + * + * @return a map of the folder name and folder path, the folder holds the files + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + * @throws InvalidFormatException + * + */ + private List parseReferencedFilePathsFromAASX() throws IOException, ParserConfigurationException, SAXException, InvalidFormatException { + + Set bundles = retrieveAASBundles(); + + List submodels = new ArrayList<>(); + + // Get the Submodels from all AASBundles + for (AASBundle bundle : bundles) { + submodels.addAll(bundle.getSubmodels()); + } + + List paths = new ArrayList(); + + for (ISubmodel sm : submodels) { + paths.addAll(parseElements(sm.getSubmodelElements().values())); + } + return paths; + } + + /** + * Gets the paths from a collection of ISubmodelElement + * + * @param elements + * @return the Paths from the File elements + */ + private List parseElements(Collection elements) { + List paths = new ArrayList(); + + for (ISubmodelElement element : elements) { + if (element instanceof IFile) { + IFile file = (IFile) element; + // If the path contains a "://", we can assume, that the Path is a link to an + // other server + // e.g. http://localhost:8080/aasx/... + if (!file.getValue().contains("://")) { + paths.add(file.getValue()); + } + } else if (element instanceof ISubmodelElementCollection) { + ISubmodelElementCollection collection = (ISubmodelElementCollection) element; + paths.addAll(parseElements(collection.getSubmodelElements().values())); + } + } + return paths; + } + + /** + * Unzips all files referenced by the aasx file according to its relationships + * + * + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + * @throws URISyntaxException + * @throws InvalidFormatException + */ + public void unzipRelatedFiles() throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException { + // load folder which stores the files + loadAASX(); + + List files = parseReferencedFilePathsFromAASX(); + for (String filePath : files) { + // name of the folder + unzipFile(filePath, aasxRoot); + } + + closeOPCPackage(); + } + + /** + * Create a folder to hold the unpackaged files The folder has the path + * \target\classes\docs + * + * @throws IOException + * @throws URISyntaxException + */ + protected Path getRootFolder() throws IOException, URISyntaxException { + URI uri = AASXToMetamodelConverter.class.getProtectionDomain().getCodeSource().getLocation().toURI(); + URI parent = new File(uri).getParentFile().toURI(); + return Paths.get(parent); + } + + /** + * unzip the file folders + * + * @param filePath + * - path of the file in the aasx to unzip + * @param aasxPath + * - aasx path + * @throws IOException + * @throws URISyntaxException + * @throws InvalidFormatException + */ + private void unzipFile(String filePath, OPCPackage aasxRoot) throws IOException, URISyntaxException, InvalidFormatException { + // Create destination directory + if (filePath.startsWith("/")) { + filePath = filePath.substring(1); + } + if (filePath.isEmpty()) { + logger.warn("A file with empty path can not be unzipped."); + return; + } + logger.info("Unzipping " + filePath + " to root folder:"); + String relativePath = "files/" + VABPathTools.getParentPath(filePath); + Path rootPath = getRootFolder(); + Path destDir = rootPath.resolve(relativePath); + logger.info("Unzipping to " + destDir); + Files.createDirectories(destDir); + + PackagePart part = aasxRoot.getPart(PackagingURIHelper.createPartName("/" + filePath)); + + if (part == null) { + logger.warn("File '" + filePath + "' could not be unzipped. It does not exist in .aasx."); + return; + } + + String targetPath = destDir.toString() + "/" + VABPathTools.getLastElement(filePath); + InputStream stream = part.getInputStream(); + FileUtils.copyInputStreamToFile(stream, new File(targetPath)); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/FileLoaderHelper.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/FileLoaderHelper.java new file mode 100644 index 00000000..b56bd274 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/FileLoaderHelper.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.factory.aasx; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A helper class for providing InputStream of file from specified path. + * + * @author danish + * + */ +public class FileLoaderHelper { + private static Logger logger = LoggerFactory.getLogger(FileLoaderHelper.class); + + public static InputStream getInputStream(String aasxFilePath) throws IOException { + InputStream stream = getResourceStream(aasxFilePath); + + if (stream != null) { + return stream; + } else { + try { + return new FileInputStream(aasxFilePath); + } catch (FileNotFoundException e) { + logger.error("File '" + aasxFilePath + "' to be loaded was not found."); + throw e; + } + } + } + + private static InputStream getResourceStream(String relativeResourcePath) { + ClassLoader classLoader = AASXToMetamodelConverter.class.getClassLoader(); + + return classLoader.getResourceAsStream(relativeResourcePath); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java index ec8385ff..0aeee140 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/InMemoryFile.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.aasx; @@ -19,7 +34,7 @@ public class InMemoryFile { private byte[] fileContent; private String path; - + public InMemoryFile(byte[] fileContent, String path) { this.fileContent = fileContent; this.path = path; diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/MetamodelToAASXConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/MetamodelToAASXConverter.java new file mode 100644 index 00000000..17b1d64a --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/MetamodelToAASXConverter.java @@ -0,0 +1,369 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.factory.aasx; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.stream.StreamResult; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackagePartName; +import org.apache.poi.openxml4j.opc.PackagingURIHelper; +import org.apache.poi.openxml4j.opc.RelationshipSource; +import org.apache.poi.openxml4j.opc.TargetMode; +import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart; +import org.eclipse.basyx.aas.factory.xml.MetamodelToXMLConverter; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AasEnv; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class can be used to generate an .aasx file from Metamodel Objects and + * the Files referred to in the Submodels + * + * @author conradi + * + */ +public class MetamodelToAASXConverter { + + private static Logger logger = LoggerFactory.getLogger(MetamodelToAASXConverter.class); + + private static final String MIME_PLAINTXT = "text/plain"; + private static final String MIME_XML = "application/xml"; + + private static final String ORIGIN_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aasx-origin"; + private static final String ORIGIN_PATH = "/aasx/aasx-origin"; + private static final String ORIGIN_CONTENT = "Intentionally empty."; + + private static final String AASSPEC_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec"; + private static final String XML_PATH = "/aasx/xml/content.xml"; + + private static final String AASSUPPL_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-suppl"; + + /** + * Generates the .aasx file and writes it to the given OutputStream + * + * @param aasList + * the AASs to be saved in the .aasx + * @param assetList + * the Assets to be saved in the .aasx + * @param conceptDescriptionList + * the ConceptDescriptions to be saved in the .aasx + * @param submodelList + * the Submodels to be saved in the .aasx + * @param files + * the files referred to in the Submodels + * @param os + * the OutputStream the resulting .aasx is written to + * @throws IOException + * @throws TransformerException + * @throws ParserConfigurationException + */ + public static void buildAASX(Collection aasList, Collection assetList, Collection conceptDescriptionList, Collection submodelList, Collection files, + OutputStream os) throws IOException, TransformerException, ParserConfigurationException { + + prepareFilePaths(submodelList, files); + + OPCPackage rootPackage = OPCPackage.create(os); + + PackagePart origin = createAASXPart(rootPackage, rootPackage, ORIGIN_PATH, MIME_PLAINTXT, ORIGIN_RELTYPE, ORIGIN_CONTENT.getBytes()); + + String xml = convertToXML(aasList, assetList, conceptDescriptionList, submodelList); + + PackagePart xmlPart = createAASXPart(rootPackage, origin, XML_PATH, MIME_XML, AASSPEC_RELTYPE, xml.getBytes()); + + storeFilesInAASX(submodelList, files, rootPackage, xmlPart); + + saveAASX(os, rootPackage); + } + + /** + * Generates the .aasx file and writes it to the given OutputStream + * + * @param aasEnv + * @param files + * @param os + * the OutputStream the resulting .aasx is written to + * @throws IOException + * @throws TransformerException + * @throws ParserConfigurationException + */ + public static void buildAASX(AasEnv aasEnv, Collection files, OutputStream os) throws IOException, TransformerException, ParserConfigurationException { + buildAASX(aasEnv.getAssetAdministrationShells(), aasEnv.getAssets(), aasEnv.getConceptDescriptions(), aasEnv.getSubmodels(), files, os); + } + + /** + * Stores the files from the Submodels in the .aasx file + * + * @param submodelList + * the Submodels + * @param files + * the content of the files + * @param rootPackage + * the OPCPackage + * @param xmlPart + * the Part the files should be related to + */ + private static void storeFilesInAASX(Collection submodelList, Collection files, OPCPackage rootPackage, PackagePart xmlPart) { + + for (ISubmodel sm : submodelList) { + for (File file : findFileElements(sm.getSubmodelElements().values())) { + String filePath = file.getValue(); + storeFileInAASX(files, rootPackage, xmlPart, file, filePath); + } + } + } + + /** + * Stores a single file in the .aasx file + * + * @param files + * @param rootPackage + * @param xmlPart + * @param file + * @param filePath + */ + private static void storeFileInAASX(Collection files, OPCPackage rootPackage, PackagePart xmlPart, File file, String filePath) { + try { + InMemoryFile content = findFileByPath(files, filePath); + logger.trace("Writing file '" + filePath + "' to .aasx."); + createAASXPart(rootPackage, xmlPart, filePath, file.getMimeType(), AASSUPPL_RELTYPE, content.getFileContent()); + } catch (ResourceNotFoundException e) { + // Log that a file is missing and continue building the .aasx + logger.warn("Could not add File '" + filePath + "'. It was not contained in given InMemoryFiles."); + } + } + + /** + * Saves the OPCPackage to the given OutputStream + * + * @param os + * the Stream to be saved to + * @param rootPackage + * the Package to be saved + * @throws IOException + */ + private static void saveAASX(OutputStream os, OPCPackage rootPackage) throws IOException { + rootPackage.flush(); + rootPackage.save(os); + } + + /** + * Generates a UUID. Every element of the .aasx needs a unique Id according to + * the specification + * + * @return UUID + */ + private static String createUniqueID() { + // only letters or underscore as start of id allowed + // https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-qualnames + // + // old AASX Package Explorer versions expect a leading R + return "Rid_" + UUID.randomUUID().toString(); + } + + /** + * Creates a Part (a file in the .aasx) of the .aasx and adds it to the Package + * + * @param root + * the OPCPackage + * @param relateTo + * the Part of the OPC the relationship of the new Part should be + * added to + * @param path + * the path inside the .aasx where the new Part should be created + * @param mimeType + * the mime-type of the file + * @param relType + * the type of the Relationship + * @param content + * the data the new part should contain + * @return the created PackagePart; Returned in case it is needed late as a Part + * to relate to + */ + private static PackagePart createAASXPart(OPCPackage root, RelationshipSource relateTo, String path, String mimeType, String relType, byte[] content) { + if (mimeType == null || mimeType.equals("")) { + throw new RuntimeException("Could not create AASX Part '" + path + "'. No MIME_TYPE specified."); + } + + PackagePartName partName = null; + MemoryPackagePart part = null; + try { + partName = PackagingURIHelper.createPartName(path); + part = new MemoryPackagePart(root, partName, mimeType); + } catch (InvalidFormatException e) { + // This occurs if the given MIME-Type is not valid according to RFC2046 + throw new RuntimeException("Could not create AASX Part '" + path + "'", e); + } + writeDataToPart(part, content); + root.registerPartAndContentType(part); + // set TargetMode to EXTERNAL to force absolute file paths + // this step is necessary for compatibility reasons with AASXPackageExplorer + relateTo.addRelationship(partName, TargetMode.EXTERNAL, relType, createUniqueID()); + return part; + } + + /** + * Writes the content of a byte[] to a Part + * + * @param part + * the Part to be written to + * @param content + * the content to be written to the part + */ + private static void writeDataToPart(PackagePart part, byte[] content) { + try (OutputStream ostream = part.getOutputStream();) { + ostream.write(content); + ostream.flush(); + } catch (Exception e) { + throw new RuntimeException("Failed to write content to AASX Part '" + part.getPartName().getName() + "'", e); + } + } + + /** + * Uses the MetamodelToXMLConverter to generate the XML + */ + private static String convertToXML(Collection aasList, Collection assetList, Collection conceptDescriptionList, Collection submodelList) + throws TransformerException, ParserConfigurationException { + + StringWriter writer = new StringWriter(); + MetamodelToXMLConverter.convertToXML(aasList, assetList, conceptDescriptionList, submodelList, new StreamResult(writer)); + + return writer.toString(); + } + + /** + * Gets the File elements from a collection of elements Also recursively + * searches in SubmodelElementCollections + * + * @param elements + * the Elements to be searched for File elements + * @return the found Files + */ + private static Collection findFileElements(Collection elements) { + Collection files = new ArrayList<>(); + + for (ISubmodelElement element : elements) { + if (element instanceof File) { + files.add((File) element); + } else if (element instanceof SubmodelElementCollection) { + // Recursive call to deal with SubmodelElementCollections + files.addAll(findFileElements(((SubmodelElementCollection) element).getSubmodelElements().values())); + } + } + + return files; + } + + /** + * Find files which has a valid in memory file path + * + * @param elements + * @param inMemoryFiles + * @return + */ + private static Collection findInMemoryFileElements(Collection elements, Collection inMemoryFiles) { + Collection files = findFileElements(elements); + return files.stream().filter(f -> isInMemoryFile(inMemoryFiles, f.getValue())).collect(Collectors.toList()); + } + + /** + * Replaces the path in File Elements which has an in memory file with the + * result of preparePath + * + * @param submodels + * the Submodels + */ + private static void prepareFilePaths(Collection submodels, Collection inMemoryFiles) { + submodels.stream().forEach(sm -> findInMemoryFileElements(sm.getSubmodelElements().values(), inMemoryFiles).stream().forEach(f -> f.setValue(preparePath(f.getValue())))); + } + + /** + * Removes the serverpart from a path. VABPathTools.getPathFromURL() also + * ensures that it starts with a slash. + * + * @param path + * the path to be prepared + * @return the prepared path + */ + private static String preparePath(String path) { + return VABPathTools.getPathFromURL(path); + } + + /** + * Finds an InMemoryFile by its path + * + * @param files + * the InMemoryFiles + * @param path + * the path of the wanted file + * @return the InMemoryFile if it was found; else null + */ + private static InMemoryFile findFileByPath(Collection files, String path) { + for (InMemoryFile file : files) { + if (preparePath(file.getPath()).equals(path)) { + return file; + } + } + throw new ResourceNotFoundException("The wanted file '" + path + "' was not found in the given files."); + } + + /** + * Finds an InMemoryFile by its path + * + * @param files + * the InMemoryFiles + * @param path + * the path of the wanted file + * @return the InMemoryFile if it was found; else null + */ + private static boolean isInMemoryFile(Collection files, String path) { + for (InMemoryFile file : files) { + if (VABPathTools.stripSlashes(file.getPath()).equals(VABPathTools.stripSlashes(path))) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java new file mode 100644 index 00000000..ae21277c --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.aas.factory.aasx; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; + +/** + * A utility class for configuring file endpoints in submodels + * + * @author espen + * + */ +public class SubmodelFileEndpointLoader { + /** + * Sets all file and blob submodelElements inside of the submodel to an endpoint + * at a given host relative to its original path. + * + * @param submodel + * @param host + * e.g. localhost + * @param port + * port for the host + * @param path + * path at which the files are hosted on the host (e.g. "/files") + */ + public static void setRelativeFileEndpoints(ISubmodel submodel, String host, int port, String path) { + String fileRoot = "http://" + host + ":" + port + path; + setRelativeFileEndpoints(submodel, fileRoot); + } + + /** + * Sets all file and blob submodelElements inside of the submodel to an endpoint + * at a given host relative to its original path. + * + * @param submodel + * @param fileRoot + * the full root path for the files (e.g. + * "http://localhost:1234/myFiles") + */ + public static void setRelativeFileEndpoints(ISubmodel submodel, String fileRoot) { + Map elements = submodel.getSubmodelElements(); + setMapEndpoints(elements, fileRoot); + } + + /** + * Fixes endpoints in a Map of submodel elements (applicable for Submodels and + * SubmodelElementCollections) + * + * @param elements + * @param fileRoot + */ + private static void setMapEndpoints(Map elements, String fileRoot) { + elements.values().stream().forEach(e -> { + if (e instanceof File) { + File file = (File) e; + setFileEndpoint(file, fileRoot); + } else if (e instanceof ISubmodelElementCollection) { + SubmodelElementCollection col = (SubmodelElementCollection) e; + setMapEndpoints(col.getSubmodelElements(), fileRoot); + } + }); + } + + /** + * Modifies the file value endpoint in a single given file according to a new + * file root path + * + * @param file + * @param fileRoot + */ + private static void setFileEndpoint(File file, String fileRoot) { + String relativePath = file.getValue(); + URL url; + try { + url = new URL(file.getValue()); + relativePath = url.getPath(); + } catch (MalformedURLException e1) { + // assume that the file value is already a relative path + } + String newEndpoint = fileRoot + relativePath; + file.setValue(newEndpoint); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/json/JSONAASBundleFactory.java b/src/main/java/org/eclipse/basyx/aas/factory/json/JSONAASBundleFactory.java new file mode 100644 index 00000000..bde5dee9 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/json/JSONAASBundleFactory.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.factory.json; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Set; + +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.bundle.AASBundleFactory; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; + +/** + * Creates multiple {@link AASBundle} from a JSON containing several AAS and + * Submodels
+ * TODO: ConceptDescriptions + * + * @author espen + * + */ +public class JSONAASBundleFactory { + private String content; + + /** + * + * @param jsonContent + * the content of the JSON + */ + public JSONAASBundleFactory(String jsonContent) { + this.content = jsonContent; + } + + public JSONAASBundleFactory(Path jsonFile) throws IOException { + content = new String(Files.readAllBytes(jsonFile)); + } + + /** + * Creates the set of {@link AASBundle} contained in the JSON string. + * + * @return + */ + public Set create() { + JSONToMetamodelConverter converter = new JSONToMetamodelConverter(content); + + Collection shells = converter.parseAAS(); + Collection submodels = converter.parseSubmodels(); + Collection assets = converter.parseAssets(); + + return new AASBundleFactory().create(shells, submodels, assets); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java index 6bc11e9c..49898f5c 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/json/JSONToMetamodelConverter.java @@ -1,20 +1,41 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.json; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AasEnv; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription; import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.map.Submodel; @@ -26,21 +47,67 @@ /** * This class can be used to parse JSON to Metamodel Objects * - * @author conradi + * @author conradi, jungjan * */ public class JSONToMetamodelConverter { - - private Map root; - - // Buffer used for parsed assets to prevent deserializing them multiple times - private List assetBuf; - @SuppressWarnings("unchecked") + private AasEnv aasEnv; + + /** + * Initializes the parser with XML given as a String + * + * @param jsonContent + * the JSON content to be parsed + */ public JSONToMetamodelConverter(String jsonContent) { - root = (Map) new GSONTools(new DefaultTypeFactory()).deserialize(jsonContent); + Map root = createRoot(jsonContent); + + List assets = createAssets(root); + + List shells = createShells(root, assets); + + List conceptDescriptions = createConceptDescriptions(root); + + List submodels = createSubmodels(root); + + aasEnv = new AasEnv(shells, assets, conceptDescriptions, submodels); + } + + @SuppressWarnings("unchecked") + private List createSubmodels(Map root) { + return ((List) root.get(MetamodelToJSONConverter.SUBMODELS)).stream().map(smMap -> Submodel.createAsFacade((Map) smMap)).collect(Collectors.toList()); } - + + @SuppressWarnings("unchecked") + private List createConceptDescriptions(Map root) { + return ((List) root.get(MetamodelToJSONConverter.CONCEPT_DESCRIPTIONS)).stream().map(cdMap -> ConceptDescription.createAsFacade((Map) cdMap)).collect(Collectors.toList()); + } + + @SuppressWarnings("unchecked") + private List createShells(Map root, List assets) { + return ((List) root.get(MetamodelToJSONConverter.ASSET_ADMINISTRATION_SHELLS)).stream().map(aasObject -> handleJSONAssetReference(aasObject, (List) (List) assets)).collect(Collectors.toList()); + } + + @SuppressWarnings("unchecked") + private List createAssets(Map root) { + return ((List) root.get(MetamodelToJSONConverter.ASSETS)).stream().map(aMap -> Asset.createAsFacade((Map) aMap)).collect(Collectors.toList()); + } + + @SuppressWarnings("unchecked") + private Map createRoot(String jsonContent) { + return (Map) new GSONTools(new DefaultTypeFactory()).deserialize(jsonContent); + } + + /** + * Parses the AasEnv from the JSON + * + * @return the AasEnv parsed from the JSON + */ + public AasEnv parseAasEnv() { + return aasEnv; + } + /** * Parses the AASs from the JSON * @@ -48,36 +115,43 @@ public JSONToMetamodelConverter(String jsonContent) { */ @SuppressWarnings("unchecked") public List parseAAS() { - assetBuf = parseAssets(); - return ((List) root.get(MetamodelToJSONConverter.ASSET_ADMINISTRATION_SHELLS)).stream() - .map(this::parseAssetAdministrationShell).collect(Collectors.toList()); + return new ArrayList<>((List) (List) aasEnv.getAssetAdministrationShells()); } @SuppressWarnings("unchecked") - private AssetAdministrationShell parseAssetAdministrationShell(Object mapObject) { - Map aasMap = (Map) mapObject; - // Fix Asset - Asset in json-Serialization is just a reference + private AssetAdministrationShell handleJSONAssetReference(Object aasObject, List assets) { + Map aasMap = (Map) aasObject; Map assetRefMap = (Map) aasMap.get(AssetAdministrationShell.ASSET); - if (assetRefMap.get(Reference.KEY) == null && assetRefMap.get(Asset.KIND) != null) { - // => Is already an asset, => does not need to be fixed - return AssetAdministrationShell.createAsFacade((Map) mapObject); + + if (isAssetReference(assetRefMap)) { + return handleReference(aasObject, aasMap, assetRefMap, assets); + } else { + return AssetAdministrationShell.createAsFacade((Map) aasObject); } + + } + + @SuppressWarnings("unchecked") + private AssetAdministrationShell handleReference(Object aasObject, Map aasMap, Map assetRefMap, List assets) { aasMap.put(AssetAdministrationShell.ASSETREF, assetRefMap); - - // Now try to find the Asset and add it to the AssetAdministrationShell + IReference assetRef = Reference.createAsFacade((Map) aasMap.get(AssetAdministrationShell.ASSETREF)); IKey lastKey = assetRef.getKeys().get(assetRef.getKeys().size() - 1); String idValue = lastKey.getValue(); - for (Asset asset : assetBuf) { + for (Asset asset : assets) { if (asset.getIdentification().getId().equals(idValue)) { aasMap.put(AssetAdministrationShell.ASSET, asset); break; } } - return AssetAdministrationShell.createAsFacade((Map) mapObject); + return AssetAdministrationShell.createAsFacade((Map) aasObject); + } + + private boolean isAssetReference(Map assetRefMap) { + return assetRefMap.get(Reference.KEY) != null && assetRefMap.get(Asset.KIND) == null; } - + /** * Parses the Submodels from the JSON * @@ -85,10 +159,9 @@ private AssetAdministrationShell parseAssetAdministrationShell(Object mapObject) */ @SuppressWarnings("unchecked") public List parseSubmodels() { - return ((List) root.get(MetamodelToJSONConverter.SUBMODELS)).stream() - .map(i -> Submodel.createAsFacade((Map) i)).collect(Collectors.toList()); + return new ArrayList<>((List) (List) aasEnv.getSubmodels()); } - + /** * Parses the Assets from the JSON * @@ -96,8 +169,7 @@ public List parseSubmodels() { */ @SuppressWarnings("unchecked") public List parseAssets() { - return ((List) root.get(MetamodelToJSONConverter.ASSETS)).stream() - .map(i -> Asset.createAsFacade((Map) i)).collect(Collectors.toList()); + return new ArrayList<>((List) (List) aasEnv.getAssets()); } /** @@ -107,7 +179,6 @@ public List parseAssets() { */ @SuppressWarnings("unchecked") public List parseConceptDescriptions() { - return ((List) root.get(MetamodelToJSONConverter.CONCEPT_DESCRIPTIONS)).stream() - .map(i -> ConceptDescription.createAsFacade((Map) i)).collect(Collectors.toList()); + return new ArrayList<>((List) (List) aasEnv.getConceptDescriptions()); } } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java index 80a9afb1..97d4d788 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/json/MetamodelToJSONConverter.java @@ -1,21 +1,38 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.json; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.basyx.aas.metamodel.map.AasEnv; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.parts.Asset; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; @@ -30,44 +47,57 @@ * @author conradi * */ -public class MetamodelToJSONConverter { - +public class MetamodelToJSONConverter { + public static final String ASSET_ADMINISTRATION_SHELLS = "assetAdministrationShells"; public static final String SUBMODELS = "submodels"; public static final String ASSETS = "assets"; public static final String CONCEPT_DESCRIPTIONS = "conceptDescriptions"; /** - * Builds the JSON for the given metamodel Objects. - * Not required parameters can be null. + * Builds the JSON for the aasEnv * - * @param aasList the AASs to build the JSON for - * @param assetList the Assets to build the JSON for - * @param conceptDescriptionList the ConceptDescriptions to build the JSON for - * @param submodelList the Submodels to build the JSON for + * @param aasEnv + * @return */ - public static String convertToJSON(Collection aasList, Collection assetList, - Collection conceptDescriptionList, Collection submodelList) { - - // The Submodel-Object holds SubmodelElements in a Map - // The JSON-Schema requires the SubmodelElements to be in a List - // This conversion is done by converting the sm to a Map - List smMapList; - if(submodelList != null) { - smMapList = submodelList.stream() - .map(sm -> SubmodelElementMapCollectionConverter.smToMap(sm)).collect(Collectors.toList()); - } else { - smMapList = new ArrayList<>(); - } - - - Map root = new HashMap<>(); - - root.put(ASSET_ADMINISTRATION_SHELLS, aasList==null ? new ArrayList() : aasList); + @SuppressWarnings("unchecked") + public static String convertToJSON(AasEnv aasEnv) { + return convertToJSON((List) (List) aasEnv.getAssetAdministrationShells(), (List) (List) aasEnv.getAssets(), (List) (List) aasEnv.getConceptDescriptions(), + (List) (List) aasEnv.getSubmodels()); + } + + /** + * Builds the JSON for the given metamodel Objects. Not required parameters can + * be null. + * + * @param aasList + * the AASs to build the JSON for + * @param assetList + * the Assets to build the JSON for + * @param conceptDescriptionList + * the ConceptDescriptions to build the JSON for + * @param submodelList + * the Submodels to build the JSON for + */ + public static String convertToJSON(Collection aasList, Collection assetList, Collection conceptDescriptionList, Collection submodelList) { + + List smMapList = submodelsToMapList(submodelList); + + Map root = new LinkedHashMap<>(); + + root.put(ASSET_ADMINISTRATION_SHELLS, aasList == null ? new ArrayList() : aasList); root.put(SUBMODELS, smMapList); - root.put(ASSETS, assetList==null ? new ArrayList() : assetList); - root.put(CONCEPT_DESCRIPTIONS, conceptDescriptionList==null ? new ArrayList() : conceptDescriptionList); - + root.put(ASSETS, assetList == null ? new ArrayList() : assetList); + root.put(CONCEPT_DESCRIPTIONS, conceptDescriptionList == null ? new ArrayList() : conceptDescriptionList); + return new GSONTools(new DefaultTypeFactory()).serialize(root); - } + } + + private static List submodelsToMapList(Collection submodelList) { + if (submodelList != null) { + return submodelList.stream().map(sm -> SubmodelElementMapCollectionConverter.smToMap(sm)).collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/AASXPackageExplorerCompatibilityHandler.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/AASXPackageExplorerCompatibilityHandler.java new file mode 100644 index 00000000..3a8121d5 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/AASXPackageExplorerCompatibilityHandler.java @@ -0,0 +1,133 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.aas.factory.xml; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter; +import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.operation.OperationXMLConverter; + +/** + * This class contains workarounds needed to be able to load .xml files produced + * by the AASXPackageExplorer in BaSyx. + * + * @author conradi + * + */ +public class AASXPackageExplorerCompatibilityHandler { + + /** + * This function makes sure the operation vars are in the correct map. + * AASXPackageExplorer uses multiple e.g. <aas:inputVariable> tags instead + * of a single <aas:inputVariable> with multiple + * <aas:operationVariable> tags within + * + * @param xmlObject + * @return + */ + @SuppressWarnings("unchecked") + public static Map prepareOperationVariableMap(Object xmlObject) { + if (xmlObject == null) { + return null; + } else if (isValidMap(xmlObject)) { + return (Map) xmlObject; + } else if (xmlObject instanceof List) { + return handleInvalidVariableList((List) xmlObject); + } else if (xmlObject instanceof Map) { + return handleInvalidVariableMap((Map) xmlObject); + } else { + throw createUnexpectedObjectRuntimeException(xmlObject); + } + + } + + private static Map handleInvalidVariableMap(Map map) throws RuntimeException { + if (hasValueTag(map)) { + return insertOperationVariableTag(map); + } else { + throw createUnexpectedObjectRuntimeException(map); + } + } + + private static boolean hasValueTag(Map map) { + return map.containsKey(SubmodelElementXMLConverter.VALUE); + } + + private static Map insertOperationVariableTag(Map map) { + // This Map contains directly the aas:value key and one variable + // e.g. was used instead of + // + Map correctMap = new LinkedHashMap<>(); + correctMap.put(OperationXMLConverter.OPERATION_VARIABLE, map); + return correctMap; + } + + @SuppressWarnings("unchecked") + private static boolean isValidMap(Object xmlObject) { + if (!(xmlObject instanceof Map)) { + return false; + } + + Map map = (Map) xmlObject; + return map.containsKey(OperationXMLConverter.OPERATION_VARIABLE); + } + + private static Map handleInvalidVariableList(List xmlObject) { + // If object is a List + // Multiple was used instead of + // and multiple within that + // Wrap List in Map with aas:operationVariable as key + Map correctMap = new LinkedHashMap<>(); + correctMap.put(OperationXMLConverter.OPERATION_VARIABLE, xmlObject); + return correctMap; + } + + private static RuntimeException createUnexpectedObjectRuntimeException(Object xmlObject) { + return new RuntimeException("Unexpected object: " + xmlObject); + } + + /** + * The AASXPackageExplorer uses "Template" instead of "Type" AssetKind This + * converts "Template" to "Type" + * + * @param assetKind + * @return + */ + public static String convertAssetKind(String assetKind) { + if (isTemplateAssetKind(assetKind)) { + assetKind = AssetKind.TYPE.toString(); + } + + return assetKind; + } + + private static boolean isTemplateAssetKind(String assetKind) { + return assetKind.toLowerCase().equals("template"); + } + +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java index 40ce6df2..b16eeab8 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/MetamodelToXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.xml; @@ -25,6 +40,7 @@ import org.eclipse.basyx.aas.factory.xml.converters.AssetAdministrationShellXMLConverter; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AasEnv; import org.eclipse.basyx.submodel.factory.xml.api.parts.ConceptDescriptionXMLConverter; import org.eclipse.basyx.submodel.factory.xml.converters.SubmodelXMLConverter; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; @@ -40,52 +56,65 @@ */ public class MetamodelToXMLConverter { public static final String AASENV = "aas:aasenv"; - + + /** + * Builds the XML for the given aasEnv + * + * @param aasEnv + * @param result + * a Result object to write the XML to e.g. ResultStream + * @throws TransformerException + * @throws ParserConfigurationException + */ + public static void convertToXML(AasEnv aasEnv, Result result) throws TransformerException, ParserConfigurationException { + convertToXML(aasEnv.getAssetAdministrationShells(), aasEnv.getAssets(), aasEnv.getConceptDescriptions(), aasEnv.getSubmodels(), result); + } + /** * Builds the XML for the given metamodel Objects * - * @param aasList the AASs to build the XML for - * @param assetList the Assets to build the XML for - * @param conceptDescriptionList the ConceptDescriptions to build the XML for - * @param submodelList the Submodels to build the XML for - * @param result a Result object to write the XML to e.g. ResultStream + * @param aasList + * the AASs to build the XML for + * @param assetList + * the Assets to build the XML for + * @param conceptDescriptionList + * the ConceptDescriptions to build the XML for + * @param submodelList + * the Submodels to build the XML for + * @param result + * a Result object to write the XML to e.g. ResultStream * @throws TransformerException * @throws ParserConfigurationException */ - public static void convertToXML(Collection aasList, Collection assetList, - Collection conceptDescriptionList, Collection submodelList, Result result) - throws TransformerException, ParserConfigurationException { - - DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); - Document document = documentBuilder.newDocument(); - - //creating the root tag + public static void convertToXML(Collection aasList, Collection assetList, Collection conceptDescriptionList, Collection submodelList, Result result) + throws TransformerException, ParserConfigurationException { + + Document document = createEmptyDocument(); + + // creating the root tag Element root = document.createElement(AASENV); - - //creating the Header information + + // creating the Header information root.setAttribute("xmlns:aas", "http://www.admin-shell.io/aas/2/0"); root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); root.setAttribute("xmlns:IEC61360", "http://www.admin-shell.io/IEC61360/2/0"); root.setAttribute("xsi:schemaLocation", "http://www.admin-shell.io/aas/2/0 AAS.xsd http://www.admin-shell.io/IEC61360/2/0 IEC61360.xsd"); document.appendChild(root); - Element buildAssetadminsroot = AssetAdministrationShellXMLConverter.buildAssetAdministrationShellsXML(document, aasList); root.appendChild(buildAssetadminsroot); - + Element assetsObj = AssetXMLConverter.buildAssetsXML(document, assetList); root.appendChild(assetsObj); Element subModelsroot = SubmodelXMLConverter.buildSubmodelsXML(document, submodelList); root.appendChild(subModelsroot); - + Element conceptDescriptionObj = ConceptDescriptionXMLConverter.buildConceptDescriptionsXML(document, conceptDescriptionList); root.appendChild(conceptDescriptionObj); - - - //create the xml file - //transform the DOM Object to an XML File + + // create the xml file + // transform the DOM Object to an XML File TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); @@ -95,4 +124,11 @@ public static void convertToXML(Collection aasList, C transformer.transform(domSource, result); } + + private static Document createEmptyDocument() throws ParserConfigurationException { + DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); + Document document = documentBuilder.newDocument(); + return document; + } } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLAASBundleFactory.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLAASBundleFactory.java new file mode 100644 index 00000000..b49939df --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLAASBundleFactory.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.factory.xml; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Set; + +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.bundle.AASBundleFactory; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.xml.sax.SAXException; + +/** + * Creates multiple {@link AASBundle} from an XML containing several AAS and + * Submodels
+ * TODO: ConceptDescriptions + * + * @author schnicke + * + */ +public class XMLAASBundleFactory { + private String content; + + /** + * + * @param xmlContent + * the content of the XML + */ + public XMLAASBundleFactory(String xmlContent) { + this.content = xmlContent; + } + + public XMLAASBundleFactory(Path xmlFile) throws IOException { + content = new String(Files.readAllBytes(xmlFile)); + } + + /** + * Creates the set of {@link AASBundle} contained in the XML string. + * + * @return + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + */ + public Set create() throws ParserConfigurationException, SAXException, IOException { + XMLToMetamodelConverter converter = new XMLToMetamodelConverter(content); + Collection shells = converter.parseAAS(); + Collection submodels = converter.parseSubmodels(); + Collection assets = converter.parseAssets(); + + return new AASBundleFactory().create(shells, submodels, assets); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java index a6621498..a1819cc7 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/XMLToMetamodelConverter.java @@ -1,16 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.xml; import java.io.IOException; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -20,6 +36,7 @@ import org.eclipse.basyx.aas.factory.xml.converters.AssetAdministrationShellXMLConverter; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AasEnv; import org.eclipse.basyx.submodel.factory.xml.api.parts.ConceptDescriptionXMLConverter; import org.eclipse.basyx.submodel.factory.xml.converters.SubmodelXMLConverter; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; @@ -35,8 +52,8 @@ */ public class XMLToMetamodelConverter { - private Map root = new HashMap<>(); - + private AasEnv aasEnv; + /** * Initializes the Parser with XML given as a String * @@ -47,68 +64,75 @@ public class XMLToMetamodelConverter { * @throws IOException */ @SuppressWarnings("unchecked") - public XMLToMetamodelConverter(String xmlContent) throws ParserConfigurationException, SAXException, IOException { - root.putAll((Map) XmlParser.buildXmlMap(xmlContent) - .get(MetamodelToXMLConverter.AASENV)); + public XMLToMetamodelConverter(String xmlContent) throws ParserConfigurationException, SAXException, IOException { + Map root = new LinkedHashMap<>(); + root.putAll((Map) XmlParser.buildXmlMap(xmlContent).get(MetamodelToXMLConverter.AASENV)); + + Map xmlAASs = (Map) root.get(AssetAdministrationShellXMLConverter.ASSET_ADMINISTRATION_SHELLS); + + Map xmlConceptDescriptions = (Map) root.get(ConceptDescriptionXMLConverter.CONCEPT_DESCRIPTIONS); + + List conceptDescriptions = ConceptDescriptionXMLConverter.parseConceptDescriptions(xmlConceptDescriptions); + + List shells = AssetAdministrationShellXMLConverter.parseAssetAdministrationShells(xmlAASs, conceptDescriptions); + + Map xmlSubmodels = (Map) root.get(SubmodelXMLConverter.SUBMODELS); + List submodels = SubmodelXMLConverter.parseSubmodels(xmlSubmodels); + Map xmlAssets = (Map) root.get(AssetXMLConverter.ASSETS); + List assets = AssetXMLConverter.parseAssets(xmlAssets); + + aasEnv = new AasEnv(shells, assets, conceptDescriptions, submodels); } - /** - * Parses the AASs form the XML + * Parses the AasEnv from the XML * - * @return the AASs parsed form the XML + * @return the AasEnv parsed from the XML + */ + public AasEnv parseAasEnv() { + return aasEnv; + } + + /** + * Parses the AASs from the XML + * + * @return the AASs parsed from the XML * @throws ParserConfigurationException * @throws SAXException * @throws IOException */ - @SuppressWarnings("unchecked") public List parseAAS() throws ParserConfigurationException, SAXException, IOException { - Map xmlAASs = (Map) root - .get(AssetAdministrationShellXMLConverter.ASSET_ADMINISTRATION_SHELLS); - // First, parse all conceptDescriptions - List conceptDescriptions = parseConceptDescriptions(); - // Then parse the AAS -> the available conceptDescriptions have to be mapped to the contained concept - // dictionaries - return AssetAdministrationShellXMLConverter.parseAssetAdministrationShells(xmlAASs, conceptDescriptions); + return new ArrayList<>(aasEnv.getAssetAdministrationShells()); } - /** - * Parses the Assets form the XML + * Parses the Assets from the XML * - * @return the Assets parsed form the XML + * @return the Assets parsed from the XML * @throws ParserConfigurationException * @throws SAXException * @throws IOException */ - @SuppressWarnings("unchecked") public List parseAssets() throws ParserConfigurationException, SAXException, IOException { - Map xmlAssets = (Map) root.get(AssetXMLConverter.ASSETS); - return AssetXMLConverter.parseAssets(xmlAssets); + return new ArrayList<>(aasEnv.getAssets()); } - /** - * Parses the Submodels form the XML + * Parses the Submodels from the XML * - * @return the Submodels parsed form the XML + * @return the Submodels parsed from the XML */ - @SuppressWarnings("unchecked") public List parseSubmodels() { - Map xmlSubmodels = (Map) root.get(SubmodelXMLConverter.SUBMODELS); - return SubmodelXMLConverter.parseSubmodels(xmlSubmodels); + return new ArrayList<>(aasEnv.getSubmodels()); } - /** - * Parses the ConceptDescriptions form the XML + * Parses the ConceptDescriptions from the XML * - * @return the ConceptDescriptions parsed form the XML + * @return the ConceptDescriptions parsed from the XML */ - @SuppressWarnings("unchecked") public List parseConceptDescriptions() { - Map xmlConceptDescriptions = (Map) root.get(ConceptDescriptionXMLConverter.CONCEPT_DESCRIPTIONS); - return ConceptDescriptionXMLConverter.parseConceptDescriptions(xmlConceptDescriptions); + return new ArrayList<>(aasEnv.getConceptDescriptions()); } - + } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java index 9ac57575..e201395d 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/AssetXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.xml.api.parts; @@ -14,6 +29,7 @@ import java.util.List; import java.util.Map; +import org.eclipse.basyx.aas.factory.xml.AASXPackageExplorerCompatibilityHandler; import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; import org.eclipse.basyx.aas.metamodel.map.parts.Asset; @@ -31,7 +47,8 @@ import com.google.common.base.Strings; /** - * Handles the conversion between IAsset objects and the XML tag <aas:assets> in both directions + * Handles the conversion between IAsset objects and the XML tag + * <aas:assets> in both directions * * @author conradi * @@ -43,38 +60,41 @@ public class AssetXMLConverter { public static final String ASSET_IDENTIFICATION_MODEL_REF = "aas:assetIdentificationModelRef"; public static final String ASSET_KIND = "aas:kind"; public static final String ASSET_BILLOFMATERIAL = "aas:billOfMaterialRef"; - + /** * Parses <aas:assets> and builds the Asset objects from it * - * @param xmlAssetObject a Map containing the content of the XML tag <aas:assets> + * @param xmlAssetObject + * a Map containing the content of the XML tag <aas:assets> * @return a List of IAsset objects parsed form the given XML Map */ public static List parseAssets(Map xmlAssetObject) { List> xmlAssets = XMLHelper.getList(xmlAssetObject.get(ASSET)); List assets = new ArrayList<>(); - + for (Map xmlAsset : xmlAssets) { Asset asset = new Asset(); - + IdentifiableXMLConverter.populateIdentifiable(xmlAsset, Identifiable.createAsFacadeNonStrict(asset, KeyElements.ASSET)); HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAsset, HasDataSpecification.createAsFacade(asset)); asset.setAssetKind(parseAssetKind(xmlAsset)); - - if(xmlAsset.containsKey(ASSET_IDENTIFICATION_MODEL_REF)) { + + if (xmlAsset.containsKey(ASSET_IDENTIFICATION_MODEL_REF)) { asset.setAssetIdentificationModel(parseAssetIdentificationModelRef(xmlAsset)); } - + assets.add(asset); } return assets; } - /** - * Parses <aas:assetIdentificationModelRef> and builds an IReference object from it + * Parses <aas:assetIdentificationModelRef> and builds an IReference + * object from it * - * @param xmlObject a Map containing the XML tag <aas:assetIdentificationModelRef> + * @param xmlObject + * a Map containing the XML tag + * <aas:assetIdentificationModelRef> * @return an IReference object parsed form the given XML Map */ @SuppressWarnings("unchecked") @@ -82,37 +102,40 @@ private static IReference parseAssetIdentificationModelRef(Map x Map semanticIDObj = (Map) xmlObject.get(ASSET_IDENTIFICATION_MODEL_REF); return ReferenceXMLConverter.parseReference(semanticIDObj); } - /** * Parses <aas:akind> and gets the correct AssetKind from it * - * @param xmlObject a Map containing the XML tag <aas:kind> + * @param xmlObject + * a Map containing the XML tag <aas:kind> * @return the parsed AssetKind or null if none was present */ private static AssetKind parseAssetKind(Map xmlObject) { String assetKindValue = XMLHelper.getString(xmlObject.get(ASSET_KIND)); if (!Strings.isNullOrEmpty(assetKindValue)) { + + assetKindValue = AASXPackageExplorerCompatibilityHandler.convertAssetKind(assetKindValue); + return AssetKind.fromString(assetKindValue); } else { throw new RuntimeException("Necessary value 'AssetKind' was not found for one of the Assets in the XML file."); } } - - - + /** * Builds <aas:assets> from a given Collection of IAsset objects * - * @param document the XML document - * @param assets a Collection of IAsset objects to build the XML for + * @param document + * the XML document + * @param assets + * a Collection of IAsset objects to build the XML for * @return the <aas:assets> XML tag for the given IAsset objects */ public static Element buildAssetsXML(Document document, Collection assets) { Element root = document.createElement(ASSETS); - + List xmlAssetList = new ArrayList<>(); - for(IAsset asset: assets) { + for (IAsset asset : assets) { Element assetRoot = document.createElement(ASSET); IdentifiableXMLConverter.populateIdentifiableXML(document, assetRoot, asset); HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, assetRoot, asset); @@ -121,36 +144,41 @@ public static Element buildAssetsXML(Document document, Collection asset buildAssetKind(document, assetRoot, asset); xmlAssetList.add(assetRoot); } - - for(Element element: xmlAssetList) { + + for (Element element : xmlAssetList) { root.appendChild(element); } return root; } - - + /** * Builds <aas:assetIdentificationModelRef> from a given IAsset object * - * @param document the XML document - * @param assetRoot the XML tag to be populated - * @param asset the IAsset object to build the XML for + * @param document + * the XML document + * @param assetRoot + * the XML tag to be populated + * @param asset + * the IAsset object to build the XML for */ private static void buildAssetIdentificationModelRef(Document document, Element assetRoot, IAsset asset) { IReference assetIdentificationModel = asset.getAssetIdentificationModel(); - if(assetIdentificationModel != null) { + if (assetIdentificationModel != null) { Element assetIdentificationroot = document.createElement(ASSET_IDENTIFICATION_MODEL_REF); assetIdentificationroot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, assetIdentificationModel)); assetRoot.appendChild(assetIdentificationroot); } } - + /** * Builds <aas:kind> from a given IAsset object * - * @param document the XML document - * @param assetRoot the XML tag to be populated - * @param asset the IAsset object to build the XML for + * @param document + * the XML document + * @param assetRoot + * the XML tag to be populated + * @param asset + * the IAsset object to build the XML for */ private static void buildAssetKind(Document document, Element root, IAsset asset) { if (asset.getAssetKind() != null) { @@ -159,13 +187,16 @@ private static void buildAssetKind(Document document, Element root, IAsset asset root.appendChild(kindRoot); } } - + /** * Builds <billOfMaterialRef> from a given IAsset object * - * @param document the XML document - * @param assetRoot the XML tag to be populated - * @param asset the IAsset object to build the XML for + * @param document + * the XML document + * @param assetRoot + * the XML tag to be populated + * @param asset + * the IAsset object to build the XML for */ private static void buildBillOfMaterial(Document document, Element root, IAsset asset) { IReference billOfMaterial = asset.getBillOfMaterial(); diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java index f6827c4c..be1ab2a9 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/api/parts/ViewXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.xml.api.parts; @@ -32,7 +47,8 @@ import org.w3c.dom.Element; /** - * Handles the conversion between IView objects and the XML tag <aas:views> in both directions + * Handles the conversion between IView objects and the XML tag + * <aas:views> in both directions * * @author conradi * @@ -47,88 +63,92 @@ public class ViewXMLConverter { /** * Parses <aas:views> and builds the IView objects from it * - * @param xmlObject a Map containing the XML tag <aas:views> + * @param xmlObject + * a Map containing the XML tag <aas:views> * @return a Set of IView objects parsed form the given XML Map */ @SuppressWarnings("unchecked") public static Collection parseViews(Map xmlObject) { Collection viewSet = new HashSet<>(); - if(xmlObject == null) return viewSet; - + if (xmlObject == null) + return viewSet; + xmlObject = (Map) xmlObject.get(VIEWS); - if(xmlObject == null) return viewSet; - + if (xmlObject == null) + return viewSet; + List> xmlViewList = XMLHelper.getList(xmlObject.get(VIEW)); - - for(Map xmlView: xmlViewList) { + + for (Map xmlView : xmlViewList) { View view = new View(); - + ReferableXMLConverter.populateReferable(xmlView, Referable.createAsFacadeNonStrict(view, KeyElements.VIEW)); HasSemanticsXMLConverter.populateHasSemantics(xmlView, HasSemantics.createAsFacade(view)); HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlView, HasDataSpecification.createAsFacade(view)); - + Map xmlContainedElementsObject = ((Map) xmlView.get(CONTAINED_ELEMENTS)); Map xmlContainedElementObject = (Map) xmlContainedElementsObject.get(CONTAINED_ELEMENT_REF); - + Set referenceSet = new HashSet<>(); referenceSet.add(ReferenceXMLConverter.parseReference(xmlContainedElementObject)); view.setContainedElement(referenceSet); - + viewSet.add(view); } - + return viewSet; } - - - - + /** * Builds <aas:views> from a given Collection of IView objects * - * @param document the XML document - * @param views a Collection of IView objects to build the XML for + * @param document + * the XML document + * @param views + * a Collection of IView objects to build the XML for * @return the <aas:views> XML tag for the given IView objects */ public static Element buildViewsXML(Document document, Collection views) { Element root = document.createElement(VIEWS); - + List viewList = new ArrayList<>(); - for(IView view: views) { + for (IView view : views) { Element viewRoot = document.createElement(VIEW); - + ReferableXMLConverter.populateReferableXML(document, viewRoot, view); HasSemanticsXMLConverter.populateHasSemanticsXML(document, viewRoot, view); HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, viewRoot, view); buildContainedElements(document, viewRoot, view); - + viewList.add(viewRoot); } - - for(Element element: viewList) { + + for (Element element : viewList) { root.appendChild(element); } return root; } - - + /** * Builds <aas:containedElements> from a given IView object * - * @param document the XML document - * @param xmlView the XML tag to be populated - * @param view the IView object to build the XML for + * @param document + * the XML document + * @param xmlView + * the XML tag to be populated + * @param view + * the IView object to build the XML for */ private static void buildContainedElements(Document document, Element xmlView, IView view) { Collection containedElement = view.getContainedElement(); - if(containedElement != null) { + if (containedElement != null) { Element xmlContainedElements = document.createElement(CONTAINED_ELEMENTS); Element xmlContainedElementsRef = document.createElement(CONTAINED_ELEMENT_REF); xmlContainedElements.appendChild(xmlContainedElementsRef); - xmlContainedElementsRef.appendChild(ReferenceXMLConverter.buildReferencesXML(document, containedElement)); + xmlContainedElementsRef.appendChild(ReferenceXMLConverter.buildReferencesXML(document, containedElement)); xmlView.appendChild(xmlContainedElements); } } diff --git a/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java index 7d95a57d..ea26eca4 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/xml/converters/AssetAdministrationShellXMLConverter.java @@ -1,16 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.factory.xml.converters; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -39,13 +55,14 @@ import org.w3c.dom.Element; /** - * Handles the conversion between IAssetAdministrationShell objects and the XML tag <aas:assetAdministrationShells> in both directions + * Handles the conversion between IAssetAdministrationShell objects and the XML + * tag <aas:assetAdministrationShells> in both directions * * @author conradi * */ public class AssetAdministrationShellXMLConverter { - + public static final String ASSET_ADMINISTRATION_SHELLS = "aas:assetAdministrationShells"; public static final String ASSET_ADMINISTRATION_SHELL = "aas:assetAdministrationShell"; public static final String DERIVED_FROM = "aas:derivedFrom"; @@ -56,50 +73,57 @@ public class AssetAdministrationShellXMLConverter { public static final String CONCEPT_DICTIONARY = "aas:conceptDictionary"; public static final String CONCEPT_DESCRIPTION_REFS = "aas:conceptDescriptionRefs"; public static final String CONCEPT_DESCRIPTION_REF = "aas:conceptDescriptionRef"; - - + /** - * Parses <aas:assetAdministrationShells> and builds the AssetAdministrationShell objects from it + * Parses <aas:assetAdministrationShells> and builds the + * AssetAdministrationShell objects from it * - * @param xmlAASObject a Map containing the content of the XML tag <aas:assetAdministrationShells> - * @param conceptDescriptions the available concept descriptions - * @return a List of IAssetAdministrationShell objects parsed form the given XML Map + * @param xmlAASObject + * a Map containing the content of the XML tag + * <aas:assetAdministrationShells> + * @param conceptDescriptions + * the available concept descriptions + * @return a List of IAssetAdministrationShell objects parsed form the given XML + * Map */ @SuppressWarnings("unchecked") - public static List parseAssetAdministrationShells(Map xmlAASObject, - Collection conceptDescriptions) { - List> xmlAASs = XMLHelper.getList(xmlAASObject.get(ASSET_ADMINISTRATION_SHELL)); + public static List parseAssetAdministrationShells(Map xmlAASObject, Collection conceptDescriptions) { + if (xmlAASObject == null) { + return Collections.emptyList(); + } + List aasList = new ArrayList<>(); - - for(Map xmlAAS: xmlAASs) { + + List> xmlAASs = XMLHelper.getList(xmlAASObject.get(ASSET_ADMINISTRATION_SHELL)); + for (Map xmlAAS : xmlAASs) { AssetAdministrationShell adminShell = new AssetAdministrationShell(); - + IdentifiableXMLConverter.populateIdentifiable(xmlAAS, Identifiable.createAsFacadeNonStrict(adminShell, KeyElements.ASSETADMINISTRATIONSHELL)); HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlAAS, HasDataSpecification.createAsFacade(adminShell)); - + Collection views = ViewXMLConverter.parseViews(xmlAAS); Collection conceptDictionary = parseConceptDictionaries(xmlAAS, conceptDescriptions); - + Map xmlAssetRef = (Map) xmlAAS.get(ASSET_REF); Reference assetRef = ReferenceXMLConverter.parseReference(xmlAssetRef); - + Map xmlDerivedFrom = (Map) xmlAAS.get(DERIVED_FROM); - IReference derivedFrom = ReferenceXMLConverter.parseReference(xmlDerivedFrom); + IReference derivedFrom = ReferenceXMLConverter.parseReference(xmlDerivedFrom); adminShell.setDerivedFrom(derivedFrom); - + adminShell.setViews(views); adminShell.setConceptDictionary(conceptDictionary); adminShell.setAssetReference(assetRef); - + Collection submodelRefs = parseSubmodelRefs(xmlAAS); adminShell.setSubmodelReferences(submodelRefs); - + aasList.add(adminShell); } + return aasList; } - - + /** * Parses <aas:submodelRefs> and builds {@link Reference} objects from it * @@ -110,7 +134,7 @@ public static List parseAssetAdministrationShells(Map @SuppressWarnings("unchecked") private static Collection parseSubmodelRefs(Map xmlObject) { Set refSet = new HashSet<>(); - + Map refMap = (Map) xmlObject.get(SUBMODEL_REFS); if (refMap == null) { @@ -121,48 +145,49 @@ private static Collection parseSubmodelRefs(Map xmlO for (Map xmlKey : xmlKeyList) { refSet.add(ReferenceXMLConverter.parseReference(xmlKey)); } - + return refSet; } - - + /** - * Parses <aas:conceptDictionaries> and builds IConceptDictionary objects from it + * Parses <aas:conceptDictionaries> and builds IConceptDictionary objects + * from it * - * @param xmlConceptDescriptionRefsObject a Map containing the XML tag <aas:conceptDictionaries> - * @param conceptDescriptions the available concept descriptions + * @param xmlConceptDescriptionRefsObject + * a Map containing the XML tag <aas:conceptDictionaries> + * @param conceptDescriptions + * the available concept descriptions * @return a Set of IConceptDictionary objects parsed form the given XML Map */ @SuppressWarnings("unchecked") - private static Collection parseConceptDictionaries( - Map xmlConceptDescriptionRefsObject, Collection conceptDescriptions) { + private static Collection parseConceptDictionaries(Map xmlConceptDescriptionRefsObject, Collection conceptDescriptions) { Set conceptDictionarySet = new HashSet<>(); - if(xmlConceptDescriptionRefsObject == null) return conceptDictionarySet; - + if (xmlConceptDescriptionRefsObject == null) + return conceptDictionarySet; + Map xmlConceptDictionaries = (Map) xmlConceptDescriptionRefsObject.get(CONCEPT_DICTIONARIES); - if(xmlConceptDictionaries == null) return conceptDictionarySet; - + if (xmlConceptDictionaries == null) + return conceptDictionarySet; + List> xmlConceptDictionaryList = XMLHelper.getList(xmlConceptDictionaries.get(CONCEPT_DICTIONARY)); for (Map xmlConceptDictionary : xmlConceptDictionaryList) { ConceptDictionary conceptDictionary = new ConceptDictionary(); ReferableXMLConverter.populateReferable(xmlConceptDictionary, Referable.createAsFacadeNonStrict(conceptDictionary, KeyElements.CONCEPTDICTIONARY)); - + Map xmlConceptDescriptionRefs = (Map) xmlConceptDictionary.get(CONCEPT_DESCRIPTION_REFS); HashSet referenceSet = new HashSet<>(); List> xmlConceptDescriptionRefsList = XMLHelper.getList(xmlConceptDescriptionRefs.get(CONCEPT_DESCRIPTION_REF)); for (Map xmlConceptDescriptionRef : xmlConceptDescriptionRefsList) { referenceSet.add(ReferenceXMLConverter.parseReference(xmlConceptDescriptionRef)); } - + conceptDictionary.setConceptDescriptions(getConceptDescriptions(referenceSet, conceptDescriptions)); conceptDictionarySet.add(conceptDictionary); } - + return conceptDictionarySet; } - - - + /** * Gets concept descriptions according to given references * @@ -170,8 +195,7 @@ private static Collection parseConceptDictionaries( * @param conceptDescriptions * @return the matching concept descriptions */ - private static Collection getConceptDescriptions(Collection referenceSet, - Collection conceptDescriptions) { + private static Collection getConceptDescriptions(Collection referenceSet, Collection conceptDescriptions) { Collection result = new ArrayList<>(); for (IReference ref : referenceSet) { if (ref.getKeys() == null || ref.getKeys().isEmpty()) { @@ -179,7 +203,7 @@ private static Collection getConceptDescriptions(Collection } IKey firstKey = ref.getKeys().iterator().next(); - if ( firstKey.getType() == KeyElements.CONCEPTDESCRIPTION && firstKey.isLocal() ) { + if (firstKey.getType() == KeyElements.CONCEPTDESCRIPTION && firstKey.isLocal()) { for (IConceptDescription description : conceptDescriptions) { if (description.getIdentification().getId().equals(firstKey.getValue())) { result.add(description); @@ -191,86 +215,96 @@ private static Collection getConceptDescriptions(Collection } /** - * Builds <aas:assetAdministrationShells> from a given Collection of IAssetAdministrationShell objects + * Builds <aas:assetAdministrationShells> from a given Collection of + * IAssetAdministrationShell objects * - * @param document the XML document - * @param assetAdministrationShells a Collection of IAssetAdministrationShell objects to build the XML for - * @return the <aas:assetAdministrationShells> XML tag for the given IAssetAdministrationShell objects + * @param document + * the XML document + * @param assetAdministrationShells + * a Collection of IAssetAdministrationShell objects to build the XML + * for + * @return the <aas:assetAdministrationShells> XML tag for the given + * IAssetAdministrationShell objects */ public static Element buildAssetAdministrationShellsXML(Document document, Collection assetAdministrationShells) { Element root = document.createElement(ASSET_ADMINISTRATION_SHELLS); - + List xmlAASList = new ArrayList(); for (IAssetAdministrationShell aas : assetAdministrationShells) { Element aasRoot = document.createElement(ASSET_ADMINISTRATION_SHELL); IdentifiableXMLConverter.populateIdentifiableXML(document, aasRoot, aas); HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, aasRoot, aas); - + buildDerivedFrom(document, aasRoot, aas); buildAssetRef(document, aasRoot, aas); buildSubmodelRef(document, aasRoot, aas); Collection views = aas.getViews(); - + Element buildViews = ViewXMLConverter.buildViewsXML(document, views); aasRoot.appendChild(buildViews); aasRoot.appendChild(buildConceptDictionary(document, aas)); xmlAASList.add(aasRoot); } - + for (Element element : xmlAASList) { root.appendChild(element); } return root; } - - + /** * Builds <aas:derivedFrom> from a given IAssetAdministrationShell object * - * @param document the XML document - * @param root the XML tag to be populated - * @param aas the IAssetAdministrationShell object to build the XML for + * @param document + * the XML document + * @param root + * the XML tag to be populated + * @param aas + * the IAssetAdministrationShell object to build the XML for */ private static void buildDerivedFrom(Document document, Element root, IAssetAdministrationShell aas) { IReference derivedFrom = aas.getDerivedFrom(); - if(derivedFrom != null) { + if (derivedFrom != null) { Element derivedFromRoot = document.createElement(DERIVED_FROM); - derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, derivedFrom)); + derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, derivedFrom)); root.appendChild(derivedFromRoot); } } - /** * Builds <aas:assetRef> from a given IAssetAdministrationShell object * - * @param document the XML document - * @param root the XML tag to be populated - * @param aas the IAssetAdministrationShell object to build the XML for + * @param document + * the XML document + * @param root + * the XML tag to be populated + * @param aas + * the IAssetAdministrationShell object to build the XML for */ private static void buildAssetRef(Document document, Element root, IAssetAdministrationShell aas) { IReference assetRef = aas.getAssetReference(); - if(assetRef!=null) { + if (assetRef != null) { Element assetrefRoot = document.createElement(ASSET_REF); assetrefRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, assetRef)); root.appendChild(assetrefRoot); } } - /** * Builds <aas:submodelRefs> from a given IAssetAdministrationShell object * - * @param document the XML document - * @param root the XML tag to be populated - * @param aas the IAssetAdministrationShell object to build the XML for + * @param document + * the XML document + * @param root + * the XML tag to be populated + * @param aas + * the IAssetAdministrationShell object to build the XML for */ private static void buildSubmodelRef(Document document, Element root, IAssetAdministrationShell aas) { Collection submodelRef = aas.getSubmodelReferences(); - - + if (submodelRef != null && !submodelRef.isEmpty()) { Element submodelRefsRoot = document.createElement(SUBMODEL_REFS); for (IReference ref : submodelRef) { @@ -282,19 +316,22 @@ private static void buildSubmodelRef(Document document, Element root, IAssetAdmi root.appendChild(submodelRefsRoot); } } - /** - * Builds <aas:conceptDictionaries> from a given IAssetAdministrationShell object + * Builds <aas:conceptDictionaries> from a given IAssetAdministrationShell + * object * - * @param document the XML document - * @param aas the IAssetAdministrationShell object to build the XML for - * @return the <aas:conceptDictionaries> XML tag build from the IAssetAdministrationShell object + * @param document + * the XML document + * @param aas + * the IAssetAdministrationShell object to build the XML for + * @return the <aas:conceptDictionaries> XML tag build from the + * IAssetAdministrationShell object */ private static Element buildConceptDictionary(Document document, IAssetAdministrationShell aas) { Collection conceptDicionary = aas.getConceptDictionary(); Element conceptDicts = document.createElement(CONCEPT_DICTIONARIES); - for(IConceptDictionary iConceptDictionary: conceptDicionary) { + for (IConceptDictionary iConceptDictionary : conceptDicionary) { Element conceptDict = document.createElement(CONCEPT_DICTIONARY); Element concDescRoot = document.createElement(CONCEPT_DESCRIPTION_REFS); if (iConceptDictionary.getIdShort() != null) { @@ -305,14 +342,14 @@ private static Element buildConceptDictionary(Document document, IAssetAdministr conceptDict.appendChild(concDescRoot); conceptDicts.appendChild(conceptDict); Collection conceptDescriptionRef = iConceptDictionary.getConceptDescriptionReferences(); - for (IReference ref: conceptDescriptionRef) { - if(ref != null) { + for (IReference ref : conceptDescriptionRef) { + if (ref != null) { Element conceptDescriptionRefRoot = document.createElement(CONCEPT_DESCRIPTION_REF); concDescRoot.appendChild(conceptDescriptionRefRoot); conceptDescriptionRefRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, ref)); } } - + } return conceptDicts; } diff --git a/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java b/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java index ef77a9cb..34cbdd30 100644 --- a/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java +++ b/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java @@ -3,14 +3,14 @@ */ package org.eclipse.basyx.aas.manager; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import org.eclipse.basyx.aas.aggregator.AASAggregatorAPIHelper; import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy; -import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; import org.eclipse.basyx.aas.manager.api.IAssetAdministrationShellManager; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell; @@ -23,7 +23,6 @@ import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel; import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.restapi.SubmodelProvider; -import org.eclipse.basyx.vab.exception.FeatureNotImplementedException; import org.eclipse.basyx.vab.factory.java.ModelProxyFactory; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.VABPathTools; @@ -57,8 +56,7 @@ public ConnectedAssetAdministrationShellManager(IAASRegistry directory) { * @param directory * @param provider */ - public ConnectedAssetAdministrationShellManager(IAASRegistry directory, - IConnectorFactory provider) { + public ConnectedAssetAdministrationShellManager(IAASRegistry directory, IConnectorFactory provider) { this.aasDirectory = directory; this.connectorFactory = provider; this.proxyFactory = new ModelProxyFactory(provider); @@ -86,7 +84,7 @@ public ConnectedAssetAdministrationShell retrieveAAS(IIdentifier aasId) { public Map retrieveSubmodels(IIdentifier aasId) { AASDescriptor aasDesc = aasDirectory.lookupAAS(aasId); Collection smDescriptors = aasDesc.getSubmodelDescriptors(); - Map submodels = new HashMap<>(); + Map submodels = new LinkedHashMap<>(); for (SubmodelDescriptor smDesc : smDescriptors) { String smEndpoint = smDesc.getFirstEndpoint(); String smIdShort = smDesc.getIdShort(); @@ -108,9 +106,16 @@ private VABElementProxy getAASProxyFromId(IIdentifier aasId) { return proxyFactory.createProxy(addr); } + /** + * Retrieves all AASs registered. This can take a long time if many AASs are + * present! Use with caution! + * + * @return all AASs registered + */ @Override public Collection retrieveAASAll() { - throw new FeatureNotImplementedException(); + List aasDescriptors = aasDirectory.lookupAll(); + return aasDescriptors.stream().map(d -> retrieveAAS(d.getIdentifier())).collect(Collectors.toList()); } @Override @@ -136,17 +141,17 @@ public void deleteAAS(IIdentifier id) { @Override public void createSubmodel(IIdentifier aasId, Submodel submodel) { - + // Push the SM to the server using the ConnectedAAS retrieveAAS(aasId).addSubmodel(submodel); - + // Lookup AAS descriptor AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId); // Get aas endpoint String addr = aasDescriptor.getFirstEndpoint(); - + // Register the SM String smEndpoint = VABPathTools.concatenatePaths(addr, AssetAdministrationShell.SUBMODELS, submodel.getIdShort(), SubmodelProvider.SUBMODEL); aasDirectory.register(aasId, new SubmodelDescriptor(submodel, smEndpoint)); @@ -163,19 +168,12 @@ public void deleteSubmodel(IIdentifier aasId, IIdentifier submodelId) { @Override public void createAAS(AssetAdministrationShell aas, String endpoint) { endpoint = VABPathTools.stripSlashes(endpoint); - if (!endpoint.endsWith(AASAggregatorProvider.PREFIX)) { - endpoint += "/" + AASAggregatorProvider.PREFIX; - } - IModelProvider provider = connectorFactory.getConnector(endpoint); + IModelProvider provider = connectorFactory.create(endpoint); AASAggregatorProxy proxy = new AASAggregatorProxy(provider); proxy.createAAS(aas); - try { + String combinedEndpoint = VABPathTools.concatenatePaths(endpoint, AASAggregatorAPIHelper.getAASAccessPath(aas.getIdentification())); + aasDirectory.register(new AASDescriptor(aas, combinedEndpoint)); - String combinedEndpoint = VABPathTools.concatenatePaths(endpoint, URLEncoder.encode(aas.getIdentification().getId(), "UTF-8"), "aas"); - aasDirectory.register(new AASDescriptor(aas, combinedEndpoint)); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Encoding failed. This should never happen"); - } } } diff --git a/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java b/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java index 784debd6..efce28d4 100644 --- a/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java +++ b/src/main/java/org/eclipse/basyx/aas/manager/api/IAssetAdministrationShellManager.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.manager.api; @@ -18,10 +33,9 @@ import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.submodel.metamodel.map.Submodel; - - /** - * Technology independent interface to technology specific Asset Administration Shell (AAS) manager class. + * Technology independent interface to technology specific Asset Administration + * Shell (AAS) manager class. * * @author schoeffler, ziesche, kuhn * @@ -31,12 +45,12 @@ public interface IAssetAdministrationShellManager { * Retrieve an AAS based on its ID */ public IAssetAdministrationShell retrieveAAS(IIdentifier aasId) throws Exception; - + /** * Retrieve all local AAS from the technology layer */ public Collection retrieveAASAll(); - + /** * Creates an AAS on a remote server * diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java index 06115aa1..85fb19b5 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAasEnv.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api; @@ -18,10 +33,10 @@ public interface IAasEnv { Collection getAssets(); - + Collection getAssetAdministrationShells(); - + Collection getSubmodels(); - + Collection getConceptDescriptions(); } diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java index 7d016a2b..8850672c 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/IAssetAdministrationShell.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api; @@ -96,7 +111,6 @@ public interface IAssetAdministrationShell extends IElement, IIdentifiable, IHas */ public IReference getAssetReference(); - /** * Gets the views associated with the AAS.
* If needed stakeholder specific views can be defined on the elements of the diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java index 944b97e5..f74b097e 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IConceptDictionary.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.parts; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java index 9ec0cd09..6c8f8769 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/IView.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.parts; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java index 4dcece66..daec147a 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/AssetKind.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.parts.asset; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java index a9af5ed2..cfcd7bf8 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/parts/asset/IAsset.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.parts.asset; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java index 248188fd..27eec9f7 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/policypoints/IAccessControlPolicyPoints.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.policypoints; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java index 8ac3316f..bf281b1a 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ICertificate.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.security; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java b/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java index 60abcbf6..65f14d60 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/api/security/ISecurity.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.api.security; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java b/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java index a8044002..7e388734 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/connected/ConnectedAssetAdministrationShell.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.connected; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -124,16 +139,14 @@ public IAsset getAsset() { @SuppressWarnings("unchecked") @Override public Collection getViews() { - Collection> coll = (Collection>) getElem() - .getPath(AssetAdministrationShell.VIEWS); + Collection> coll = (Collection>) getElem().getPath(AssetAdministrationShell.VIEWS); return coll.stream().map(View::createAsFacade).collect(Collectors.toSet()); } @SuppressWarnings("unchecked") @Override public Collection getConceptDictionary() { - Collection> set = (Collection>) getElem() - .getPath(AssetAdministrationShell.CONCEPTDICTIONARY); + Collection> set = (Collection>) getElem().getPath(AssetAdministrationShell.CONCEPTDICTIONARY); return set.stream().map(ConceptDictionary::createAsFacade).collect(Collectors.toSet()); } @@ -142,7 +155,7 @@ public Collection getConceptDictionary() { public Map getSubmodels() { Collection> submodelCollection = (Collection>) getProxy().getValue(AssetAdministrationShell.SUBMODELS); - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); for (Map m : submodelCollection) { Submodel sm = Submodel.createAsFacade(m); @@ -192,10 +205,10 @@ public Collection getSubmodelReferences() { public IReference getAssetReference() { return Reference.createAsFacade((Map) getElem().getPath(AssetAdministrationShell.ASSETREF)); } - + private KeyElements getKeyElement() { return KeyElements.ASSETADMINISTRATIONSHELL; - } + } @Override public IReference getReference() { diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/exception/IdShortDuplicationException.java b/src/main/java/org/eclipse/basyx/aas/metamodel/exception/IdShortDuplicationException.java new file mode 100644 index 00000000..69def99c --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/exception/IdShortDuplicationException.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.metamodel.exception; + +import java.util.Map; + +/** + * This class represents the exception when there are two Submodel elements that + * has same IdShort. + * + * @author danish + * + */ +public class IdShortDuplicationException extends MetamodelConstructionException { + private static final long serialVersionUID = 1L; + + public IdShortDuplicationException(Class clazz, Map map) { + super(clazz, map); + } + + public IdShortDuplicationException(Map map) { + super("Could not construct meta model element due to IdShort duplication. Passed argument was " + map.toString()); + } + +} diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java b/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java index 42ede92b..0ea66b5d 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/exception/MetamodelConstructionException.java @@ -1,28 +1,48 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.exception; import java.util.Map; +import org.eclipse.basyx.vab.exception.provider.ProviderException; + /** - * This class is used to throw exception when - * metamodel's createAsFacade from map does not work - * due to absence of mandatory fields + * This class is used to throw exception when metamodel's createAsFacade from + * map does not work due to absence of mandatory fields * * @author haque * */ -public class MetamodelConstructionException extends RuntimeException { +public class MetamodelConstructionException extends ProviderException { private static final long serialVersionUID = 1L; - - public MetamodelConstructionException(Class clazz , Map map) { + + public MetamodelConstructionException(Class clazz, Map map) { super("Could not construct meta model element " + clazz.getName() + ". Passed argument was " + map.toString()); } + + public MetamodelConstructionException(String exceptionMessage) { + super(exceptionMessage); + } } diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java index d61650e1..59c8bebd 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/AasEnv.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map; @@ -27,27 +42,25 @@ import org.eclipse.basyx.vab.model.VABModelMap; /** - * AasEnv class + * AasEnv class * * @author gordt */ public class AasEnv extends VABModelMap implements IAasEnv { - + public static final String ASSETS = "assets"; public static final String ASSETADMINISTRATIONSHELLS = "assetAdministrationShells"; public static final String SUBMODELS = "submodels"; public static final String CONCEPTDESCRIPTIONS = "conceptDescriptions"; public static final String MODELTYPE = "AasEnv"; - public AasEnv() { // Add model type putAll(new ModelType(MODELTYPE)); } - public AasEnv(Collection aasList, Collection assetList, - Collection conceptDescriptionList, Collection submodelList) { + public AasEnv(Collection aasList, Collection assetList, Collection conceptDescriptionList, Collection submodelList) { setAssetAdministrationShells(aasList); setAssets(assetList); setConceptDescriptions(conceptDescriptionList); @@ -69,48 +82,46 @@ public static AasEnv createAsFacade(Map map) { } AasEnv ret = new AasEnv(); - + Collection assetsTarget = new LinkedList<>(); if (map.get(ASSETS) != null && map.get(ASSETS) instanceof Collection) { Collection> objectMapCollection = (Collection>) map.get(ASSETS); - for(Map objectMap : objectMapCollection) { + for (Map objectMap : objectMapCollection) { assetsTarget.add(Asset.createAsFacade(objectMap)); } } ret.put(ASSETS, assetsTarget); - + Collection aasTarget = new LinkedList<>(); if (map.get(ASSETADMINISTRATIONSHELLS) != null && map.get(ASSETADMINISTRATIONSHELLS) instanceof Collection) { Collection> objectMapCollection = (Collection>) map.get(ASSETADMINISTRATIONSHELLS); - for(Map objectMap : objectMapCollection) { + for (Map objectMap : objectMapCollection) { aasTarget.add(AssetAdministrationShell.createAsFacade(objectMap)); } } ret.put(ASSETADMINISTRATIONSHELLS, aasTarget); - + Collection submodelsTarget = new LinkedList<>(); if (map.get(SUBMODELS) != null && map.get(SUBMODELS) instanceof Collection) { Collection> objectMapCollection = (Collection>) map.get(SUBMODELS); - for(Map objectMap : objectMapCollection) { + for (Map objectMap : objectMapCollection) { submodelsTarget.add(Submodel.createAsFacade(objectMap)); } } ret.put(SUBMODELS, submodelsTarget); - + Collection conceptDescriptionsTarget = new LinkedList<>(); if (map.get(CONCEPTDESCRIPTIONS) != null && map.get(CONCEPTDESCRIPTIONS) instanceof Collection) { Collection> objectMapCollection = (Collection>) map.get(CONCEPTDESCRIPTIONS); - for(Map objectMap : objectMapCollection) { + for (Map objectMap : objectMapCollection) { conceptDescriptionsTarget.add(ConceptDescription.createAsFacade(objectMap)); } } ret.put(CONCEPTDESCRIPTIONS, conceptDescriptionsTarget); - + return ret; } - - - + @SuppressWarnings("unchecked") @Override public Collection getAssets() { @@ -123,7 +134,7 @@ public Collection getAssets() { public void setAssets(Collection assets) { put(ASSETS, assets); } - + @SuppressWarnings("unchecked") @Override public Collection getAssetAdministrationShells() { @@ -136,7 +147,12 @@ public Collection getAssetAdministrationShells() { public void setAssetAdministrationShells(Collection assetAdministrationShells) { put(ASSETADMINISTRATIONSHELLS, assetAdministrationShells); } - + + @SuppressWarnings("unchecked") + public void addAssetAdministrationShell(IAssetAdministrationShell aas) { + ((Collection) get(ASSETADMINISTRATIONSHELLS)).add(aas); + } + @SuppressWarnings("unchecked") @Override public Collection getSubmodels() { @@ -150,6 +166,11 @@ public void setSubmodels(Collection submodels) { put(SUBMODELS, submodels); } + @SuppressWarnings("unchecked") + public void addSubmodel(ISubmodel submodel) { + ((Collection) get(SUBMODELS)).add(submodel); + } + @SuppressWarnings("unchecked") @Override public Collection getConceptDescriptions() { diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java index 1d7ed15c..172adc19 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/AssetAdministrationShell.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map; @@ -77,9 +92,10 @@ public class AssetAdministrationShell extends VABModelMap implements IAs public AssetAdministrationShell() { this(null, null, new Asset(), new HashSet(), new HashSet(), new HashSet()); } - + /** * Constructor accepting only mandatory attributes + * * @param idShort * @param identification * @param asset @@ -90,11 +106,10 @@ public AssetAdministrationShell(String idShort, IIdentifier identification, Asse setIdShort(idShort); } - public AssetAdministrationShell(Reference derivedFrom, Security security, Asset asset, - Collection submodels, Collection dictionaries, Collection views) { + public AssetAdministrationShell(Reference derivedFrom, Security security, Asset asset, Collection submodels, Collection dictionaries, Collection views) { // Add model type putAll(new ModelType(MODELTYPE)); - + // Add qualifiers putAll(new Identifiable()); putAll(new HasDataSpecification()); @@ -123,30 +138,28 @@ public static AssetAdministrationShell createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(AssetAdministrationShell.class, map); } - + if (!map.containsKey(SUBMODELS)) { map.put(SUBMODELS, new ArrayList<>()); } AssetAdministrationShell ret = new AssetAdministrationShell(); ret.setMap(map); - return ret; + return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ @SuppressWarnings("unchecked") public static boolean isValid(Map map) { - return Identifiable.isValid(map) && - map.containsKey(AssetAdministrationShell.ASSET) && - Asset.isValid((Map)map.get(AssetAdministrationShell.ASSET)); + return Identifiable.isValid(map) && map.containsKey(AssetAdministrationShell.ASSET) && Asset.isValid((Map) map.get(AssetAdministrationShell.ASSET)); } @Override @@ -260,8 +273,7 @@ public void setConceptDictionary(Collection dictionaries) { @Override @SuppressWarnings("unchecked") public Collection getConceptDictionary() { - Collection> coll = (Collection>) get( - AssetAdministrationShell.CONCEPTDICTIONARY); + Collection> coll = (Collection>) get(AssetAdministrationShell.CONCEPTDICTIONARY); return coll.stream().map(ConceptDictionary::createAsFacade).collect(Collectors.toSet()); } @@ -309,10 +321,10 @@ public void addSubmodel(Submodel submodel) { addSubmodelReferences(submodel); } - @Override public void removeSubmodel(IIdentifier id) { - // Currently not implemented since future of Submodel References in AAS is not clear + // Currently not implemented since future of Submodel References in AAS is not + // clear throw new FeatureNotImplementedException(); } @@ -353,18 +365,20 @@ private void addSubmodelReferences(Submodel submodel) { private KeyElements getKeyElement() { return KeyElements.ASSETADMINISTRATIONSHELL; } - + /** - * Set reference of current AAS to each Submodel of a collection - * as a parent reference + * Set reference of current AAS to each Submodel of a collection as a parent + * reference * - * @param submodels collection of Submodels + * @param submodels + * collection of Submodels */ private void setSubmodelParent(Collection submodels) { for (Submodel submodel : submodels) { submodel.setParent(getReference()); } } + @Override public IReference getReference() { return Identifiable.createAsFacade(this, getKeyElement()).getReference(); diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java index 041755ad..b28b8d6e 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.descriptor; @@ -34,7 +49,7 @@ public class AASDescriptor extends ModelDescriptor { public static final String MODELTYPE = "AssetAdministrationShellDescriptor"; public static final String ASSET = "asset"; - + /** * Create descriptor from existing hash map */ @@ -61,7 +76,6 @@ public AASDescriptor(IAssetAdministrationShell assetAdministrationShell, String this(assetAdministrationShell.getIdShort(), assetAdministrationShell.getIdentification(), assetAdministrationShell.getAsset(), endpoint); } - /** * Create a new descriptor with aasid, idshort , assetid, and endpoint */ @@ -73,11 +87,11 @@ public AASDescriptor(String idShort, IIdentifier aasid, IAsset asset, String htt // Set Submodels put(AssetAdministrationShell.SUBMODELS, new HashSet()); - + // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Create a new descriptor with minimal information */ @@ -98,7 +112,7 @@ public AASDescriptor(String idShort, IIdentifier aasid, String httpEndpoint) { public AASDescriptor(IIdentifier aasid, String httpEndpoint) { this("", aasid, httpEndpoint); } - + /** * Add a sub model descriptor */ @@ -106,7 +120,7 @@ public AASDescriptor(IIdentifier aasid, String httpEndpoint) { public AASDescriptor addSubmodelDescriptor(SubmodelDescriptor desc) { // Sub model descriptors are stored in a list Collection> submodelDescriptors = (Collection>) get(AssetAdministrationShell.SUBMODELS); - + // Add new sub model descriptor to list submodelDescriptors.add(desc); put(AssetAdministrationShell.SUBMODELS, submodelDescriptors); @@ -147,8 +161,7 @@ public void removeSubmodelDescriptor(IIdentifier id) { @SuppressWarnings("unchecked") public SubmodelDescriptor getSubmodelDescriptorFromIdentifierId(String subModelId) { // Sub model descriptors are stored in a list - Collection> smDescriptorMaps = (Collection>) get( - AssetAdministrationShell.SUBMODELS); + Collection> smDescriptorMaps = (Collection>) get(AssetAdministrationShell.SUBMODELS); // Go through all descriptors (as maps) and find the one with the subModelId for (Map smDescriptorMap : smDescriptorMaps) { @@ -158,7 +171,7 @@ public SubmodelDescriptor getSubmodelDescriptorFromIdentifierId(String subModelI return new SubmodelDescriptor(smDescriptorMap); } } - + // No descriptor found return null; } @@ -195,7 +208,7 @@ public Collection getSubmodelDescriptors() { protected String getModelType() { return MODELTYPE; } - + /** * Get asset */ @@ -204,7 +217,7 @@ public IAsset getAsset() { Map assetModel = (Map) get(ASSET); return Asset.createAsFacade(assetModel); } - + @Override public void validate(Map map) { super.validate(map); @@ -215,4 +228,3 @@ public void validate(Map map) { } } } - diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java index 7c0b29ee..bc9ca0c8 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/CustomId.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.descriptor; diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java index 8dc0b627..27f3d1bb 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java @@ -1,18 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.descriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Iterator; import java.util.Map; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; @@ -25,10 +41,8 @@ import org.eclipse.basyx.vab.model.VABModelMap; /** - * Abstract class for a model descriptor that contains: - * - a short id - * - an identifier - * - endpoints + * Abstract class for a model descriptor that contains: - a short id - an + * identifier - endpoints * * @author espen * @@ -63,10 +77,8 @@ public ModelDescriptor(String idShort, IIdentifier id, String httpEndpoint) { put(Identifiable.IDENTIFICATION, identifierMap); // Set Endpoints - HashMap endpointWrapper = new HashMap<>(); - endpointWrapper.put(AssetAdministrationShell.TYPE, "http"); - endpointWrapper.put(AssetAdministrationShell.ADDRESS, httpEndpoint); - put(ENDPOINTS, Arrays.asList(endpointWrapper)); + Map endpointWrapper = convertEndpointToMap(httpEndpoint, "http"); + setEndpoints(Arrays.asList(endpointWrapper)); } /** @@ -77,19 +89,48 @@ public IIdentifier getIdentifier() { Map identifierModel = (Map) get(Identifiable.IDENTIFICATION); return Identifier.createAsFacade(identifierModel); } - + public String getIdShort() { - // Passing null in KeyElement type since it doesn't matter while only retrieving idShort + // Passing null in KeyElement type since it doesn't matter while only retrieving + // idShort return Referable.createAsFacade(this, null).getIdShort(); } + /** + * Adds an endpoint + * + * @param endpoint + */ + public void addEndpoint(String endpoint) { + Collection> endpointsCollection = getEndpoints(); + + Map endpointWrapper = convertEndpointToMap(endpoint, "http"); + endpointsCollection.add(endpointWrapper); + setEndpoints(endpointsCollection); + } + + public void removeEndpoint(String endpoint) { + Collection> endpointsCollection = getEndpoints(); + + Iterator> iterator = endpointsCollection.iterator(); + while (iterator.hasNext()) { + Map endpointMap = iterator.next(); + if (endpointMap.containsKey(AssetAdministrationShell.ADDRESS) && endpointMap.get(AssetAdministrationShell.ADDRESS) != null && endpointMap.get(AssetAdministrationShell.ADDRESS).toString().equalsIgnoreCase(endpoint)) { + iterator.remove(); + break; + } + } + setEndpoints(endpointsCollection); + } + /** * Return first AAS endpoint */ @SuppressWarnings("unchecked") public String getFirstEndpoint() { Object e = get(ENDPOINTS); - // Extract String from endpoint for set or list representations of the endpoint wrappers + // Extract String from endpoint for set or list representations of the endpoint + // wrappers if (e instanceof Collection) { Collection> endpoints = (Collection>) e; if (endpoints.isEmpty()) { @@ -102,28 +143,36 @@ public String getFirstEndpoint() { } return ""; } - + /** * Return all AAS endpoints */ @SuppressWarnings("unchecked") public Collection> getEndpoints() { Object endpoints = get(ENDPOINTS); - // Extract String from endpoint for set or list representations of the endpoint wrappers + // Extract String from endpoint for set or list representations of the endpoint + // wrappers if (endpoints instanceof Collection) { - return (Collection>) endpoints; + // Create a new return list and insert all endpoints. If the endpoints are + // created using Arrays.asList() which is immutable, this can be solved + Collection> ret = new ArrayList>(); + for (Map endpointMap : (Collection>) endpoints) { + ret.add(endpointMap); + } + return ret; } else { return new ArrayList<>(); } } - + /** - * Validates a model descriptor by checking whether - * idShort, identification and endpoints key is present in the given map + * Validates a model descriptor by checking whether idShort, identification and + * endpoints key is present in the given map + * * @param map */ protected void validate(Map map) { - if (!map.containsKey(Referable.IDSHORT) || !(map.get(Referable.IDSHORT) instanceof String)) + if (!map.containsKey(Referable.IDSHORT) || !(map.get(Referable.IDSHORT) instanceof String)) throw new MalformedRequestException(getModelType() + " is missing idShort entry"); if (!map.containsKey(Identifiable.IDENTIFICATION) || !(map.get(Identifiable.IDENTIFICATION) instanceof Map)) throw new MalformedRequestException(getModelType() + " is missing identification entry"); @@ -132,4 +181,22 @@ protected void validate(Map map) { } protected abstract String getModelType(); + + /** + * Converts an endpoint to a map wrapper + * + * @param endpoint + * @param type + * @return + */ + private Map convertEndpointToMap(String endpoint, String type) { + LinkedHashMap endpointWrapper = new LinkedHashMap<>(); + endpointWrapper.put(AssetAdministrationShell.TYPE, type); + endpointWrapper.put(AssetAdministrationShell.ADDRESS, endpoint); + return endpointWrapper; + } + + private void setEndpoints(Collection> endpointsCollection) { + put(ENDPOINTS, endpointsCollection); + } } diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java index cd558d14..a8114ae5 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelUrn.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.descriptor; @@ -18,7 +33,8 @@ import org.slf4j.LoggerFactory; /** - * Create URNs with the format urn: {@literal :::::#} + * Create URNs with the format urn: + * {@literal :::::#} * * @author kuhn * @@ -30,7 +46,7 @@ public class ModelUrn extends Identifier { private ModelUrn() { setIdType(IdentifierType.IRI); } - + /** * Constructor that accepts a single, raw URN */ @@ -38,42 +54,51 @@ public ModelUrn(String rawURN) { this(); setId(rawURN); } - - + /** * Constructor that build a URN */ public ModelUrn(String legalEntity, String subUnit, String subModel, String version, String revision, String elementId, String elementInstance) { this(); - // Goal is: urn::::::# + // Goal is: + // urn::::::# StringBuffer urnBuilder = new StringBuffer(); - + // Start with header urnBuilder.append("urn:"); // - Add URN components until instance - if (legalEntity != null) urnBuilder.append(legalEntity); urnBuilder.append(":"); - if (subUnit != null) urnBuilder.append(subUnit); urnBuilder.append(":"); - if (subModel != null) urnBuilder.append(subModel); urnBuilder.append(":"); - if (version != null) urnBuilder.append(version); urnBuilder.append(":"); - if (revision != null) urnBuilder.append(revision); urnBuilder.append(":"); - if (elementId != null) urnBuilder.append(elementId); + if (legalEntity != null) + urnBuilder.append(legalEntity); + urnBuilder.append(":"); + if (subUnit != null) + urnBuilder.append(subUnit); + urnBuilder.append(":"); + if (subModel != null) + urnBuilder.append(subModel); + urnBuilder.append(":"); + if (version != null) + urnBuilder.append(version); + urnBuilder.append(":"); + if (revision != null) + urnBuilder.append(revision); + urnBuilder.append(":"); + if (elementId != null) + urnBuilder.append(elementId); // - Add element instance, prefix with '#' - if (elementInstance != null) urnBuilder.append("#"+elementInstance); - + if (elementInstance != null) + urnBuilder.append("#" + elementInstance); + // Build URN setId(urnBuilder.toString()); } - - - + /** * Get URN as string */ public String getURN() { return getId(); } - - + /** * Get URL encoded URN as string */ @@ -87,13 +112,13 @@ public String getEncodedURN() { return null; } } - + /** - * Create a new ModelUrn by appending a String to the URN string, e.g. to create a new element instance + * Create a new ModelUrn by appending a String to the URN string, e.g. to create + * a new element instance */ public ModelUrn append(String suffix) { // Append suffix return new ModelUrn(getId() + suffix); } } - diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java index 2ccb8175..c0e724b1 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/SubmodelDescriptor.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.descriptor; @@ -19,9 +34,6 @@ import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics; import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; - - - /** * AAS descriptor class * @@ -29,7 +41,7 @@ * */ public class SubmodelDescriptor extends ModelDescriptor implements IHasSemantics { - + public static final String MODELTYPE = "SubmodelDescriptor"; /** @@ -39,7 +51,11 @@ public SubmodelDescriptor(Map map) { super(map); validate(map); } - + + protected SubmodelDescriptor() { + super(); + } + /** * Create a new aas descriptor with minimal information based on an existing * submodel. @@ -47,16 +63,16 @@ public SubmodelDescriptor(Map map) { public SubmodelDescriptor(ISubmodel sm, String httpEndpoint) { // Create descriptor with minimal information (id and idShort) this(sm.getIdShort(), sm.getIdentification(), httpEndpoint); - + putAll(new HasSemantics(sm.getSemanticId())); } - + /** * Create a new descriptor with minimal information */ public SubmodelDescriptor(String idShort, IIdentifier id, String httpEndpoint) { super(idShort, id, harmonizeEndpoint(httpEndpoint)); - + // Add model type putAll(new ModelType(MODELTYPE)); } @@ -84,4 +100,3 @@ public void setSemanticId(Reference ref) { } } - diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java index 93f4b74d..bce98d6e 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/Asset.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.parts; @@ -61,9 +76,10 @@ public Asset() { // Default values setAssetKind(AssetKind.INSTANCE); } - + /** * Constructor accepting only mandatory attributes + * * @param idShort * @param identification * @param kind @@ -98,24 +114,23 @@ public static Asset createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Asset.class, map); } - + Asset ret = new Asset(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { - return Identifiable.isValid(map) && - map.containsKey(Asset.KIND); + return Identifiable.isValid(map) && map.containsKey(Asset.KIND); } @Override @@ -176,6 +191,7 @@ public IReference getAssetIdentificationModel() { public void setAssetIdentificationModel(IReference submodel) { put(Asset.ASSETIDENTIFICATIONMODEL, submodel); } + @Override public String getIdShort() { return Referable.createAsFacade(this, getKeyElement()).getIdShort(); @@ -221,7 +237,7 @@ public IReference getBillOfMaterial() { public void setBillOfMaterial(Reference reference) { put(Asset.BILLOFMATERIAL, reference); } - + private KeyElements getKeyElement() { return KeyElements.ASSET; } diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java index 67d54a71..69630202 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/ConceptDictionary.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.parts; @@ -45,9 +60,10 @@ public ConceptDictionary() { put(CONCEPTDESCRIPTION, new ArrayList()); put(CONCEPTDESCRIPTIONS, new ArrayList()); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort */ public ConceptDictionary(String idShort) { @@ -73,19 +89,19 @@ public static ConceptDictionary createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(ConceptDictionary.class, map); } - + ConceptDictionary ret = new ConceptDictionary(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { @@ -143,16 +159,17 @@ public void setConceptDescriptionReferences(Collection ref) { } /** - * Sets the concept descriptions for this concept dictionary. The method sets local references to the added - * concept descriptions, too. + * Sets the concept descriptions for this concept dictionary. The method sets + * local references to the added concept descriptions, too. * - * @param descriptions All the concept descriptions the concept dictionary shall have + * @param descriptions + * All the concept descriptions the concept dictionary shall have */ public void setConceptDescriptions(Collection descriptions) { put(CONCEPTDESCRIPTIONS, descriptions); // Also add the references to these concept descriptions Collection refs = new ArrayList<>(); - for ( IConceptDescription desc : descriptions ) { + for (IConceptDescription desc : descriptions) { refs.add(createConceptDescriptionRef(desc)); } setConceptDescriptionReferences(refs); @@ -161,7 +178,8 @@ public void setConceptDescriptions(Collection descriptions) /** * Adds a new concept description together with a local reference to it. * - * @param description The new concept description + * @param description + * The new concept description */ @SuppressWarnings("unchecked") public void addConceptDescription(IConceptDescription description) { @@ -181,7 +199,7 @@ private IReference createConceptDescriptionRef(IConceptDescription description) public Collection getConceptDescriptions() { return ((Collection) get(CONCEPTDESCRIPTIONS)); } - + private KeyElements getKeyElement() { return KeyElements.CONCEPTDICTIONARY; } diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java index 0cd8677a..1f81fb03 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/parts/View.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.parts; @@ -53,9 +68,10 @@ public View() { // Default values put(CONTAINEDELEMENT, new HashSet()); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort */ public View(String idShort) { @@ -84,19 +100,19 @@ public static View createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(View.class, map); } - + View ret = new View(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { @@ -175,7 +191,7 @@ public void setDescription(LangStrings description) { public void setParent(IReference obj) { Referable.createAsFacade(this, getKeyElement()).setParent(obj); } - + private KeyElements getKeyElement() { return KeyElements.VIEW; } diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java index 7e62c525..6e77db8c 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/AccessControlPolicyPoints.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.policypoints; @@ -29,7 +44,8 @@ public class AccessControlPolicyPoints extends VABModelMap implements IA /** * Constructor */ - public AccessControlPolicyPoints() {} + public AccessControlPolicyPoints() { + } /** * Creates a DataSpecificationIEC61360 object from a map diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java index 8495d8b1..6aa54ffd 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyAdministrationPoint.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.policypoints; @@ -13,6 +28,7 @@ * Security class * * DUMMY, TO BE DONE + * * @author elsheikh * */ diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java index 824f6571..e6ca4846 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyDecisionPoint.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.policypoints; @@ -13,6 +28,7 @@ * Security class * * DUMMY, TO BE DONE + * * @author elsheikh * */ diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java index 158c7b97..2037807d 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyEnforcementPoint.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.policypoints; @@ -13,6 +28,7 @@ * Security class * * DUMMY, TO BE DONE + * * @author elsheikh * */ diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java index 908ff56d..3e20e5e4 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/policypoints/PolicyInformationPoints.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.policypoints; @@ -13,6 +28,7 @@ * Security class * * DUMMY, TO BE DONE + * * @author elsheikh * */ diff --git a/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java b/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java index f4baabcf..ab3582ae 100644 --- a/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java +++ b/src/main/java/org/eclipse/basyx/aas/metamodel/map/security/Security.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.metamodel.map.security; @@ -32,7 +47,8 @@ public class Security extends VABModelMap implements ISecurity { /** * Constructor */ - public Security() {} + public Security() { + } /** * Creates a Security object from a map @@ -61,7 +77,6 @@ public void setAccessControlPolicyPoints(IAccessControlPolicyPoints obj) { put(Security.ACCESSCONTROLPOLICYPOINTS, obj); } - @Override public ICertificate getCertificate() { // TODO: Implement diff --git a/src/main/java/org/eclipse/basyx/aas/registration/AASRegistryAPIHelper.java b/src/main/java/org/eclipse/basyx/aas/registration/AASRegistryAPIHelper.java new file mode 100644 index 00000000..ddfad165 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/registration/AASRegistryAPIHelper.java @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.registration; + +import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; + +/** + * API helper for AAS Registry + * + * @author haque + * + */ +public class AASRegistryAPIHelper { + + /** + * Retrieves base access path + * + * @return + */ + public static String getRegistryPath() { + return AASRegistryModelProvider.PREFIX; + } + + /** + * Retrieves an access path for an AAS + * + * @param aasId + * @return + */ + public static String getAASPath(IIdentifier aasId) { + return VABPathTools.concatenatePaths(getRegistryPath(), VABPathTools.encodePathElement(aasId.getId())); + } + + /** + * Retrieves an access path for all the submodels inside an AAS + * + * @param aasId + * @return + */ + public static String getSubmodelListOfAASPath(IIdentifier aasId) { + return VABPathTools.concatenatePaths(getRegistryPath(), buildSubmodelPath(aasId)); + } + + /** + * Retrieves an access path for a submodel + * + * @param aasId + * @param submodelId + * @return + */ + public static String getSubmodelAccessPath(IIdentifier aasId, IIdentifier submodelId) { + return VABPathTools.concatenatePaths(getSubmodelListOfAASPath(aasId), VABPathTools.encodePathElement(submodelId.getId())); + } + + private static String buildSubmodelPath(IIdentifier aas) throws ProviderException { + // Encode id to handle usage of reserved symbols, e.g. / + String encodedAASId = VABPathTools.encodePathElement(aas.getId()); + return VABPathTools.concatenatePaths(encodedAASId, AASRegistryModelProvider.SUBMODELS); + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java b/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java index 2173b061..39f9ec29 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistry.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.api; @@ -16,9 +31,6 @@ import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.vab.exception.provider.ProviderException; - - - /** * BaSys registry interface * @@ -26,9 +38,9 @@ * */ public interface IAASRegistry { - + /** - * Register AAS descriptor in registry, delete old registration + * Register AAS descriptor in registry, delete old registration */ public void register(AASDescriptor deviceAASDescriptor) throws ProviderException; @@ -41,12 +53,12 @@ public interface IAASRegistry { * Delete AAS descriptor from registry */ public void delete(IIdentifier aasId) throws ProviderException; - + /** * Delete SM descriptor from registry */ public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException; - + /** * Lookup AAS */ @@ -82,4 +94,3 @@ public interface IAASRegistry { public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException; } - diff --git a/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java b/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java index 021d654f..94abc3b0 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/memory/AASRegistry.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.memory; @@ -27,7 +42,7 @@ public class AASRegistry implements IAASRegistry { private static Logger logger = LoggerFactory.getLogger(AASRegistry.class); protected IRegistryHandler handler; - + public AASRegistry(IRegistryHandler handler) { this.handler = handler; } @@ -47,8 +62,7 @@ public void register(AASDescriptor aasDescriptor) { public void delete(IIdentifier aasIdentifier) { String aasId = aasIdentifier.getId(); if (!handler.contains(aasIdentifier)) { - throw new ResourceNotFoundException( - "Could not delete key for AAS " + aasId + " since it does not exist"); + throw new ResourceNotFoundException("Could not delete key for AAS " + aasId + " since it does not exist"); } else { handler.remove(aasIdentifier); logger.debug("Removed " + aasId); @@ -59,8 +73,7 @@ public void delete(IIdentifier aasIdentifier) { public AASDescriptor lookupAAS(IIdentifier aasIdentifier) { String aasId = aasIdentifier.getId(); if (!handler.contains(aasIdentifier)) { - throw new ResourceNotFoundException( - "Could not look up descriptor for AAS " + aasId + " since it does not exist"); + throw new ResourceNotFoundException("Could not look up descriptor for AAS " + aasId + " since it does not exist"); } return handler.get(aasIdentifier); } @@ -80,11 +93,10 @@ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) { } AASDescriptor descriptor = handler.get(aas); - if(descriptor == null) { - throw new ResourceNotFoundException( - "Could not add submodel descriptor for AAS " + aas.getId() + " since the AAS does not exist"); + if (descriptor == null) { + throw new ResourceNotFoundException("Could not add submodel descriptor for AAS " + aas.getId() + " since the AAS does not exist"); } - + descriptor.addSubmodelDescriptor(smDescriptor); handler.update(descriptor); logger.debug("Registered submodel " + smDescriptor.getIdShort() + " for AAS " + aas.getId()); @@ -95,12 +107,10 @@ public void delete(IIdentifier aasId, IIdentifier smId) { String smIdString = smId.getId(); AASDescriptor desc = handler.get(aasId); if (desc == null) { - throw new ResourceNotFoundException( - "Could not delete submodel descriptor for AAS " + aasId.getId() + " since the AAS does not exist"); + throw new ResourceNotFoundException("Could not delete submodel descriptor for AAS " + aasId.getId() + " since the AAS does not exist"); } if (desc.getSubmodelDescriptorFromIdentifierId(smIdString) == null) { - throw new ResourceNotFoundException( - "Could not delete submodel descriptor for AAS " + aasId.getId() + " since the SM does not exist"); + throw new ResourceNotFoundException("Could not delete submodel descriptor for AAS " + aasId.getId() + " since the SM does not exist"); } desc.removeSubmodelDescriptor(smId); diff --git a/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java b/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java index d0c723fb..9cb4d100 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/memory/IRegistryHandler.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.memory; @@ -15,16 +30,19 @@ import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; /** - * An interface for a registry handler for different types of registry datasources. + * An interface for a registry handler for different types of registry + * datasources. * * @author espen * */ public interface IRegistryHandler { /** - * Queries the registry datasource to check, if an entry with the given identifier exists. + * Queries the registry datasource to check, if an entry with the given + * identifier exists. * - * @param id The asset- or AAS-identifier that will be checked + * @param id + * The asset- or AAS-identifier that will be checked * @return True, if an entry with the given identifier exists */ public boolean contains(IIdentifier id); @@ -32,29 +50,34 @@ public interface IRegistryHandler { /** * Removes an entry with a given identifier from the registry datasource * - * @param id The asset- or AAS-identifier that will be removed + * @param id + * The asset- or AAS-identifier that will be removed */ public void remove(IIdentifier id); /** * Inserts a new descriptor into the registry datasource. * - * @param descriptor The descriptor that will be inserted. + * @param descriptor + * The descriptor that will be inserted. */ public void insert(AASDescriptor descriptor); /** - * Updates a given descriptor. It is assumed that an entry with the same AAS id already exists in the registry - * datasource. + * Updates a given descriptor. It is assumed that an entry with the same AAS id + * already exists in the registry datasource. * - * @param descriptor The descriptor that will be inserted. + * @param descriptor + * The descriptor that will be inserted. */ public void update(AASDescriptor descriptor); /** * Queries the registry datasource for a entry with the given identifier. * - * @param id The asset- or AAS-identifier for which the descriptor should be retrieved. + * @param id + * The asset- or AAS-identifier for which the descriptor should be + * retrieved. * @return The found descriptor from the registry datasource matching the id. */ public AASDescriptor get(IIdentifier id); diff --git a/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java b/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java index a1d5625a..41439a29 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java @@ -1,19 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.memory; -import java.util.HashMap; +import java.util.LinkedHashMap; /** - * An implementation of the IAASRegistryService interface. - * This registry can not store its entries permanently, because it is completely based on HashMaps. + * An implementation of the IAASRegistryService interface. This registry can not + * store its entries permanently, because it is completely based on HashMaps. * * @author espen * @@ -24,6 +39,6 @@ public class InMemoryRegistry extends AASRegistry { * Default constructor based on HashMaps */ public InMemoryRegistry() { - super(new MapRegistryHandler(new HashMap<>())); + super(new MapRegistryHandler(new LinkedHashMap<>())); } } diff --git a/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java b/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java index cccb80b5..436cd123 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistryHandler.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.memory; diff --git a/src/main/java/org/eclipse/basyx/aas/registration/observing/IAASRegistryServiceObserver.java b/src/main/java/org/eclipse/basyx/aas/registration/observing/IAASRegistryServiceObserver.java new file mode 100644 index 00000000..e8787da1 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/registration/observing/IAASRegistryServiceObserver.java @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.registration.observing; + +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.observer.IObserver; + +/** + * Interface for an observer of {@link ObservableAASRegistryService} + * + * @author haque + * + */ +public interface IAASRegistryServiceObserver extends IObserver { + + /** + * Is called when an AAS is registered + * + * @param aasId + * id of the registered AAS + */ + public void aasRegistered(String aasId); + + /** + * Is called when a submodel is registered + * + * @param aasId + * id of the parent AAS + * @param smId + * id of the registered submodel + */ + public void submodelRegistered(IIdentifier aasId, IIdentifier smId); + + /** + * Is called when an AAS is deleted + * + * @param aasId + * id of the deleted AAS + */ + public void aasDeleted(String aasId); + + /** + * Is called when a submodel is deleted + * + * @param aasId + * id of the parent AAS + * @param smId + * id of the deleted Submodel + */ + public void submodelDeleted(IIdentifier aasId, IIdentifier smId); + +} diff --git a/src/main/java/org/eclipse/basyx/aas/registration/observing/ObservableAASRegistryService.java b/src/main/java/org/eclipse/basyx/aas/registration/observing/ObservableAASRegistryService.java new file mode 100644 index 00000000..8ecd3bfd --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/registration/observing/ObservableAASRegistryService.java @@ -0,0 +1,97 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.registration.observing; + +import java.util.List; + +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.observer.Observable; +import org.eclipse.basyx.vab.exception.provider.ProviderException; + +/** + * + * Implementation of {@link IAASRegistry} that calls back registered + * {@link IAASRegistryServiceObserver} when changes on Registry occur + * + * @author haque + * + */ +public class ObservableAASRegistryService extends Observable implements IAASRegistry { + + private IAASRegistry aasRegistry; + + public ObservableAASRegistryService(IAASRegistry registry) { + this.aasRegistry = registry; + } + + @Override + public void register(AASDescriptor deviceAASDescriptor) throws ProviderException { + aasRegistry.register(deviceAASDescriptor); + observers.stream().forEach(o -> o.aasRegistered(deviceAASDescriptor.getIdentifier().getId())); + } + + @Override + public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException { + aasRegistry.register(aas, smDescriptor); + observers.stream().forEach(o -> o.submodelRegistered(aas, smDescriptor.getIdentifier())); + } + + @Override + public void delete(IIdentifier aasId) throws ProviderException { + aasRegistry.delete(aasId); + observers.stream().forEach(o -> o.aasDeleted(aasId.getId())); + } + + @Override + public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException { + observers.stream().forEach(o -> o.submodelDeleted(aasId, smId)); + } + + @Override + public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException { + return aasRegistry.lookupAAS(aasId); + } + + @Override + public List lookupAll() throws ProviderException { + return aasRegistry.lookupAll(); + } + + @Override + public List lookupSubmodels(IIdentifier aasId) throws ProviderException { + return aasRegistry.lookupSubmodels(aasId); + } + + @Override + public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException { + return aasRegistry.lookupSubmodel(aasId, smId); + } + +} diff --git a/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java b/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java index c5c5380b..6a87f2e0 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java @@ -1,16 +1,29 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.proxy; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.Collection; import java.util.List; import java.util.Map; @@ -18,48 +31,50 @@ import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.registration.AASRegistryAPIHelper; import org.eclipse.basyx.aas.registration.api.IAASRegistry; import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.vab.coder.json.connector.JSONConnector; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; -import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector; +import org.eclipse.basyx.vab.protocol.https.HTTPSConnector; import org.eclipse.basyx.vab.registry.proxy.VABRegistryProxy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - /** * Local proxy class that hides HTTP calls to BaSys registry - * + * * @author kuhn, schnicke * */ public class AASRegistryProxy extends VABRegistryProxy implements IAASRegistry { - - private static Logger logger = LoggerFactory.getLogger(AASRegistryProxy.class); /** * Constructor for an AAS registry proxy based on a HTTP connection - * + * * @param registryUrl * The endpoint of the registry with a HTTP-REST interface */ public AASRegistryProxy(String registryUrl) { - this(new JSONConnector(new HTTPConnector(harmonizeURL(registryUrl)))); + this(getJSONConnectorWithProtocol(registryUrl)); + } + + private static JSONConnector getJSONConnectorWithProtocol(String registryUrl) { + if (isHTTPSUrl(registryUrl)) { + return new JSONConnector(new HTTPSConnector(harmonizeURL(registryUrl))); + } + return new JSONConnector(new HTTPConnector(harmonizeURL(registryUrl))); } /** * Removes prefix if it exists since it will be readded at a later stage - * + * * @param url * @return */ - private static String harmonizeURL(String url) { + protected static String harmonizeURL(String url) { if (url.endsWith(AASRegistryModelProvider.PREFIX)) { url = url.substring(0, url.length() - AASRegistryModelProvider.PREFIX.length()); } @@ -68,7 +83,7 @@ private static String harmonizeURL(String url) { /** * Constructor for an AAS registry proxy based on its model provider - * + * * @param provider * A model provider for the actual registry */ @@ -77,7 +92,7 @@ public AASRegistryProxy(IModelProvider provider) throws ProviderException { } private static VABElementProxy createProxy(IModelProvider provider) { - return new VABElementProxy(AASRegistryModelProvider.PREFIX, provider); + return new VABElementProxy("", provider); } /** @@ -87,7 +102,7 @@ private static VABElementProxy createProxy(IModelProvider provider) { public void register(AASDescriptor deviceAASDescriptor) throws ProviderException { // Add a mapping from the AAS id to the serialized descriptor try { - String encodedId = VABPathTools.encodePathElement(deviceAASDescriptor.getIdentifier().getId()); + String encodedId = AASRegistryAPIHelper.getAASPath(deviceAASDescriptor.getIdentifier()); // Typically, VAB SET should not create new entries. Nevertheless, the registry // API is defined to do it. @@ -106,21 +121,17 @@ public void register(AASDescriptor deviceAASDescriptor) throws ProviderException */ @Override public void delete(IIdentifier aasIdentifier) throws ProviderException { - try { - this.removeMapping(URLEncoder.encode(aasIdentifier.getId(), "UTF-8")); - } catch (UnsupportedEncodingException e) { - logger.error("Could not encode URL. This should not happen"); - throw new RuntimeException(e); - } + this.removeMapping(AASRegistryAPIHelper.getAASPath(aasIdentifier)); } - + /** * Lookup device AAS */ - @Override @SuppressWarnings("unchecked") + @Override + @SuppressWarnings("unchecked") public AASDescriptor lookupAAS(IIdentifier aasIdentifier) throws ProviderException { try { - Object result = provider.getValue(URLEncoder.encode(aasIdentifier.getId(), "UTF-8")); + Object result = provider.getValue(AASRegistryAPIHelper.getAASPath(aasIdentifier)); return new AASDescriptor((Map) result); } catch (Exception e) { if (e instanceof ProviderException) { @@ -135,7 +146,7 @@ public AASDescriptor lookupAAS(IIdentifier aasIdentifier) throws ProviderExcepti @Override public List lookupAll() throws ProviderException { try { - Object result = provider.getValue(""); + Object result = provider.getValue(AASRegistryAPIHelper.getRegistryPath()); Collection descriptors = (Collection) result; return descriptors.stream().map(x -> new AASDescriptor((Map) x)).collect(Collectors.toList()); } catch (Exception e) { @@ -152,7 +163,7 @@ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws Pr try { // Typically, VAB SET should not create new entries. Nevertheless, the registry // API is defined to do it. - provider.setValue(VABPathTools.concatenatePaths(buildSubmodelPath(aas), URLEncoder.encode(smDescriptor.getIdentifier().getId(), "UTF-8")), smDescriptor); + provider.setValue(AASRegistryAPIHelper.getSubmodelAccessPath(aas, smDescriptor.getIdentifier()), smDescriptor); } catch (Exception e) { if (e instanceof ProviderException) { throw (ProviderException) e; @@ -165,7 +176,7 @@ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws Pr @Override public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException { try { - provider.deleteValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smId.getId(), "UTF-8"))); + provider.deleteValue(AASRegistryAPIHelper.getSubmodelAccessPath(aasId, smId)); } catch (Exception e) { if (e instanceof ProviderException) { throw (ProviderException) e; @@ -175,17 +186,11 @@ public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException } } - private String buildSubmodelPath(IIdentifier aas) throws ProviderException { - // Encode id to handle usage of reserved symbols, e.g. / - String encodedAASId = VABPathTools.encodePathElement(aas.getId()); - return VABPathTools.concatenatePaths(encodedAASId, AASRegistryModelProvider.SUBMODELS); - } - @SuppressWarnings("unchecked") @Override public List lookupSubmodels(IIdentifier aasId) throws ProviderException { try { - Object result = provider.getValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId))); + Object result = provider.getValue(AASRegistryAPIHelper.getSubmodelListOfAASPath(aasId)); Collection descriptors = (Collection) result; return descriptors.stream().map(x -> new SubmodelDescriptor((Map) x)).collect(Collectors.toList()); } catch (Exception e) { @@ -201,7 +206,7 @@ public List lookupSubmodels(IIdentifier aasId) throws Provid @Override public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException { try { - Object result = provider.getValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), URLEncoder.encode(smId.getId(), "UTF-8"))); + Object result = provider.getValue(AASRegistryAPIHelper.getSubmodelAccessPath(aasId, smId)); return new SubmodelDescriptor((Map) result); } catch (Exception e) { if (e instanceof ProviderException) { @@ -212,4 +217,3 @@ public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) th } } } - diff --git a/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java b/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java index 285944bb..11f0b844 100644 --- a/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java +++ b/src/main/java/org/eclipse/basyx/aas/registration/restapi/AASRegistryModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.registration.restapi; @@ -54,7 +69,8 @@ public AASRegistryModelProvider() { * * @param path * @return - * @throws MalformedRequestException if path does not start with PERFIX "api/v1/registry" + * @throws MalformedRequestException + * if path does not start with PREFIX "api/v1/registry" */ private String stripPrefix(String path) throws MalformedRequestException { path = VABPathTools.stripSlashes(path); @@ -65,35 +81,38 @@ private String stripPrefix(String path) throws MalformedRequestException { path = VABPathTools.stripSlashes(path); return path; } - + /** - * Splits a path and checks, that first element is not "submodels" and that the second one, if exists, is "submodels" + * Splits a path and checks, that first element is not "submodels" and that the + * second one, if exists, is "submodels" * - * @param path the path to be splitted + * @param path + * the path to be splitted * @return Array of path elements - * @throws MalformedRequestException if path is not valid + * @throws MalformedRequestException + * if path is not valid */ private String[] splitPath(String path) throws MalformedRequestException { - - if(path.isEmpty()) { + + if (path.isEmpty()) { return new String[0]; } - + String[] splitted = path.split("/"); - - //Assumes "submodels" is not a valid AASId - if(splitted[0].equals(SUBMODELS)) { + + // Assumes "submodels" is not a valid AASId + if (splitted[0].equals(SUBMODELS)) { throw new MalformedRequestException("Path must not start with " + SUBMODELS); } - - //If path contains more than one element, the second one has to be "submodels" - if(splitted.length > 1 && !splitted[1].equals(SUBMODELS)) { + + // If path contains more than one element, the second one has to be "submodels" + if (splitted.length > 1 && !splitted[1].equals(SUBMODELS)) { throw new MalformedRequestException("Second path element must be (if present): " + SUBMODELS); } - + return splitted; } - + private String[] preparePath(String path) throws MalformedRequestException { path = stripPrefix(path); @@ -105,61 +124,67 @@ private String[] preparePath(String path) throws MalformedRequestException { } return splitted; } catch (UnsupportedEncodingException e) { - //Malformed request because of unsupported encoding + // Malformed request because of unsupported encoding throw new MalformedRequestException("Path has to be encoded as UTF-8 string."); } } - + /** * Checks if a given Object is a Map and checks if it has the correct modelType * - * @param expectedModelType the modelType the Object is expected to have - * @param value the Object to be checked and casted + * @param expectedModelType + * the modelType the Object is expected to have + * @param value + * the Object to be checked and casted * @return the object casted to a Map - * @throws MalformedRequestException + * @throws MalformedRequestException */ @SuppressWarnings("unchecked") private Map checkModelType(String expectedModelType, Object value) throws MalformedRequestException { - //check if the given value is a Map - if(!(value instanceof Map)) { + // check if the given value is a Map + if (!(value instanceof Map)) { throw new MalformedRequestException("Given newValue is not a Map"); } Map map = (Map) value; - - //check if the given Map contains an AAS + + // check if the given Map contains an AAS String type = ModelType.createAsFacade(map).getName(); - - //have to accept Objects without modeltype information, - //as modeltype is not part of the public metamodel - if(!expectedModelType.equals(type) && type != null) { + + // have to accept Objects without modeltype information, + // as modeltype is not part of the public metamodel + if (!expectedModelType.equals(type) && type != null) { throw new MalformedRequestException("Given newValue map has not the correct ModelType"); } - + return map; } - + /** - * Makes sure, that given Object is an AASDescriptor by checking its ModelType
+ * Makes sure, that given Object is an AASDescriptor by checking its + * ModelType
* Creates a new AASDescriptor with the content of the given Map * - * @param value the AAS Map object + * @param value + * the AAS Map object * @return an AAS - * @throws MalformedRequestException + * @throws MalformedRequestException */ private AASDescriptor createAASDescriptorFromMap(Object value) throws MalformedRequestException { Map map = checkModelType(AASDescriptor.MODELTYPE, value); AASDescriptor aasDescriptor = new AASDescriptor(map); return aasDescriptor; } - + /** - * Makes sure, that given Object is an SubmodelDescriptor by checking its ModelType
+ * Makes sure, that given Object is an SubmodelDescriptor by checking its + * ModelType
* Creates a new SubmodelDescriptor with the content of the given Map * - * @param value the AAS Map object + * @param value + * the AAS Map object * @return an AAS - * @throws MalformedRequestException + * @throws MalformedRequestException */ private SubmodelDescriptor createSMDescriptorFromMap(Object value) throws MalformedRequestException { Map map = checkModelType(SubmodelDescriptor.MODELTYPE, value); @@ -171,73 +196,98 @@ private SubmodelDescriptor createSMDescriptorFromMap(Object value) throws Malfor public Object getValue(String path) throws ProviderException { String[] splitted = preparePath(path); - //Path is empty, request for all AASDescriptors - if (splitted.length == 0) { + if (isRequestForAllAASDescriptors(splitted)) { return registry.lookupAll(); - } else { - - //Given path consists only of an AAS Id - if(splitted.length == 1) { - AASDescriptor descriptor = registry.lookupAAS(new ModelUrn(splitted[0])); - - //Throw an Exception if the requested AAS does not exist - if(descriptor == null) { - throw new ResourceNotFoundException("Specified AASid '" + splitted[0] + "' does not exist."); - } - return descriptor; - - //Given path consists of an AAS Id and "/submodels" - //Request for all SubmodelDescriptors of given AAS - } else if(splitted.length == 2) { - return getSmDescriptorsFromAAS(new ModelUrn(splitted[0])); - - //Given path consists of an AAS Id and "/submodels/" and a SubmodelId - //Request for the SubmodelDescriptor of given AAS with given id - } else if(splitted.length == 3) { - SubmodelDescriptor smDescriptor = getSmDescriptorFromAAS(new ModelUrn(splitted[0]), splitted[2]); - if(smDescriptor == null) { - throw new ResourceNotFoundException("Specified SubmodelId '" + splitted[2] + "' does not exist in AAS '" + splitted[0] + "'."); - } - return smDescriptor; - } - - //path has more than three elements and is therefore invalid - throw new MalformedRequestException("Given path '" + path + "' contains more than three path elements and is therefore invalid."); + } else if (isRequestForAASDescriptor(splitted)) { + return getAASDescriptor(splitted); + } else if (isRequestForSubmodelDescriptorsOfAAS(splitted)) { + return getSmDescriptorsFromAAS(createAASModelUrn(splitted)); + } else if (isRequestForSubmodelDescriptorOfAAS(splitted)) { + return getSubmodelDescriptor(splitted); } + + throw new MalformedRequestException(createInvalidPathMessage(path)); + } + + private String createInvalidPathMessage(String path) { + return "Given path '" + path + "' contains more than three path elements and is therefore invalid."; + } + + private Object getSubmodelDescriptor(String[] splitted) { + SubmodelDescriptor smDescriptor = getSmDescriptorFromAAS(createAASModelUrn(splitted), splitted[2]); + + if (smDescriptor == null) { + throw new ResourceNotFoundException("Specified SubmodelId '" + splitted[2] + "' does not exist in AAS '" + splitted[0] + "'."); + } + + return smDescriptor; + } + + private boolean isRequestForSubmodelDescriptorOfAAS(String[] splitted) { + return splitted.length == 3; + } + + private boolean isRequestForSubmodelDescriptorsOfAAS(String[] splitted) { + return splitted.length == 2; + } + + private boolean isRequestForAASDescriptor(String[] splitted) { + return splitted.length == 1; + } + + private boolean isRequestForAllAASDescriptors(String[] splitted) { + return splitted.length == 0; + } + + private Object getAASDescriptor(String[] splitted) { + AASDescriptor descriptor = registry.lookupAAS(createAASModelUrn(splitted)); + + if (descriptor == null) { + throw new ResourceNotFoundException("Specified AASid '" + splitted[0] + "' does not exist."); + } + + return descriptor; } @Override public void setValue(String path, Object newValue) throws ProviderException { String[] splitted = preparePath(path); - if (splitted.length > 0) { // Overwriting existing entry - //if path contains more or less than an aasID after the prefix - - // Decode encoded path - ModelUrn identifier = new ModelUrn(splitted[0]); - - if (splitted.length == 1) { - // Typically, VAB SET should not create new entries. Nevertheless, the registry - // API is defined to do it. - AASDescriptor desc = createAASDescriptorFromMap(newValue); - - // Ensure the passed identifier is equals the - String descId = desc.getIdentifier().getId(); - String urlId = splitted[0]; - if (descId.equals(urlId)) { - registry.register(desc); - } else { - throw new MalformedRequestException("The Identifier " + descId + " in the descriptor does not match the URL with id " + urlId); - } - } else if (splitted.length == 3) { - SubmodelDescriptor smDesc = createSMDescriptorFromMap(newValue); - registry.register(identifier, smDesc); - } else { - throw new MalformedRequestException("Unknown path " + path); - } - } else { + if (!isValidSetPath(splitted)) { throw new MalformedRequestException("Set with empty path is not supported by registry"); } + + ModelUrn identifier = createAASModelUrn(splitted); + + if (isRequestForAASDescriptor(splitted)) { + registerAASDescriptor(newValue, splitted); + } else if (isRequestForSubmodelDescriptorOfAAS(splitted)) { + registerSubmodelDescriptor(newValue, identifier); + } else { + throw new MalformedRequestException("Unknown path " + path); + } + } + + private void registerSubmodelDescriptor(Object newValue, ModelUrn identifier) { + SubmodelDescriptor smDesc = createSMDescriptorFromMap(newValue); + registry.register(identifier, smDesc); + } + + private void registerAASDescriptor(Object newValue, String[] splitted) { + AASDescriptor desc = createAASDescriptorFromMap(newValue); + + String descId = desc.getIdentifier().getId(); + String urlId = splitted[0]; + + if (descId.equals(urlId)) { + registry.register(desc); + } else { + throw new MalformedRequestException("The Identifier " + descId + " in the descriptor does not match the URL with id " + urlId); + } + } + + private boolean isValidSetPath(String[] splitted) { + return splitted.length > 0; } @Override @@ -248,32 +298,47 @@ public void createValue(String path, Object newEntity) throws ProviderException @Override public void deleteValue(String path) throws ProviderException { String[] splitted = preparePath(path); - - if (splitted.length == 1) { //delete an aas - - ModelUrn aasId = new ModelUrn(splitted[0]); - - //aas to be deleted does not exist - if(registry.lookupAAS(aasId) == null) { - throw new ResourceNotFoundException("AAS '" + splitted[0] + "' to be deleted does not exist."); - } - - registry.delete(aasId); - - } else if(splitted.length == 3) { //delete a submodel - ModelUrn aasId = new ModelUrn(splitted[0]); - String smId = splitted[2]; - // a submodel with this Id does not exist in given aas - // getSmDescriptorFromAAS also checks if aas exists - SubmodelDescriptor smDesc = getSmDescriptorFromAAS(aasId, smId); - if (smDesc == null) { - throw new ResourceNotFoundException("A Submodel with id '" + smId + "' does not exist in aas '" + splitted[0] + "'."); - } - registry.delete(aasId, smDesc.getIdentifier()); - } else { + if (!isValidDeletePath(splitted)) { throw new MalformedRequestException("Delete with empty path is not supported by registry"); } + + if (isRequestForAASDescriptor(splitted)) { + deleteAASDescriptor(splitted); + } else if (isRequestForSubmodelDescriptorOfAAS(splitted)) { + deleteSubmodelDescriptor(splitted); + } + + } + + private boolean isValidDeletePath(String[] splitted) { + return splitted.length > 0; + } + + private void deleteSubmodelDescriptor(String[] splitted) { + ModelUrn aasId = createAASModelUrn(splitted); + String smId = splitted[2]; + + SubmodelDescriptor smDesc = getSmDescriptorFromAAS(aasId, smId); + if (smDesc == null) { + throw new ResourceNotFoundException("A Submodel with id '" + smId + "' does not exist in aas '" + aasId + "'."); + } + + registry.delete(aasId, smDesc.getIdentifier()); + } + + private ModelUrn createAASModelUrn(String[] splitted) { + return new ModelUrn(splitted[0]); + } + + private void deleteAASDescriptor(String[] splitted) { + ModelUrn aasId = createAASModelUrn(splitted); + + if (registry.lookupAAS(aasId) == null) { + throw new ResourceNotFoundException("AAS '" + aasId + "' to be deleted does not exist."); + } + + registry.delete(aasId); } @Override @@ -285,43 +350,52 @@ public void deleteValue(String path, Object obj) throws ProviderException { public Object invokeOperation(String path, Object... parameter) throws ProviderException { throw new MalformedRequestException("Invoke not supported by registry"); } - + /** - * Gets all SubmodelDescriptor objects form an aas. - * Throws RuntimeException if aas does not exist. + * Gets all SubmodelDescriptor objects form an aas. Throws RuntimeException if + * aas does not exist. * - * @param id id of the aas + * @param id + * id of the aas * @return Set of contained SubmodelDescriptor objects - * @throws ResourceNotFoundException if the AAS does not exist + * @throws ResourceNotFoundException + * if the AAS does not exist */ private Collection getSmDescriptorsFromAAS(IIdentifier id) throws ResourceNotFoundException { AASDescriptor aasDescriptor = registry.lookupAAS(id); - if(aasDescriptor == null) { + + if (aasDescriptor == null) { throw new ResourceNotFoundException("Specified AASid '" + id.getId() + "' does not exist."); } + return aasDescriptor.getSubmodelDescriptors(); } - + /** - * Gets a specific SubmodelDescriptor form an aas. - * Throws RuntimeException if aas does not exist. + * Gets a specific SubmodelDescriptor form an aas. Throws RuntimeException if + * aas does not exist. * - * @param aasId id of the aas - * @param smId id of the submodel + * @param aasId + * id of the aas + * @param smId + * id of the submodel * @return the SubmodelDescriptor with the given id - * @throws ResourceNotFoundException if aasId does not exist + * @throws ResourceNotFoundException + * if aasId does not exist */ - private SubmodelDescriptor getSmDescriptorFromAAS(IIdentifier aasId, String smId) - throws ResourceNotFoundException { + private SubmodelDescriptor getSmDescriptorFromAAS(IIdentifier aasId, String smId) throws ResourceNotFoundException { AASDescriptor aasDescriptor = registry.lookupAAS(aasId); - if(aasDescriptor == null) { + + if (aasDescriptor == null) { throw new ResourceNotFoundException("Specified AASId '" + aasId.getId() + "' does not exist."); } - + SubmodelDescriptor smDescriptor = aasDescriptor.getSubmodelDescriptorFromIdentifierId(smId); + if (smDescriptor == null) { throw new ResourceNotFoundException("Specified SMId '" + smId + "' for AAS " + aasId.getId() + " does not exist."); } + return smDescriptor; } diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java b/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java new file mode 100644 index 00000000..0e19b076 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIFactory.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.restapi; + +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; +import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory; + +/** + * AAS API provider that provides the default AAS API + * + * @author fried + */ +public class AASAPIFactory implements IAASAPIFactory { + IAASAPIFactory aasAPIFactory; + + public AASAPIFactory() { + aasAPIFactory = new VABAASAPIFactory(); + } + + public AASAPIFactory(IAASAPIFactory factoryToBeDecorated) { + aasAPIFactory = factoryToBeDecorated; + } + + @Override + public IAASAPI getAASApi(AssetAdministrationShell aas) { + return aasAPIFactory.create(aas); + } + +} diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIHelper.java b/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIHelper.java new file mode 100644 index 00000000..08dade6b --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/restapi/AASAPIHelper.java @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.aas.restapi; + +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; + +/** + * API helper for AAS API + * + * @author haque + * + */ +public class AASAPIHelper { + + /** + * Retrieves base access path for AAS API + * + * @return + */ + public static String getAASPath() { + return ""; + } + + /** + * Retrieves access path for submodels inside AAS API + * + * @return + */ + public static String getSubmodelsPath() { + return AssetAdministrationShell.SUBMODELS; + } +} diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java b/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java index 47b07bc0..e6c83ee5 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/AASModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.restapi; @@ -24,7 +39,8 @@ /** * Model provider explicitely meant to implement the access to the AAS object. - * This excludes access to the submodels, that are wrapped into their own provider. + * This excludes access to the submodels, that are wrapped into their own + * provider. * * @author espen * @@ -34,8 +50,8 @@ public class AASModelProvider implements IModelProvider { private IAASAPI aasApi; /** - * Constructor based on the model provider containing the AAS model. This is based - * on the default AAS API + * Constructor based on the model provider containing the AAS model. This is + * based on the default AAS API */ public AASModelProvider(IModelProvider modelProvider) { aasApi = new VABAASAPI(modelProvider); @@ -102,7 +118,7 @@ public void deleteValue(String path) throws ProviderException { path = preparePath(path); String[] splitted = VABPathTools.splitPath(path); if (splitted.length == 3 && splitted[1].equals(AssetAdministrationShell.SUBMODELS)) { - String id = splitted[2]; + String id = VABPathTools.decodePathElement(splitted[2]); aasApi.removeSubmodel(id); } else { throw new MalformedRequestException("Delete on path " + path + " is not supported"); @@ -115,7 +131,8 @@ public void deleteValue(String path, Object obj) throws ProviderException { } /** - * Operations that can be invoked are not contained inside of AAS, but inside of submodels + * Operations that can be invoked are not contained inside of AAS, but inside of + * submodels */ @Override public Object invokeOperation(String path, Object... parameter) throws ProviderException { diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java b/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java index 187ebe83..cd5b2007 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/MultiSubmodelProvider.java @@ -1,17 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.restapi; import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -23,12 +36,15 @@ import org.eclipse.basyx.aas.restapi.api.IAASAPI; import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; import org.eclipse.basyx.aas.restapi.vab.VABAASAPIFactory; +import org.eclipse.basyx.submodel.aggregator.SubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.restapi.SubmodelProvider; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; -import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; @@ -43,53 +59,39 @@ * path
*
* Supported API:
- * - getModelPropertyValue
- * /aas Returns the Asset Administration Shell
- * /aas/submodels Retrieves all Submodels from the current Asset Administration - * Shell
- * /aas/submodels/{subModelId} Retrieves a specific Submodel from a specific - * Asset Administration Shell
- * /aas/submodels/{subModelId}/properties Retrieves all Properties from the - * current Submodel
- * /aas/submodels/{subModelId}/operations Retrieves all Operations from the - * current Submodel
- * /aas/submodels/{subModelId}/events Retrieves all Events from the current - * Submodel
- * /aas/submodels/{subModelId}/properties/{propertyId} Retrieves a specific - * property from the AAS's Submodel
- * /aas/submodels/{subModelId}/operations/{operationId} Retrieves a specific - * Operation from the AAS's Submodel
- * /aas/submodels/{subModelId}/events/{eventId} Retrieves a specific event from - * the AAS's submodel - *

- * - createValue
- * /aas/submodels Adds a new Submodel to an existing Asset Administration Shell - *

- * /aas/submodels/{subModelId}/properties Adds a new property to the AAS's - * submodel
- * /aas/submodels/{subModelId}/operations Adds a new operation to the AAS's - * submodel
- * /aas/submodels/{subModelId}/events Adds a new event to the AAS's submodel - *

+ * - getValue
+ * /aas Returns the Asset Administration Shell
+ * /aas/submodels Retrieves all Submodels from the current Asset + * Administration Shell
+ * /aas/submodels/{subModelIdShort}/submodel Retrieves a specific + * Submodel from a specific Asset Administration Shell
+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements Retrieves + * all SubmodelElements from the current Submodel
+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements/{submodelElementIdShort} + * Retrieves a specific SubmodelElement from the AAS's Submodel
+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements/{submodelElementIdShort}/value + * Retrieves the value of a specific SubmodelElement from the AAS's Submodel
+ *
+ * - setValue
+ * /aas/submodels/{subModelIdShort} Adds a new Submodel to an existing + * Asset Administration Shell
+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements/{submodelElementIdShort} + * Adds a new SubmodelElement to the AAS's submodel
+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements/{submodelElementIdShort} + * Sets the value of a specific SubmodelElement from the AAS's Submodel
+ *
* - invokeOperation
- * /aas/submodels/{subModelId}/operations/{operationId} Invokes a specific - * operation from the AAS' submodel with a list of input parameters - *

+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements/{submodelElementIdShort} + * Invokes a specific operation from the AAS' submodel with a list of input + * parameters
+ *
* - deleteValue
- * /aas/submodels/{subModelId} Deletes a specific Submodel from a specific Asset - * Administration Shell
- * /aas/submodels/{subModelId}/properties/{propertyId} Deletes a specific - * Property from the AAS's Submodel
- * /aas/submodels/{subModelId}/operations/{operationId} Deletes a specific - * Operation from the AAS's Submodel
- * /aas/submodels/{subModelId}/events/{eventId} Deletes a specific event from - * the AAS's submodel - *

- * - setModelPropertyValue
- * /aas/submodels/{subModelId}/properties/{propertyId} Sets the value of the - * AAS's Submodel's Property - * - * + * /aas/submodels/{subModelId} Deletes a specific Submodel from a + * specific Asset Administration Shell
+ * /aas/submodels/{subModelIdShort}/submodel/submodelElements/{submodelElementIdShort} + * Deletes a specific submodelElement from the AAS's Submodel
+ * + * * @author kuhn, pschorn * */ @@ -102,22 +104,17 @@ public class MultiSubmodelProvider implements IModelProvider { * Store aas providers */ protected AASModelProvider aas_provider = null; - + /** * Store aasId */ protected IIdentifier aasId = null; - /** - * Store submodel providers - */ - protected Map submodel_providers = new HashMap<>(); - - /** + /* * Store AAS Registry */ protected IAASRegistry registry = null; - + /** * Store HTTP Connector */ @@ -128,28 +125,24 @@ public class MultiSubmodelProvider implements IModelProvider { */ protected IAASAPIFactory aasApiProvider; - /** - * Store Submodel API Provider. By default, uses the VAB Submodel Provider - */ - protected ISubmodelAPIFactory smApiProvider; + private ISubmodelAggregator smAggregator; /** * Constructor with empty default aas and default VAB APIs */ public MultiSubmodelProvider() { - this.aasApiProvider = new VABAASAPIFactory(); - this.smApiProvider = new VABSubmodelAPIFactory(); - IAASAPI aasApi = aasApiProvider.getAASApi(new AssetAdministrationShell()); + this.setAasApiProvider(new VABAASAPIFactory()); + this.setSmAggregator(new SubmodelAggregator()); + IAASAPI aasApi = getAasApiProvider().create(new AssetAdministrationShell()); setAssetAdministrationShell(new AASModelProvider(aasApi)); } /** * Constructor for using custom APIs */ - public MultiSubmodelProvider(AASModelProvider contentProvider, IAASAPIFactory aasApiProvider, - ISubmodelAPIFactory smApiProvider) { - this.aasApiProvider = aasApiProvider; - this.smApiProvider = smApiProvider; + public MultiSubmodelProvider(AASModelProvider contentProvider, IAASAPIFactory aasApiProvider, ISubmodelAPIFactory smApiProvider) { + this.setAasApiProvider(aasApiProvider); + this.setSmAggregator(new SubmodelAggregator(smApiProvider)); setAssetAdministrationShell(contentProvider); } @@ -157,8 +150,8 @@ public MultiSubmodelProvider(AASModelProvider contentProvider, IAASAPIFactory aa * Constructor that accepts an AAS */ public MultiSubmodelProvider(AASModelProvider contentProvider) { - this.aasApiProvider = new VABAASAPIFactory(); - this.smApiProvider = new VABSubmodelAPIFactory(); + this.setAasApiProvider(new VABAASAPIFactory()); + this.setSmAggregator(new SubmodelAggregator()); // Store content provider setAssetAdministrationShell(contentProvider); } @@ -171,31 +164,44 @@ public MultiSubmodelProvider(SubmodelProvider contentProvider) { // Store content provider addSubmodel(contentProvider); } - + /** * Constructor that accepts a registry and a connection provider + * * @param registry * @param provider */ public MultiSubmodelProvider(IAASRegistry registry, IConnectorFactory provider) { this(); this.registry = registry; - this.connectorFactory = provider; + this.setConnectorFactory(provider); } - + /** - * Constructor that accepts a registry, a connection provider and API providers + * Constructor that accepts a registry, a connection provider, and API providers */ - public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry, - IConnectorFactory connectorFactory, ISubmodelAPIFactory smApiProvider, IAASAPIFactory aasApiProvider) { + public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry, IConnectorFactory connectorFactory, ISubmodelAPIFactory smApiProvider, IAASAPIFactory aasApiProvider) { this(contentProvider, aasApiProvider, smApiProvider); this.registry = registry; - this.connectorFactory = connectorFactory; + this.setConnectorFactory(connectorFactory); } /** - * Constructor that accepts a aas provider, a registry and a connection provider - * + * Constructor that accepts a registry, a connection provider, API providers, + * and submodelAggregator + */ + public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry, IConnectorFactory connectorFactory, IAASAPIFactory aasApiProvider, ISubmodelAggregator submodelAggregator) { + this.setAasApiProvider(aasApiProvider); + setAssetAdministrationShell(contentProvider); + this.setSmAggregator(submodelAggregator); + this.registry = registry; + this.setConnectorFactory(connectorFactory); + } + + /** + * Constructor that accepts a aas provider, a registry, and a connection + * provider + * * @param contentProvider * @param registry * @param provider @@ -203,12 +209,12 @@ public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry regi public MultiSubmodelProvider(AASModelProvider contentProvider, IAASRegistry registry, HTTPConnectorFactory provider) { this(contentProvider); this.registry = registry; - this.connectorFactory = provider; + this.setConnectorFactory(provider); } /** * Set an AAS for this provider - * + * * @param modelContentProvider * Model content provider */ @@ -222,33 +228,26 @@ public void setAssetAdministrationShell(AASModelProvider modelContentProvider) { @SuppressWarnings("unchecked") public void addSubmodel(SubmodelProvider modelContentProvider) { Submodel sm = Submodel.createAsFacade((Map) modelContentProvider.getValue("/submodel")); - addSubmodel(sm, modelContentProvider); + aas_provider.createValue("/submodels", sm); + getSmAggregator().createSubmodel(modelContentProvider.getAPI()); } @SuppressWarnings("unchecked") - private void createSubmodel(Object newSM) throws ProviderException { - // Adds a new submodel to the registered AAS - Submodel sm = Submodel.createAsFacade((Map) newSM); - - ISubmodelAPI smApi = smApiProvider.getSubmodelAPI(sm); - addSubmodel(sm, new SubmodelProvider(smApi)); - } - - private void addSubmodel(Submodel sm, SubmodelProvider modelContentProvider) { - String smIdShort = sm.getIdShort(); - submodel_providers.put(smIdShort, modelContentProvider); - aas_provider.createValue("/submodels", sm); + private void createSubmodel(Object newValue) { + Map newSubmodelMap = (Map) newValue; + Submodel submodel = Submodel.createAsFacade(newSubmodelMap); + getSmAggregator().createSubmodel(submodel); + aas_provider.createValue("/submodels", submodel); } /** * Remove a provider - * - * @param elementId + * + * @param elementIdShort * Element ID */ - public void removeProvider(String elementId) { - // Remove model provider - submodel_providers.remove(elementId); + public void removeProvider(String elementIdShort) { + getSmAggregator().deleteSubmodelByIdShort(elementIdShort); } /** @@ -267,81 +266,87 @@ public Object getValue(String path) throws ProviderException { if (pathElements.length == 2) { return retrieveSubmodels(); } else { - IModelProvider provider = submodel_providers.get(pathElements[2]); - - if (provider == null) { - // Get a model provider for the submodel in the registry - provider = getModelProvider(pathElements[2]); - } - - // - Retrieve submodel or property value - return provider.getValue(VABPathTools.buildPath(pathElements, 3)); + String smIdShort = pathElements[2]; + String remainingPath = VABPathTools.buildPath(pathElements, 3); + return handleSingleSubmodelRequest(smIdShort, remainingPath); } } else { - // Handle access to AAS - return aas_provider.getValue(VABPathTools.buildPath(pathElements, 1)); + String remainingPath = VABPathTools.buildPath(pathElements, 1); + return aas_provider.getValue(remainingPath); } } else { throw new MalformedRequestException("The request " + path + " is not allowed for this endpoint"); } } + private Object handleSingleSubmodelRequest(String smIdShort, String remainingPath) { + IModelProvider provider = retrieveSubmodelProvider(smIdShort); + return provider.getValue(remainingPath); + } + + private IModelProvider retrieveSubmodelProvider(String smIdShort) { + IModelProvider smProvider; + try { + ISubmodelAPI smAPI = getSmAggregator().getSubmodelAPIByIdShort(smIdShort); + smProvider = new SubmodelProvider(smAPI); + } catch (ResourceNotFoundException exception) { + // Get a model provider for the submodel in the registry + smProvider = getRemoteSubmodelProvider(smIdShort); + } + return smProvider; + } + /** * Retrieves all submodels of the AAS. If there's a registry, remote Submodels * will also be retrieved. - * + * * @return * @throws ProviderException */ - @SuppressWarnings("unchecked") private Object retrieveSubmodels() throws ProviderException { // Make a list and return all local submodels - Collection submodels = new HashSet<>(); - for (IModelProvider submodel : submodel_providers.values()) { - submodels.add(Submodel.createAsFacade((Map) submodel.getValue("/submodel"))); - } + Collection submodels = getSmAggregator().getSubmodelList(); + addConnectedSubmodels(submodels); + return submodels.stream().map(sm -> SubmodelElementMapCollectionConverter.smToMap((Submodel) sm)).collect(Collectors.toList()); + } - // Check for remote submodels + @SuppressWarnings("unchecked") + private void addConnectedSubmodels(Collection submodels) { if (registry != null) { AASDescriptor desc = registry.lookupAAS(aasId); - + // Get the address of the AAS e.g. http://localhost:8080 // This address should be equal to the address of this server String aasEndpoint = desc.getFirstEndpoint(); String aasServerURL = getServerURL(aasEndpoint); - + List localIds = submodels.stream().map(sm -> sm.getIdentification().getId()).collect(Collectors.toList()); - List missingIds = desc.getSubmodelDescriptors().stream().map(d -> d.getIdentifier()). - filter(id -> !localIds.contains(id.getId())).collect(Collectors.toList()); - - if(!missingIds.isEmpty()) { - List missingEndpoints = missingIds.stream().map(id -> desc.getSubmodelDescriptorFromIdentifierId(id.getId())) - .map(smDesc -> smDesc.getFirstEndpoint()).collect(Collectors.toList()); - + List missingIds = desc.getSubmodelDescriptors().stream().map(d -> d.getIdentifier()).filter(id -> !localIds.contains(id.getId())).collect(Collectors.toList()); + + if (!missingIds.isEmpty()) { + List missingEndpoints = missingIds.stream().map(id -> desc.getSubmodelDescriptorFromIdentifierId(id.getId())).map(smDesc -> smDesc.getFirstEndpoint()).collect(Collectors.toList()); + // Check if any of the missing Submodels have the same address as the AAS. // This would mean, that the Submodel should be present on the same // server of the AAS but is not - + // If this error would not be caught here an endless loop would develop - // as the registry would be asked for this Submodel and then it would be requested + // as the registry would be asked for this Submodel and then it would be + // requested // from this server again, which would ask the registry about it again - + // Such a situation might originate from a deleted but not unregistered Submodel // or from a manually registered but never pushed Submodel - for(String missingEndpoint: missingEndpoints) { - if(getServerURL(missingEndpoint).equals(aasServerURL)) { - throw new ResourceNotFoundException("The Submodel at Endpoint '" + missingEndpoint + - "' does not exist on this server. It seems to be registered but not actually present."); + for (String missingEndpoint : missingEndpoints) { + if (getServerURL(missingEndpoint).equals(aasServerURL)) { + throw new ResourceNotFoundException("The Submodel at Endpoint '" + missingEndpoint + "' does not exist on this server. It seems to be registered but not actually present."); } } - - List remoteSms = missingEndpoints.stream().map(endpoint -> connectorFactory.getConnector(endpoint)). - map(p -> (Map) p.getValue("")).map(m -> Submodel.createAsFacade(m)).collect(Collectors.toList()); + + List remoteSms = missingEndpoints.stream().map(endpoint -> getConnectorFactory().create(endpoint)).map(p -> (Map) p.getValue("")).map(m -> Submodel.createAsFacade(m)).collect(Collectors.toList()); submodels.addAll(remoteSms); } } - - return submodels; } /** @@ -349,7 +354,7 @@ private Object retrieveSubmodels() throws ProviderException { */ @Override public void setValue(String path, Object newValue) throws ProviderException { - VABPathTools.checkPathForNull(path); + VABPathTools.checkPathForNull(path); path = VABPathTools.stripSlashes(path); String[] pathElements = VABPathTools.splitPath(path); String propertyPath = VABPathTools.buildPath(pathElements, 3); @@ -360,13 +365,8 @@ public void setValue(String path, Object newValue) throws ProviderException { } else if (propertyPath.isEmpty()) { createSubmodel(newValue); } else { - IModelProvider provider; - if (isSubmodelLocal(pathElements[2])) { - provider = submodel_providers.get(pathElements[2]); - } else { - // Get a model provider for the submodel in the registry - provider = getModelProvider(pathElements[2]); - } + String smIdShort = pathElements[2]; + IModelProvider provider = retrieveSubmodelProvider(smIdShort); provider.setValue(propertyPath, newValue); } } @@ -376,17 +376,14 @@ public void createValue(String path, Object newValue) throws ProviderException { throw new MalformedRequestException("Create is not supported by VABMultiSubmodelProvider. Path was: " + path); } - @SuppressWarnings("unchecked") private void createAssetAdministrationShell(Object newAAS) { - Map aas = (Map) newAAS; - AssetAdministrationShell shell = AssetAdministrationShell.createAsFacade(aas); - IAASAPI aasApi = aasApiProvider.getAASApi(shell); + Map newAASMap = (Map) newAAS; + AssetAdministrationShell shell = AssetAdministrationShell.createAsFacade(newAASMap); + IAASAPI aasApi = getAasApiProvider().create(shell); aas_provider = new AASModelProvider(aasApi); } - - @SuppressWarnings("unchecked") @Override public void deleteValue(String path) throws ProviderException { VABPathTools.checkPathForNull(path); @@ -394,32 +391,22 @@ public void deleteValue(String path) throws ProviderException { if (!path.startsWith(SUBMODELS_PREFIX)) { throw new MalformedRequestException("Access to MultiSubmodelProvider always has to start with \"" + SUBMODELS_PREFIX + "\", was " + path); } - + String[] pathElements = VABPathTools.splitPath(path); String propertyPath = VABPathTools.buildPath(pathElements, 3); if (pathElements.length == 3) { // Delete Submodel from registered AAS String smIdShort = pathElements[2]; if (!isSubmodelLocal(smIdShort)) { - return; + return; } - - // Delete submodel reference from aas - // TODO: This is a hack until the API is further clarified - Submodel sm = Submodel.createAsFacade((Map) submodel_providers.get(smIdShort).getValue("/" + SubmodelProvider.SUBMODEL)); - aas_provider.deleteValue(SUBMODELS_PREFIX + "/" + sm.getIdentification().getId()); - - // Remove submodel provider - submodel_providers.remove(smIdShort); + Submodel sm = (Submodel) getSmAggregator().getSubmodelbyIdShort(smIdShort); + String smId = sm.getIdentification().getId(); + aas_provider.deleteValue(SUBMODELS_PREFIX + "/" + VABPathTools.encodePathElement(smId)); + getSmAggregator().deleteSubmodelByIdShort(smIdShort); } else if (propertyPath.length() > 0) { - IModelProvider provider; - if (isSubmodelLocal(pathElements[2])) { - provider = submodel_providers.get(pathElements[2]); - } else { - // Get a model provider for the submodel in the registry - provider = getModelProvider(pathElements[2]); - } - + String smIdShort = pathElements[2]; + IModelProvider provider = retrieveSubmodelProvider(smIdShort); provider.deleteValue(propertyPath); } } @@ -436,86 +423,92 @@ public Object invokeOperation(String path, Object... parameter) throws ProviderE if (!path.startsWith(SUBMODELS_PREFIX)) { throw new MalformedRequestException("Access to MultiSubmodelProvider always has to start with \"" + SUBMODELS_PREFIX + "\", was " + path); } - String[] pathElements = VABPathTools.splitPath(path); String operationPath = VABPathTools.buildPath(pathElements, 3); - - IModelProvider provider; - if (isSubmodelLocal(pathElements[2])) { - provider = submodel_providers.get(pathElements[2]); - } else { - // Get a model provider for the submodel in the registry - provider = getModelProvider(pathElements[2]); - } - + String smIdShort = pathElements[2]; + IModelProvider provider = retrieveSubmodelProvider(smIdShort); return provider.invokeOperation(operationPath, parameter); } - + /** * Check whether the given submodel exists in submodel provider - * @param key to search the submodel + * + * @param key + * to search the submodel * @return boolean true/false */ - private boolean isSubmodelLocal(String submodelId) { - return submodel_providers.containsKey(submodelId); + private boolean isSubmodelLocal(String smIdShort) { + try { + getSmAggregator().getSubmodelbyIdShort(smIdShort); + return true; + } catch (ResourceNotFoundException exception) { + return false; + } } - + /** * Check whether a registry exists + * * @return boolean true/false */ private boolean doesRegistryExist() { return this.registry != null; } - + /** * Get submodel descriptor from the registry - * @param submodelId to search the submodel + * + * @param submodelId + * to search the submodel * @return a specifi submodel descriptor */ private SubmodelDescriptor getSubmodelDescriptorFromRegistry(String submodelIdShort) { AASDescriptor aasDescriptor = registry.lookupAAS(aasId); SubmodelDescriptor desc = aasDescriptor.getSubmodelDescriptorFromIdShort(submodelIdShort); - if(desc == null) { + if (desc == null) { throw new ResourceNotFoundException("Could not resolve Submodel with idShort " + submodelIdShort + " for AAS " + aasId); } return desc; } - + /** * Get a model provider from a submodel descriptor + * * @param submodelDescriptor * @return a model provider */ - private IModelProvider getModelProvider(SubmodelDescriptor submodelDescriptor) { + private IModelProvider getRemoteSubmodelProvider(SubmodelDescriptor submodelDescriptor) { String endpoint = submodelDescriptor.getFirstEndpoint(); // Remove "/submodel" since it will be readded later endpoint = endpoint.substring(0, endpoint.length() - SubmodelProvider.SUBMODEL.length() - 1); - return connectorFactory.getConnector(endpoint); + return getConnectorFactory().create(endpoint); } - + /** * Get a model provider from a submodel id - * @param submodelId to select a specific submodel - * @throws ResourceNotFoundException if no registry is found + * + * @param submodelId + * to select a specific submodel + * @throws ResourceNotFoundException + * if no registry is found * @return a model provider */ - private IModelProvider getModelProvider(String submodelId) { + private IModelProvider getRemoteSubmodelProvider(String submodelId) { if (!doesRegistryExist()) { - throw new ResourceNotFoundException("Submodel with id " + submodelId + " cannot be resolved locally, but no registry is passed"); + throw new ResourceNotFoundException("Submodel with id " + submodelId + " cannot be resolved locally, but no registry is passed"); } - + SubmodelDescriptor submodelDescriptor = getSubmodelDescriptorFromRegistry(submodelId); - return getModelProvider(submodelDescriptor); + return getRemoteSubmodelProvider(submodelDescriptor); } - + /** - * Gets the server URL of a given endpoint. - * e.g. http://localhost:1234/x/y/z/aas/submodels/Sm1IdShort would return + * Gets the server URL of a given endpoint. e.g. + * http://localhost:1234/x/y/z/aas/submodels/Sm1IdShort would return * http://localhost:1234/x/y/z - * + * * @param endpoint * @return the server URL part of the given endpoint */ @@ -523,9 +516,33 @@ public static String getServerURL(String endpoint) { int endServerURL = endpoint.indexOf("/aas"); // if indexOf returned -1 ("/aas" not present in String) // return the whole given path - if(endServerURL < 0) { + if (endServerURL < 0) { return endpoint; } return endpoint.substring(0, endServerURL); } + + public ISubmodelAggregator getSmAggregator() { + return smAggregator; + } + + public void setSmAggregator(ISubmodelAggregator smAggregator) { + this.smAggregator = smAggregator; + } + + public IAASAPIFactory getAasApiProvider() { + return aasApiProvider; + } + + public void setAasApiProvider(IAASAPIFactory aasApiProvider) { + this.aasApiProvider = aasApiProvider; + } + + public IConnectorFactory getConnectorFactory() { + return connectorFactory; + } + + public void setConnectorFactory(IConnectorFactory connectorFactory) { + this.connectorFactory = connectorFactory; + } } diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java b/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java index 96498fb2..a08612a1 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPI.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.restapi.api; @@ -36,9 +51,8 @@ public interface IAASAPI { /** * Removes a submodel reference from the AAS * - * @param id + * @param idShort * the unique id of the submodel to-be-deleted */ - public void removeSubmodel(String id); + public void removeSubmodel(String idShort); } - diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java b/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java index 430a0773..1acff459 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/api/IAASAPIFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.restapi.api; @@ -21,7 +36,15 @@ public interface IAASAPIFactory { /** * Return a constructed AAS API based on a raw model provider * + * @deprecated This method is deprecated please use + * {@link #create(AssetAdministrationShell)} + * * @return */ + @Deprecated public IAASAPI getAASApi(AssetAdministrationShell aas); + + public default IAASAPI create(AssetAdministrationShell aas) { + return getAASApi(aas); + } } diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/observing/IAASAPIObserver.java b/src/main/java/org/eclipse/basyx/aas/restapi/observing/IAASAPIObserver.java new file mode 100644 index 00000000..8d695734 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/restapi/observing/IAASAPIObserver.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.restapi.observing; + +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.observer.IObserver; + +/** + * Observer for the AASAPI that triggers MQTT events for different operations on + * the AAS. + * + * @author fried + * + */ + +public interface IAASAPIObserver extends IObserver { + + /** + * Is called when a submodel reference is added + * + * @param submodel + * the reference to the submodel + */ + public void submodelAdded(IReference submodel); + + /** + * Is called when a submodel reference is removed + * + * @param idShort + * the idShort of the removed element + */ + public void submodelRemoved(String idShort); +} diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/observing/ObservableAASAPI.java b/src/main/java/org/eclipse/basyx/aas/restapi/observing/ObservableAASAPI.java new file mode 100644 index 00000000..adba9153 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/aas/restapi/observing/ObservableAASAPI.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.aas.restapi.observing; + +import java.util.stream.Stream; + +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.observer.Observable; +import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; + +/** + * Implementation of {@link IAASAPI} that calls back registered + * {@link IAASAPIObserver} when changes on Submodel References occur + * + * @author fried + * + */ +public class ObservableAASAPI extends Observable implements IAASAPI { + + private IAASAPI aasAPI; + + public ObservableAASAPI(IAASAPI observedAPI) { + aasAPI = observedAPI; + } + + @Override + public IAssetAdministrationShell getAAS() { + return aasAPI.getAAS(); + } + + @Override + public void addSubmodel(IReference submodel) { + if (!containsSubmodelReference(submodel)) + throw new MalformedRequestException("Reference has to contain a submodel"); + + aasAPI.addSubmodel(submodel); + observers.stream().forEach(o -> o.submodelAdded(submodel)); + } + + @Override + public void removeSubmodel(String id) { + aasAPI.removeSubmodel(id); + observers.stream().forEach(o -> o.submodelRemoved(id)); + } + + private boolean containsSubmodelReference(IReference submodel) { + Stream filtered = submodel.getKeys().stream().filter(o -> o.getType().name().equalsIgnoreCase(KeyElements.SUBMODEL.getStandardizedLiteral())); + return filtered.count() > 0; + } + +} diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java b/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java index 9c4734c3..12b1256f 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPI.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.restapi.vab; @@ -17,6 +32,7 @@ import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.aas.restapi.AASAPIHelper; import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; @@ -49,19 +65,19 @@ public VABAASAPI(IModelProvider provider) { @Override public IAssetAdministrationShell getAAS() { // For access on the container property root, return the whole model - Map map = (Map) provider.getValue(""); + Map map = (Map) provider.getValue(AASAPIHelper.getAASPath()); return AssetAdministrationShell.createAsFacade(map); } @Override public void addSubmodel(IReference submodel) { - provider.createValue(AssetAdministrationShell.SUBMODELS, submodel); + provider.createValue(AASAPIHelper.getSubmodelsPath(), submodel); } - + @SuppressWarnings("unchecked") @Override public void removeSubmodel(String id) { - Collection> smReferences = (Collection>) provider.getValue(AssetAdministrationShell.SUBMODELS); + Collection> smReferences = (Collection>) provider.getValue(AASAPIHelper.getSubmodelsPath()); // Reference to submodel could be either by idShort (=> local) or directly via // its identifier for (Iterator> iterator = smReferences.iterator(); iterator.hasNext();) { @@ -72,7 +88,7 @@ public void removeSubmodel(String id) { String idValue = lastKey.getValue(); // remove this reference, if the last key points to the submodel if (idValue.equals(id)) { - provider.deleteValue(AssetAdministrationShell.SUBMODELS, ref); + provider.deleteValue(AASAPIHelper.getSubmodelsPath(), ref); break; } } diff --git a/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java b/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java index c1250806..5f45b2c5 100644 --- a/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/aas/restapi/vab/VABAASAPIFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.aas.restapi.vab; diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java new file mode 100644 index 00000000..4473417e --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/AASAggregatorAASXUpload.java @@ -0,0 +1,102 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.extensions.aas.aggregator.aasxupload; + +import java.io.InputStream; +import java.util.Collection; +import java.util.Set; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.bundle.AASBundleHelper; +import org.eclipse.basyx.aas.factory.aasx.AASXToMetamodelConverter; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.api.IAASAggregatorAASXUpload; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; + +/** + * An implementation of the IAASAggregatorAASXUpload interface using maps + * internally with the support of AASX upload via {@link InputStream} + * + * @author haque + * + */ +public class AASAggregatorAASXUpload implements IAASAggregatorAASXUpload { + private IAASAggregator aggregator; + + /** + * Constructs default AAS Aggregator with AASX upload + */ + public AASAggregatorAASXUpload(IAASAggregator aggregator) { + this.aggregator = aggregator; + } + + @Override + public void uploadAASX(InputStream aasxStream) { + try { + AASXToMetamodelConverter converter = new AASXToMetamodelConverter(aasxStream); + Set bundles = converter.retrieveAASBundles(); + AASBundleHelper.integrate(this, bundles); + } catch (Exception e) { + throw new MalformedRequestException("invalid request to aasx path without valid aasx input stream"); + } + } + + @Override + public Collection getAASList() { + return aggregator.getAASList(); + } + + @Override + public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException { + return aggregator.getAAS(aasId); + } + + @Override + public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException { + return aggregator.getAASProvider(aasId); + } + + @Override + public void createAAS(AssetAdministrationShell aas) { + aggregator.createAAS(aas); + } + + @Override + public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException { + aggregator.updateAAS(aas); + } + + @Override + public void deleteAAS(IIdentifier aasId) { + aggregator.deleteAAS(aasId); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/api/IAASAggregatorAASXUpload.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/api/IAASAggregatorAASXUpload.java new file mode 100644 index 00000000..580d8d51 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/api/IAASAggregatorAASXUpload.java @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.extensions.aas.aggregator.aasxupload.api; + +import java.io.InputStream; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; + +/** + * Interface for the Asset Administration Shell Aggregator API
+ * with AASX upload support + * + * @author haque + * + */ +public interface IAASAggregatorAASXUpload extends IAASAggregator { + /** + * Uploads an AASX in the AAS Aggregator + * + * @param aasxStream + * stream of the given AASX + */ + public void uploadAASX(InputStream aasxStream); +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/proxy/AASAggregatorAASXUploadProxy.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/proxy/AASAggregatorAASXUploadProxy.java new file mode 100644 index 00000000..d9fdf6e6 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/proxy/AASAggregatorAASXUploadProxy.java @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.extensions.aas.aggregator.aasxupload.proxy; + +import java.io.InputStream; + +import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.api.IAASAggregatorAASXUpload; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.restapi.AASAggregatorAASXUploadProvider; +import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.eclipse.basyx.vab.protocol.http.helper.HTTPUploadHelper; + +/** + * Proxy AASAggregator with the support of uploading AASX + * + * @author haque + * + */ +public class AASAggregatorAASXUploadProxy extends AASAggregatorProxy implements IAASAggregatorAASXUpload { + private String aasAggregatorUrl; + + public AASAggregatorAASXUploadProxy(String url) { + super(url); + this.aasAggregatorUrl = url; + } + + @Override + public void uploadAASX(InputStream aasxStream) { + String uploadUrl = VABPathTools.append(aasAggregatorUrl, AASAggregatorAASXUploadProvider.AASX_PATH); + try { + HTTPUploadHelper.uploadHTTPPost(aasxStream, uploadUrl); + } catch (Exception e) { + throw new MalformedRequestException("invalid request to aasx path without valid aasx input stream"); + } + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/restapi/AASAggregatorAASXUploadProvider.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/restapi/AASAggregatorAASXUploadProvider.java new file mode 100644 index 00000000..f1aee340 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/aasxupload/restapi/AASAggregatorAASXUploadProvider.java @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.extensions.aas.aggregator.aasxupload.restapi; + +import java.io.InputStream; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.api.IAASAggregatorAASXUpload; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; + +/** + * Provider class with support to upload an AASX file in the underlying + * {@link IAASAggregator} + * + * @author haque + * + */ +public class AASAggregatorAASXUploadProvider extends AASAggregatorProvider { + private IAASAggregatorAASXUpload uploadAggregator; + public static final String AASX_PATH = "aasx"; + + public AASAggregatorAASXUploadProvider(IAASAggregatorAASXUpload aggregator) { + super(aggregator); + this.uploadAggregator = aggregator; + } + + @Override + public void createValue(String path, Object newEntity) throws ProviderException { + path = stripPrefix(path); + String[] splitted = VABPathTools.splitPath(path); + + if (isAASXAccessPath(splitted)) { + try { + this.uploadAggregator.uploadAASX((InputStream) newEntity); + } catch (Exception e) { + throw new ProviderException("AASX upload failed"); + } + + } else { + super.createValue(path, newEntity); + } + } + + /** + * Checks if the path array is a valid AASX path + * + * @param splitted + * @return true/false + */ + private boolean isAASXAccessPath(String[] splitted) { + return splitted.length == 1 && splitted[0].equals(AASX_PATH); + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AASAggregatorScopes.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AASAggregatorScopes.java new file mode 100644 index 00000000..8a612a8c --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AASAggregatorScopes.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.authorization; + +/** + * Constants for the OAuth2 scopes related to the + * {@link AuthorizedAASAggregator}. + * + * @author jungjan, fried, fischer + * @see https://tools.ietf.org/html/rfc6749#section-3.3 + */ +public final class AASAggregatorScopes { + public static final String READ_SCOPE = "urn:org.eclipse.basyx:scope:aas-aggregator:read"; + public static final String WRITE_SCOPE = "urn:org.eclipse.basyx:scope:aas-aggregator:write"; + + private AASAggregatorScopes() { + // This class should not be instantiated as it serves as a holder for constants + // only + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedAASAggregator.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedAASAggregator.java new file mode 100644 index 00000000..b32168b8 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedAASAggregator.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.authorization; + +/** + * An aggregator implementation that authorizes invocations before forwarding them to + * an underlying aggregator implementation. + *

+ * Implementation Note: + * This implementation internally uses {@link SecurityContextHolder} to access the {@link SecurityContext} and its {@link Authentication}. + * For read operations we require Read Scope Authority, for mutations we require Write Scope Authority. + * + * @author jungjan, fried, fischer + * @see AASAggregatorScopes + */ +import java.util.Collection; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.extensions.shared.authorization.SecurityContextAuthorizer; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; + +public class AuthorizedAASAggregator implements IAASAggregator { + private static final String SCOPE_AUTHORITY_PREFIX = "SCOPE_"; + public static final String READ_AUTHORITY = SCOPE_AUTHORITY_PREFIX + AASAggregatorScopes.READ_SCOPE; + public static final String WRITE_AUTHORITY = SCOPE_AUTHORITY_PREFIX + AASAggregatorScopes.WRITE_SCOPE; + + private final IAASAggregator aasAggregator; + private final SecurityContextAuthorizer authorizer = new SecurityContextAuthorizer(); + + public AuthorizedAASAggregator(IAASAggregator aasAggregator) { + this.aasAggregator = aasAggregator; + } + + @Override + public Collection getAASList() { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return aasAggregator.getAASList(); + } + + @Override + public IAssetAdministrationShell getAAS(IIdentifier shellId) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return aasAggregator.getAAS(shellId); + } + + @Override + public IModelProvider getAASProvider(IIdentifier shellId) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return aasAggregator.getAASProvider(shellId); + } + + @Override + public void createAAS(AssetAdministrationShell shell) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + aasAggregator.createAAS(shell); + } + + @Override + public void updateAAS(AssetAdministrationShell shell) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + aasAggregator.updateAAS(shell); + } + + @Override + public void deleteAAS(IIdentifier shellId) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + aasAggregator.deleteAAS(shellId); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedAASAggregatorProxy.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedAASAggregatorProxy.java new file mode 100644 index 00000000..f9b57e90 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedAASAggregatorProxy.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.authorization; + +import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy; +import org.eclipse.basyx.vab.coder.json.connector.JSONConnector; +import org.eclipse.basyx.vab.protocol.http.connector.IAuthorizationSupplier; +import org.eclipse.basyx.vab.protocol.https.HTTPSConnector; + +/** + * Local proxy class that hides HTTP calls to BaSys aggregator with enabled + * authorization. + * + * @author jungjan, fischer, fried + */ +public class AuthorizedAASAggregatorProxy extends AASAggregatorProxy { + + /** + * Constructor for an AAS aggregator proxy based on a HTTP connection + * + * @param aasAggregatorUrl + * The endpoint of the aggregator + * @param authorizationSupplier + * Supplier for values to be placed in the HTTP Authorization request + * header + */ + public AuthorizedAASAggregatorProxy(String aasAggregatorUrl, IAuthorizationSupplier authorizationSupplier) { + super(new JSONConnector(new HTTPSConnector(harmonizeURL(aasAggregatorUrl), authorizationSupplier))); + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedDecoratingAASAggregatorFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedDecoratingAASAggregatorFactory.java new file mode 100644 index 00000000..3b038b2d --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/authorization/AuthorizedDecoratingAASAggregatorFactory.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.authorization; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregatorFactory; + +/** + * Factory decorating AASAggregator for authorization + * + * @author fischer, fried + */ +public class AuthorizedDecoratingAASAggregatorFactory implements IAASAggregatorFactory { + private IAASAggregatorFactory apiFactory; + + public AuthorizedDecoratingAASAggregatorFactory(IAASAggregatorFactory factoryToBeDecorated) { + this.apiFactory = factoryToBeDecorated; + } + + @Override + public IAASAggregator create() { + IAASAggregator aggregator = apiFactory.create(); + aggregator = new AuthorizedAASAggregator(aggregator); + return aggregator; + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java index 86371c2c..4e6d7d32 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregator.java @@ -1,123 +1,166 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.aggregator.mqtt; import java.util.Collection; import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.observing.ObservableAASAggregator; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; -import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; import org.eclipse.paho.client.mqttv3.MqttException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; /** * Implementation variant for the AASAggregator that triggers MQTT events for * different operations on the aggregator. Has to be based on a backend * implementation of the IAASAggregator to forward its method calls. + * + * @author haque, jungjan, fischer * - * @author haque + * @deprecated Deprecated, please use {@link MqttDecoratingAASAggregatorFactory} * */ -public class MqttAASAggregator extends MqttEventService implements IAASAggregator { - private static Logger logger = LoggerFactory.getLogger(MqttAASAggregator.class); +@Deprecated +public class MqttAASAggregator implements IAASAggregator { - // List of topics - public static final String TOPIC_CREATEAAS = "BaSyxAggregator_createdAAS"; - public static final String TOPIC_DELETEAAS = "BaSyxAggregator_deletedAAS"; - public static final String TOPIC_UPDATEAAS = "BaSyxAggregator_updatedAAS"; + protected ObservableAASAggregator observedAASAggregator; + private MqttAASAggregatorObserver observer; - // The underlying AASAggregator - protected IAASAggregator observedAASAggregator; - /** * Constructor for adding this MQTT extension on top of an AASAggregator * - * @param observedAASAggregator the underlying AAS Aggregator - * @param serverEndpoint endpoint of mqtt broker - * @param clientId unique client identifier + * @param aasAggregatorToBeObserved + * the underlying AAS Aggregator + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier * @throws MqttException */ - public MqttAASAggregator(IAASAggregator observedAASAggregator, String serverEndpoint, String clientId) throws MqttException { - super(serverEndpoint, clientId); - logger.info("Create new MQTT AAS Aggregator for endpoint " + serverEndpoint); - this.observedAASAggregator = observedAASAggregator; + public MqttAASAggregator(IAASAggregator aasAggregatorToBeObserved, String serverEndpoint, String clientId) throws MqttException { + this(aasAggregatorToBeObserved, serverEndpoint, clientId, new MqttDefaultFilePersistence()); + } + + public MqttAASAggregator(IAASAggregator aasAggregatorToBeObserved, MqttClient client) throws MqttException { + observedAASAggregator = new ObservableAASAggregator(aasAggregatorToBeObserved); + observer = new MqttAASAggregatorObserver(client); + observedAASAggregator.addObserver(observer); } /** * Constructor for adding this MQTT extension on top of an AASAggregator * - * @param observedAASAggregator the underlying AAS Aggregator - * @param serverEndpoint endpoint of mqtt broker - * @param clientId unique client identifier - * @param user username for authentication with broker - * @param pw password for authentication with broker + * @param aasAggregatorToBeObserved + * the underlying AAS Aggregator + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * * @throws MqttException */ - public MqttAASAggregator(IAASAggregator observedAASAggregator, String serverEndpoint, String clientId, String user, char[] pw) - throws MqttException { - super(serverEndpoint, clientId, user, pw); - logger.info("Create new MQTT AAS Aggregator for endpoint " + serverEndpoint); - this.observedAASAggregator = observedAASAggregator; + public MqttAASAggregator(IAASAggregator aasAggregatorToBeObserved, String serverEndpoint, String clientId, MqttClientPersistence persistence) throws MqttException { + observedAASAggregator = new ObservableAASAggregator(aasAggregatorToBeObserved); + observer = new MqttAASAggregatorObserver(serverEndpoint, clientId, persistence); + observedAASAggregator.addObserver(observer); } - + /** * Constructor for adding this MQTT extension on top of an AASAggregator * - * @param observedAASAggregator the underlying AAS Aggregator - * @param client already configured client + * @param aasAggregatorToBeObserved + * the underlying AAS Aggregator + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param pw + * password for authentication with broker + * @param pw + * password for authentication with broker * @throws MqttException */ - public MqttAASAggregator(IAASAggregator observedAASAggregator, MqttClient client) throws MqttException { - super(client); - logger.info("Create new MQTT AAS Aggregator for endpoint " + client.getServerURI()); - this.observedAASAggregator = observedAASAggregator; + public MqttAASAggregator(IAASAggregator aasAggregatorToBeObserved, String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + this(aasAggregatorToBeObserved, serverEndpoint, clientId, user, pw, new MqttDefaultFilePersistence()); } - + + /** + * + * @param aasAggregatorToBeObserved + * the underlying AAS Aggregator + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param persistence + * persistence level + * @throws MqttException + */ + public MqttAASAggregator(IAASAggregator aasAggregatorToBeObserved, String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence persistence) throws MqttException { + observedAASAggregator = new ObservableAASAggregator(aasAggregatorToBeObserved); + observer = new MqttAASAggregatorObserver(serverEndpoint, clientId, user, pw, persistence); + observedAASAggregator.addObserver(observer); + } + @Override public Collection getAASList() { - return this.observedAASAggregator.getAASList(); + return observedAASAggregator.getAASList(); } @Override - public IAssetAdministrationShell getAAS(IIdentifier aasId) throws ResourceNotFoundException { - return this.observedAASAggregator.getAAS(aasId); + public IAssetAdministrationShell getAAS(IIdentifier shellId) throws ResourceNotFoundException { + return observedAASAggregator.getAAS(shellId); } @Override - public IModelProvider getAASProvider(IIdentifier aasId) throws ResourceNotFoundException { - return this.observedAASAggregator.getAASProvider(aasId); + public IModelProvider getAASProvider(IIdentifier shellId) throws ResourceNotFoundException { + return observedAASAggregator.getAASProvider(shellId); } @Override - public void createAAS(AssetAdministrationShell aas) { - this.observedAASAggregator.createAAS(aas); - sendMqttMessage(TOPIC_CREATEAAS, aas.getIdentification().getId()); - + public void createAAS(AssetAdministrationShell shell) { + observedAASAggregator.createAAS(shell); } @Override - public void updateAAS(AssetAdministrationShell aas) throws ResourceNotFoundException { - this.observedAASAggregator.updateAAS(aas); - sendMqttMessage(TOPIC_UPDATEAAS, aas.getIdentification().getId()); - + public void updateAAS(AssetAdministrationShell shell) throws ResourceNotFoundException { + observedAASAggregator.updateAAS(shell); } @Override - public void deleteAAS(IIdentifier aasId) { - this.observedAASAggregator.deleteAAS(aasId); - sendMqttMessage(TOPIC_DELETEAAS, aasId.getId()); + public void deleteAAS(IIdentifier shellId) { + observedAASAggregator.deleteAAS(shellId); } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregatorHelper.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregatorHelper.java new file mode 100644 index 00000000..25147b97 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregatorHelper.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.mqtt; + +/** + * A helper class containing string constants of topics used by the + * AASAggregator. + * + * @author danish + * + */ +public class MqttAASAggregatorHelper { + public static final String TOPIC_CREATEAAS = "BaSyxAggregator_createdAAS"; + public static final String TOPIC_DELETEAAS = "BaSyxAggregator_deletedAAS"; + public static final String TOPIC_UPDATEAAS = "BaSyxAggregator_updatedAAS"; +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregatorObserver.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregatorObserver.java new file mode 100644 index 00000000..867fb627 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttAASAggregatorObserver.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.mqtt; + +import org.eclipse.basyx.aas.aggregator.observing.IAASAggregatorObserver; +import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Observer for the AASAggregator that triggers MQTT events for different + * operations on the aggregator. + * + * @author haque, jungjan, fischer + * + */ +public class MqttAASAggregatorObserver extends MqttEventService implements IAASAggregatorObserver { + private static Logger logger = LoggerFactory.getLogger(MqttAASAggregatorObserver.class); + + /** + * Constructor for adding this MQTT extension as an AAS Aggregator Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @throws MqttException + */ + public MqttAASAggregatorObserver(String serverEndpoint, String clientId) throws MqttException { + super(serverEndpoint, clientId); + logger.info("Create new MQTT AAS Aggregator Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an AAS Aggregator Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param pw + * password for authentication with broker + * @throws MqttException + */ + public MqttAASAggregatorObserver(String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + super(serverEndpoint, clientId, user, pw); + logger.info("Create new MQTT AAS Aggregator Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an AAS Aggregator Observer + * + * @param client + * already configured client + * @throws MqttException + */ + public MqttAASAggregatorObserver(MqttClient client) throws MqttException { + super(client); + logger.info("Create new MQTT AAS Aggregator Observer for endpoint " + client.getServerURI()); + } + + /** + * Constructor for adding this MQTT extension as an AAS Aggregator Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param persistence + * custom persistence strategy + * @throws MqttException + */ + public MqttAASAggregatorObserver(String serverEndpoint, String clientId, MqttClientPersistence persistence) throws MqttException { + super(serverEndpoint, clientId, persistence); + logger.info("Create new MQTT AAS Aggregator Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an AAS Aggregator Observer + * + * @param serverEndpoint + * endpoint of MQTT broker + * @param clientId + * unique client identifier + * @param user + * MQTT user + * @param pw + * MQTT password + * @param persistence + * custom persistence strategy + * @throws MqttException + */ + public MqttAASAggregatorObserver(String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence persistence) throws MqttException { + super(serverEndpoint, clientId, user, pw, persistence); + logger.info("Create new MQTT AAS Aggregator Observer for endpoint " + serverEndpoint); + } + + @Override + public void aasCreated(String shellId) { + sendMqttMessage(MqttAASAggregatorHelper.TOPIC_CREATEAAS, shellId); + } + + @Override + public void aasUpdated(String shellId) { + sendMqttMessage(MqttAASAggregatorHelper.TOPIC_UPDATEAAS, shellId); + } + + @Override + public void aasDeleted(String shellId) { + sendMqttMessage(MqttAASAggregatorHelper.TOPIC_DELETEAAS, shellId); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttDecoratingAASAggregatorFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttDecoratingAASAggregatorFactory.java new file mode 100644 index 00000000..0c855656 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/aggregator/mqtt/MqttDecoratingAASAggregatorFactory.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.aggregator.mqtt; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregatorFactory; +import org.eclipse.basyx.aas.aggregator.observing.ObservableAASAggregator; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; + +/** + * Factory decorating AASAggregator with MQTT events by wrapping an + * IAASAggregatorFactory + * + * @author fried + */ +public class MqttDecoratingAASAggregatorFactory implements IAASAggregatorFactory { + private IAASAggregatorFactory apiFactory; + private MqttClient client; + + public MqttDecoratingAASAggregatorFactory(IAASAggregatorFactory factoryToBeDecorated, MqttClient client) { + this.apiFactory = factoryToBeDecorated; + this.client = client; + } + + @Override + public IAASAggregator create() { + try { + IAASAggregator aggregator = apiFactory.create(); + ObservableAASAggregator observedAASAggregator = new ObservableAASAggregator(aggregator); + MqttAASAggregatorObserver observer = new MqttAASAggregatorObserver(client); + observedAASAggregator.addObserver(observer); + return observedAASAggregator; + } catch (MqttException exception) { + throw new ProviderException(exception); + } + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AASAPIScopes.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AASAPIScopes.java new file mode 100644 index 00000000..8a8a9817 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AASAPIScopes.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.api.authorization; + +/** + * Constants for the OAuth2 scopes related to the {@link AuthorizedAASAPI}. + * + * @author jungjan, fried, fischer + * @see https://tools.ietf.org/html/rfc6749#section-3.3 + */ +public final class AASAPIScopes { + public static final String READ_SCOPE = "urn:org.eclipse.basyx:scope:aas-api:read"; + public static final String WRITE_SCOPE = "urn:org.eclipse.basyx:scope:aas-api:write"; + + private AASAPIScopes() { + // This class should not be instantiated as it serves as a holder for constants + // only + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedAASAPI.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedAASAPI.java new file mode 100644 index 00000000..7d0b2f05 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedAASAPI.java @@ -0,0 +1,42 @@ +package org.eclipse.basyx.extensions.aas.api.authorization; + +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.extensions.shared.authorization.SecurityContextAuthorizer; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; + +/** + * Implementation variant for the AASAPI that authorizes each access to the API + * + * @author espen + */ +public class AuthorizedAASAPI implements IAASAPI { + public static final String SCOPE_AUTHORITY_PREFIX = "SCOPE_"; + public static final String READ_AUTHORITY = SCOPE_AUTHORITY_PREFIX + AASAPIScopes.READ_SCOPE; + public static final String WRITE_AUTHORITY = SCOPE_AUTHORITY_PREFIX + AASAPIScopes.WRITE_SCOPE; + + private SecurityContextAuthorizer authorizer = new SecurityContextAuthorizer(); + private IAASAPI authorizedAPI; + + public AuthorizedAASAPI(IAASAPI authorizedAPI) { + this.authorizedAPI = authorizedAPI; + } + + @Override + public IAssetAdministrationShell getAAS() { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return authorizedAPI.getAAS(); + } + + @Override + public void addSubmodel(IReference submodel) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + authorizedAPI.addSubmodel(submodel); + } + + @Override + public void removeSubmodel(String idShort) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + authorizedAPI.removeSubmodel(idShort); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java new file mode 100644 index 00000000..a86f4e78 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/authorization/AuthorizedDecoratingAASAPIFactory.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.api.authorization; + +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; + +/** + * Api provider for constructing a new AAS API that is authorized + * + * @author espen + */ +public class AuthorizedDecoratingAASAPIFactory implements IAASAPIFactory { + private IAASAPIFactory apiFactory; + + public AuthorizedDecoratingAASAPIFactory(IAASAPIFactory factoryToBeDecorated) { + this.apiFactory = factoryToBeDecorated; + } + + @Override + public IAASAPI getAASApi(AssetAdministrationShell aas) { + return new AuthorizedAASAPI(apiFactory.create(aas)); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttAASAPIHelper.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttAASAPIHelper.java new file mode 100644 index 00000000..bb65b447 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttAASAPIHelper.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.api.mqtt; + +/** + * A helper class containing string constants of topics used by the AASAPI. + * + * @author fried + * + */ +public class MqttAASAPIHelper { + public static final String TOPIC_ADDSUBMODEL = "BaSyxAAS_addedSubmodelReference"; + public static final String TOPIC_REMOVESUBMODEL = "BaSyxAAS_removedSubmodelReference"; +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttAASAPIObserver.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttAASAPIObserver.java new file mode 100644 index 00000000..c99288c7 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttAASAPIObserver.java @@ -0,0 +1,130 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.extensions.aas.api.mqtt; + +import org.eclipse.basyx.aas.restapi.observing.IAASAPIObserver; +import org.eclipse.basyx.aas.restapi.observing.ObservableAASAPI; +import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of {@link IAASAPIObserver} Triggers MQTT events for different + * operations on the AAS. + * + * @author fried + * + */ +public class MqttAASAPIObserver extends MqttEventService implements IAASAPIObserver { + private static Logger logger = LoggerFactory.getLogger(MqttAASAPIObserver.class); + + // The underlying AASAPI + protected ObservableAASAPI observedAPI; + + /** + * Constructor for adding this MQTT extension on top of another AASAPI + * + * @param observedAPI + * The underlying aasAPI + * @throws MqttException + */ + public MqttAASAPIObserver(ObservableAASAPI observedAPI, String serverEndpoint, String clientId) throws MqttException { + this(observedAPI, serverEndpoint, clientId, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for adding this MQTT extension on top of another AASAPI with a + * custom persistence strategy + */ + public MqttAASAPIObserver(ObservableAASAPI observedAPI, String brokerEndpoint, String clientId, MqttClientPersistence persistence) throws MqttException { + super(brokerEndpoint, clientId, persistence); + logger.info("Create new MQTT AASAPI for endpoint " + brokerEndpoint); + this.observedAPI = observedAPI; + observedAPI.addObserver(this); + } + + /** + * Constructor for adding this MQTT extension on top of another AASAPI + * + * @param observedAPI + * The underlying aasAPI + * @throws MqttException + */ + public MqttAASAPIObserver(ObservableAASAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + this(observedAPI, serverEndpoint, clientId, user, pw, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for adding this MQTT extension on top of another AASAPI with + * credentials and persistency strategy + */ + public MqttAASAPIObserver(ObservableAASAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence persistence) throws MqttException { + super(serverEndpoint, clientId, user, pw); + logger.info("Create new MQTT AASAPI for endpoint " + serverEndpoint); + this.observedAPI = observedAPI; + observedAPI.addObserver(this); + } + + /** + * Constructor for adding this MQTT extension on top of another AASAPI. + * + * @param observedAPI + * The underlying aasAPI + * @param client + * An already connected mqtt client + * @throws MqttException + */ + public MqttAASAPIObserver(ObservableAASAPI observedAPI, MqttClient client) throws MqttException { + super(client); + this.observedAPI = observedAPI; + observedAPI.addObserver(this); + } + + @Override + public void submodelAdded(IReference submodelReference) { + for (IKey key : submodelReference.getKeys()) { + if (key.getType().name().equalsIgnoreCase("Submodel")) { + String id = key.getValue(); + sendMqttMessage(MqttAASAPIHelper.TOPIC_ADDSUBMODEL, getCombinedMessage(observedAPI.getAAS().getIdShort(), id)); + } + } + } + + @Override + public void submodelRemoved(String id) { + sendMqttMessage(MqttAASAPIHelper.TOPIC_REMOVESUBMODEL, getCombinedMessage(observedAPI.getAAS().getIdShort(), id)); + } + + public static String getCombinedMessage(String aasId, String idShort) { + return "(" + aasId + "," + idShort + ")"; + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java new file mode 100644 index 00000000..c18b9cab --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/api/mqtt/MqttDecoratingAASAPIFactory.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.api.mqtt; + +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.aas.restapi.api.IAASAPIFactory; +import org.eclipse.basyx.aas.restapi.observing.ObservableAASAPI; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; + +/** + * Factory decorating AASAPI with MQTT events by wrapping an IAASAPIFactory + * + * @author fried + */ +public class MqttDecoratingAASAPIFactory implements IAASAPIFactory { + private IAASAPIFactory apiFactory; + private MqttClient client; + + public MqttDecoratingAASAPIFactory(IAASAPIFactory factoryToBeDecorated, MqttClient client) { + this.apiFactory = factoryToBeDecorated; + this.client = client; + } + + @Override + public IAASAPI getAASApi(AssetAdministrationShell aas) { + try { + ObservableAASAPI observedAPI = new ObservableAASAPI(apiFactory.create(aas)); + new MqttAASAPIObserver(observedAPI, client); + return observedAPI; + } catch (MqttException e) { + throw new ProviderException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java index c8fc43b3..70291f07 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/IAASTaggedDirectory.java @@ -1,17 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.directory.tagged.api; import java.util.Set; import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; /** * A tagged directory is a registry that allows to register AAS and associate @@ -39,4 +55,51 @@ public interface IAASTaggedDirectory extends IAASRegistry { */ public Set lookupTags(Set tags); + /** + * Registers SM descriptor with tags in the registry, deletes the old + * registration if exists. + * + * @param aas + * identifier for the Asset Administration Shell. + * @param descriptor + * with information of tags. + */ + public default void registerSubmodel(IIdentifier aas, TaggedSubmodelDescriptor descriptor) { + throw new UnsupportedOperationException("The method registerSubmodel has not been implemented!"); + } + + /** + * Looks up all SM that are tagged with submodelTag + * + * @param submodelTag + * @return + */ + public default Set lookupSubmodelTag(String submodelTag) { + throw new UnsupportedOperationException("The method lookupSubmodelTag has not been implemented!"); + } + + /** + * Looks up all SM that are tagged with submodelTags + * + * @param submodelTags + * @return + */ + public default Set lookupSubmodelTags(Set submodelTags) { + throw new UnsupportedOperationException("The method lookupSubmodelTags has not been implemented!"); + } + + /** + * Looks up all SM that are tagged with submodelTags and that belongs to + * an AssetAdministrationShell tagged with aasTags. If a tag is given + * with a wildcard character asterisk (*), the tag will have the effect to match + * all other tags. + * + * @param aasTags + * @param submodelTags + * @return + */ + public default Set lookupBothAasAndSubmodelTags(Set aasTags, Set submodelTags) { + throw new UnsupportedOperationException("The method lookupBothAasAndSubmodelTags has not been implemented!"); + } + } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TagType.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TagType.java new file mode 100644 index 00000000..0dcc9f37 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TagType.java @@ -0,0 +1,27 @@ +/* Copyright 2021 objective partner AG, all rights reserved */ +package org.eclipse.basyx.extensions.aas.directory.tagged.api; + +import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnum; + +/** + * Enum that implements the {@link StandardizedLiteralEnum} interface. Used to + * specify which type of tag is processed. + * + * @author msiebert + * + */ + +public enum TagType implements StandardizedLiteralEnum { + SUBMODEL("submodelTags"), AAS("tags"); + + private String standardizedLiteral; + + TagType(String name) { + this.standardizedLiteral = name; + } + + @Override + public String getStandardizedLiteral() { + return this.standardizedLiteral; + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java index a42a8d32..66c86f6a 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedAASDescriptor.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.directory.tagged.api; diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedSubmodelDescriptor.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedSubmodelDescriptor.java new file mode 100644 index 00000000..0e021557 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/api/TaggedSubmodelDescriptor.java @@ -0,0 +1,77 @@ +/* Copyright 2021 objective partner AG, all rights reserved */ +package org.eclipse.basyx.extensions.aas.directory.tagged.api; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; + +/** + * Extension of {@link SubmodelDescriptor} that allows to add tags to the + * descriptor + * + * @author msiebert + * + */ +public class TaggedSubmodelDescriptor extends SubmodelDescriptor { + public static final String MODELTYPE = "TaggedSubmodelDescriptor"; + public static final String TAGS = "tags"; + + public TaggedSubmodelDescriptor(ISubmodel submodel, String httpEndpoint) { + super(submodel, httpEndpoint); + initialize(); + } + + public TaggedSubmodelDescriptor(String idShort, IIdentifier id, String httpEndpoint) { + super(idShort, id, httpEndpoint); + initialize(); + } + + protected TaggedSubmodelDescriptor() { + super(); + } + + @SuppressWarnings("unchecked") + public static TaggedSubmodelDescriptor createAsFacade(Map map) { + if (map == null) { + return null; + } + + Collection tags = (Collection) map.get(TAGS); + if (tags instanceof List) { + map.put(TAGS, new HashSet(tags)); + } + + TaggedSubmodelDescriptor descriptor = new TaggedSubmodelDescriptor(); + descriptor.putAll(map); + + return descriptor; + } + + private void initialize() { + this.put(TAGS, new HashSet<>()); + } + + public void addTag(String tag) { + getTags().add(tag); + } + + public void addTags(List tags) { + tags.stream().forEach(this::addTag); + } + + @SuppressWarnings("unchecked") + public Set getTags() { + return (Set) this.get(TAGS); + } + + @Override + protected String getModelType() { + return MODELTYPE; + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java index 87ff5f42..e65ba0fb 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/map/MapTaggedDirectory.java @@ -1,25 +1,29 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0/ * - * SPDX-License-Identifier: EPL-2.0 + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.directory.tagged.map; -import java.util.HashSet; +import java.util.Collection; +import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; import org.eclipse.basyx.aas.registration.memory.AASRegistry; import org.eclipse.basyx.aas.registration.memory.MapRegistryHandler; import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory; import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor; +import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedSubmodelDescriptor; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; /** @@ -31,6 +35,9 @@ */ public class MapTaggedDirectory extends AASRegistry implements IAASTaggedDirectory { private Map> tagMap; + private Map> submodelTagMap = new LinkedHashMap<>(); + + private static final String WILDCARD = "*"; /** * Constructor that takes a reference to a map as a base for the registry @@ -49,20 +56,125 @@ public void register(TaggedAASDescriptor descriptor) { // Let MapRegistry take care of the registry part and only manage the tags super.register(descriptor); addTags(descriptor.getTags(), descriptor); + + Collection submodelDescriptors = descriptor.getSubmodelDescriptors(); + if (!submodelDescriptors.isEmpty()) { + submodelDescriptors.stream().filter(TaggedSubmodelDescriptor.class::isInstance).map(TaggedSubmodelDescriptor.class::cast).forEach(s -> addSubmodelTags(s.getTags(), s)); + } + } + + @Override + public void registerSubmodel(IIdentifier aas, TaggedSubmodelDescriptor descriptor) { + super.register(aas, descriptor); + addSubmodelTags(descriptor.getTags(), descriptor); + } + + private void addSubmodelTags(Set submodelTags, TaggedSubmodelDescriptor descriptor) { + submodelTags.stream().forEach(t -> addSubmodelTag(t, descriptor)); + } + + private synchronized void addSubmodelTag(String submodelTag, TaggedSubmodelDescriptor descriptor) { + submodelTagMap.computeIfAbsent(submodelTag, key -> new LinkedHashSet()).add(descriptor); + } + + @SuppressWarnings("unchecked") + public void deleteSubmodelTag(IIdentifier aasIdentifier, IIdentifier smIdentifier) { + SubmodelDescriptor submodelDescriptor = super.lookupSubmodel(aasIdentifier, smIdentifier); + super.delete(aasIdentifier, smIdentifier); + + Set tags = (Set) submodelDescriptor.get("tags"); + tags.stream().forEach(t -> submodelTagMap.get(t).remove(submodelDescriptor)); + } + + @Override + public Set lookupBothAasAndSubmodelTags(Set aasTags, Set submodelTags) { + if (aasTags.isEmpty() || submodelTags.isEmpty() || (aasTags.contains(WILDCARD) && submodelTags.contains(WILDCARD))) { + return Collections.emptySet(); + } else if (aasTags.contains(WILDCARD)) { + return lookupSubmodelTags(submodelTags); + } else if (submodelTags.contains(WILDCARD)) { + return lookupAllSubmodelDescriptorsForAasTags(aasTags); + } else { + return lookupCombinedTags(aasTags, submodelTags); + } + } + + private Set lookupCombinedTags(Set aasTags, Set submodelTags) { + Set result = new LinkedHashSet<>(); + Set aasDescriptors = lookupTags(aasTags); + Set smDescriptors = lookupSubmodelTags(submodelTags); + + for (TaggedAASDescriptor aasDesc : aasDescriptors) { + for (TaggedSubmodelDescriptor smDesc : smDescriptors) { + if (aasDesc.getSubmodelDescriptorFromIdentifierId(smDesc.getIdentifier().getId()) != null) { + result.add(smDesc); + } + } + } + + return result; + } + + private Set lookupAllSubmodelDescriptorsForAasTags(Set aasTags) { + Set result = new LinkedHashSet<>(); + + Set desc = lookupTags(aasTags); + + for (TaggedAASDescriptor descriptor : desc) { + for (SubmodelDescriptor smDesc : descriptor.getSubmodelDescriptors()) { + result.add(TaggedSubmodelDescriptor.createAsFacade(smDesc)); + } + } + + return result; + } + + @Override + public Set lookupSubmodelTag(String submodelTag) { + if (submodelTagMap.containsKey(submodelTag)) { + return new LinkedHashSet<>(submodelTagMap.get(submodelTag)); + } else { + return new LinkedHashSet<>(); + } + } + + @Override + public Set lookupSubmodelTags(Set submodelTags) { + Set result = new LinkedHashSet<>(); + result.addAll(getMatchingSubmodelDescriptors(submodelTags)); + + return result; + } + + private Set getMatchingSubmodelDescriptors(Set submodelTags) { + Set result = new LinkedHashSet<>(); + Set smDescriptors = new LinkedHashSet<>(); + + for (String s : submodelTags) { + smDescriptors.addAll(lookupSubmodelTag(s)); + } + + for (TaggedSubmodelDescriptor desc : smDescriptors) { + if (desc.getTags().containsAll(submodelTags)) { + result.add(desc); + } + } + + return result; } @Override public Set lookupTag(String tag) { if (tagMap.containsKey(tag)) { - return tagMap.get(tag); + return new LinkedHashSet<>(tagMap.get(tag)); } else { - return new HashSet<>(); + return new LinkedHashSet<>(); } } @Override public Set lookupTags(Set tags) { - Set result = new HashSet<>(); + Set result = new LinkedHashSet<>(); Set> descriptors = tags.stream().map(t -> lookupTag(t)).collect(Collectors.toSet()); if (descriptors.size() > 0) { @@ -95,7 +207,7 @@ private void addTags(Set tags, TaggedAASDescriptor descriptor) { private synchronized void addTag(String tag, TaggedAASDescriptor descriptor) { if (!tagMap.containsKey(tag)) { - tagMap.put(tag, new HashSet<>()); + tagMap.put(tag, new LinkedHashSet<>()); } tagMap.get(tag).add(descriptor); diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java index 293b0c5e..24bb18b6 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/proxy/TaggedDirectoryProxy.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.directory.tagged.proxy; @@ -18,9 +33,12 @@ import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy; import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory; import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor; +import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedSubmodelDescriptor; import org.eclipse.basyx.extensions.aas.directory.tagged.restapi.TaggedDirectoryProvider; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.vab.coder.json.connector.JSONConnector; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector; @@ -44,7 +62,27 @@ private static VABElementProxy createTaggedProxy(IModelProvider provider) { @Override public void register(TaggedAASDescriptor descriptor) { - taggedProvider.createValue("", descriptor); + taggedProvider.createValue(VABPathTools.encodePathElement(descriptor.getIdentifier().getId()), descriptor); + } + + @Override + public void registerSubmodel(IIdentifier aas, TaggedSubmodelDescriptor smDescriptor) { + taggedProvider.createValue(VABPathTools.encodePathElement(aas.getId() + "/submodels/" + smDescriptor.getIdentifier().getId()), smDescriptor); + } + + @Override + public Set lookupBothAasAndSubmodelTags(Set aasTags, Set submodelTags) { + String aasTagsList = joinTagsAsString(aasTags); + String submodelTagsList = joinTagsAsString(submodelTags); + + return performCombinedTagRequest(aasTagsList, submodelTagsList); + } + + @SuppressWarnings("unchecked") + private Set performCombinedTagRequest(String aasTagList, String submodelTagList) { + Collection> desc = (Collection>) taggedProvider.getValue("?" + TaggedDirectoryProvider.API_ACCESS + aasTagList + "&" + TaggedDirectoryProvider.SUBMODEL_API_ACCESS + submodelTagList); + + return desc.stream().map(TaggedSubmodelDescriptor::createAsFacade).collect(Collectors.toSet()); } @Override @@ -54,16 +92,36 @@ public Set lookupTag(String tag) { @Override public Set lookupTags(Set tags) { - StringJoiner joiner = new StringJoiner(","); - tags.stream().forEach(t -> joiner.add(t)); - - return performTagRequest(joiner.toString()); + return performTagRequest(joinTagsAsString(tags)); } @SuppressWarnings("unchecked") private Set performTagRequest(String tagList) { - Collection> desc = (Collection>) taggedProvider.getValue(TaggedDirectoryProvider.API_ACCESS + tagList); + Collection> desc = (Collection>) taggedProvider.getValue("?" + TaggedDirectoryProvider.API_ACCESS + tagList); return desc.stream().map(m -> TaggedAASDescriptor.createAsFacade(m)).collect(Collectors.toSet()); } + @Override + public Set lookupSubmodelTag(String submodelTag) { + return performSubmodelTagRequest(submodelTag); + } + + @Override + public Set lookupSubmodelTags(Set tags) { + return performSubmodelTagRequest(joinTagsAsString(tags)); + } + + @SuppressWarnings("unchecked") + private Set performSubmodelTagRequest(String submodelTagList) { + Collection> desc = (Collection>) taggedProvider.getValue("?" + TaggedDirectoryProvider.SUBMODEL_API_ACCESS + submodelTagList); + return desc.stream().map(m -> TaggedSubmodelDescriptor.createAsFacade(m)).collect(Collectors.toSet()); + } + + private String joinTagsAsString(Set tags) { + StringJoiner joiner = new StringJoiner(","); + tags.stream().forEach(joiner::add); + + return joiner.toString(); + } + } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java index c6d251ee..5096f618 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/directory/tagged/restapi/TaggedDirectoryProvider.java @@ -1,34 +1,39 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0/ * - * SPDX-License-Identifier: EPL-2.0 + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.directory.tagged.restapi; import java.util.Arrays; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; -import java.util.regex.Pattern; import java.util.stream.Collectors; import org.eclipse.basyx.aas.registration.restapi.AASRegistryModelProvider; +import org.eclipse.basyx.extensions.aas.directory.tagged.api.TagType; import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor; +import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedSubmodelDescriptor; import org.eclipse.basyx.extensions.aas.directory.tagged.map.MapTaggedDirectory; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import com.google.common.base.Splitter; + public class TaggedDirectoryProvider extends AASRegistryModelProvider { private MapTaggedDirectory directory; public static final String PREFIX = "api/v1/directory"; - public static final String API_ACCESS = "?tags="; + public static final String API_ACCESS = "tags="; + public static final String SUBMODEL_API_ACCESS = "submodelTags="; public TaggedDirectoryProvider() { - this(new MapTaggedDirectory(new HashMap<>(), new HashMap<>())); + this(new MapTaggedDirectory(new LinkedHashMap<>(), new LinkedHashMap<>())); } public TaggedDirectoryProvider(MapTaggedDirectory directory) { @@ -40,30 +45,59 @@ public TaggedDirectoryProvider(MapTaggedDirectory directory) { public Object getValue(String path) throws ProviderException { path = VABPathTools.stripSlashes(path); if (path.startsWith(PREFIX)) { - return directory.lookupTags(extractTags(path)); + if (path.contains(API_ACCESS) && path.contains(SUBMODEL_API_ACCESS)) { + return directory.lookupBothAasAndSubmodelTags(extractTags(path, TagType.AAS.getStandardizedLiteral()), extractTags(path, TagType.SUBMODEL.getStandardizedLiteral())); + } else if (path.contains(SUBMODEL_API_ACCESS)) { + return directory.lookupSubmodelTags(extractTags(path, TagType.SUBMODEL.getStandardizedLiteral())); + } else { + return directory.lookupTags(extractTags(path, TagType.AAS.getStandardizedLiteral())); + } } else { return super.getValue(path); } } - + @SuppressWarnings("unchecked") @Override public void createValue(String path, Object newEntity) throws ProviderException { + path = VABPathTools.decodePathElement(path); path = VABPathTools.stripSlashes(path); if (path.startsWith(PREFIX)) { - directory.register(TaggedAASDescriptor.createAsFacade((Map) newEntity)); + if (path.contains("/submodels/")) { + registerSubmodel(path, newEntity); + } else { + directory.register(TaggedAASDescriptor.createAsFacade((Map) newEntity)); + } } else { super.createValue(path, newEntity); } } - private Set extractTags(String path) { + @SuppressWarnings("unchecked") + private void registerSubmodel(String path, Object newEntity) { + String aasIdWithSlashes = path.replace(PREFIX, "").replace(path.substring(path.indexOf("/submodels/")), ""); + String aasIdWithoutSlashes = VABPathTools.stripSlashes(aasIdWithSlashes); + + Identifier id = new Identifier(); + id.setId(aasIdWithoutSlashes); + directory.registerSubmodel(id, TaggedSubmodelDescriptor.createAsFacade((Map) newEntity)); + } + + private Set extractTags(String path, String tagType) { path = VABPathTools.stripSlashes(path); - path = path.replaceFirst(PREFIX, ""); + path = path.split("\\?")[1]; + Map queryParams = Splitter.on("&").trimResults().withKeyValueSeparator("=").split(path); + String tags = queryParams.get(tagType); + + return getTagsAsSet(tags); + } - // Paths now does only contain ?tags=a,b,c - path = path.replaceFirst(Pattern.quote(API_ACCESS), ""); - return Arrays.stream(path.split(",")).collect(Collectors.toSet()); + private Set getTagsAsSet(String tags) { + if (tags.isEmpty()) { + return new LinkedHashSet<>(); + } else { + return Arrays.stream(tags.split(",")).collect(Collectors.toSet()); + } } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/manager/authorized/AuthorizedConnectedAASManager.java b/src/main/java/org/eclipse/basyx/extensions/aas/manager/authorized/AuthorizedConnectedAASManager.java new file mode 100644 index 00000000..fadeff13 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/manager/authorized/AuthorizedConnectedAASManager.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.manager.authorized; + +import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.extensions.aas.registration.authorization.AuthorizedAASRegistryProxy; +import org.eclipse.basyx.vab.protocol.http.connector.IAuthorizationSupplier; +import org.eclipse.basyx.vab.protocol.https.HTTPSConnectorProvider; + +/** + * A ConnectedAASManager that uses a HTTPSConnector with authorization. + * Optionally, an authorized registry can also be created with an registry-URL + * + * @author mueller-zhang, espen + */ +public class AuthorizedConnectedAASManager extends ConnectedAssetAdministrationShellManager { + + /** + * Constructor to create a ConnectedAASManager with an user defined registry and + * authorization supplier + * + * @param registry + * an user defined registry + * @param authorizationSupplier + * Supplier for values to be placed in the HTTP Authorization request + * header + */ + public AuthorizedConnectedAASManager(IAASRegistry registry, IAuthorizationSupplier authorizationSupplier) { + super(registry, new HTTPSConnectorProvider(authorizationSupplier)); + } + + /** + * Constructor to create a ConnectedAASManager with authorized registry and + * authorization supplier + * + * @param registryUrl + * registry url to create a registry with authorization + * @param authorizationSupplier + * Supplier for values to be placed in the HTTP Authorization request + * header + */ + public AuthorizedConnectedAASManager(String registryUrl, IAuthorizationSupplier authorizationSupplier) { + super(new AuthorizedAASRegistryProxy(registryUrl, authorizationSupplier), new HTTPSConnectorProvider(authorizationSupplier)); + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AASRegistryScopes.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AASRegistryScopes.java new file mode 100644 index 00000000..d2742906 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AASRegistryScopes.java @@ -0,0 +1,18 @@ +package org.eclipse.basyx.extensions.aas.registration.authorization; + +/** + * Constants for the OAuth2 scopes related to the {@link AuthorizedAASRegistry}. + * + * @author pneuschwander + * @see https://tools.ietf.org/html/rfc6749#section-3.3 + */ +public final class AASRegistryScopes { + public static final String READ_SCOPE = "urn:org.eclipse.basyx:scope:aas-registry:read"; + public static final String WRITE_SCOPE = "urn:org.eclipse.basyx:scope:aas-registry:write"; + + private AASRegistryScopes() { + // This class should not be instantiated as it serves as a holder for constants + // only + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AuthorizedAASRegistry.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AuthorizedAASRegistry.java new file mode 100644 index 00000000..1794c5a3 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AuthorizedAASRegistry.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.registration.authorization; + +import java.util.List; + +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.extensions.shared.authorization.SecurityContextAuthorizer; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * A registry implementation that authorizes invocations before forwarding them + * to an underlying registry implementation. + *

+ * Implementation Note: This implementation internally uses + * {@link SecurityContextHolder} to access the {@link SecurityContext} and its + * {@link Authentication}. For read operations we require Read Scope Authority, + * for mutations we require Write Scope Authority. + * + * @author pneuschwander + * @see AASRegistryScopes + */ +public class AuthorizedAASRegistry implements IAASRegistry { + public static final String SCOPE_AUTHORITY_PREFIX = "SCOPE_"; + public static final String READ_AUTHORITY = SCOPE_AUTHORITY_PREFIX + AASRegistryScopes.READ_SCOPE; + public static final String WRITE_AUTHORITY = SCOPE_AUTHORITY_PREFIX + AASRegistryScopes.WRITE_SCOPE; + + private final IAASRegistry registry; + private final SecurityContextAuthorizer authorizer = new SecurityContextAuthorizer(); + + /** + * Provides registry implementation that authorizes invocations before + * forwarding them to the provided registry implementation. + */ + public AuthorizedAASRegistry(final IAASRegistry registry) { + this.registry = registry; + } + + @Override + public void register(AASDescriptor deviceAASDescriptor) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + registry.register(deviceAASDescriptor); + } + + @Override + public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + registry.register(aas, smDescriptor); + } + + @Override + public void delete(IIdentifier aasId) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + registry.delete(aasId); + } + + @Override + public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + registry.delete(aasId, smId); + } + + @Override + public AASDescriptor lookupAAS(IIdentifier aasId) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return registry.lookupAAS(aasId); + } + + @Override + public List lookupAll() throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return registry.lookupAll(); + } + + @Override + public List lookupSubmodels(IIdentifier aasId) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return registry.lookupSubmodels(aasId); + } + + @Override + public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return registry.lookupSubmodel(aasId, smId); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AuthorizedAASRegistryProxy.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AuthorizedAASRegistryProxy.java new file mode 100644 index 00000000..719ad771 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/authorization/AuthorizedAASRegistryProxy.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.registration.authorization; + +import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy; +import org.eclipse.basyx.vab.coder.json.connector.JSONConnector; +import org.eclipse.basyx.vab.protocol.http.connector.IAuthorizationSupplier; +import org.eclipse.basyx.vab.protocol.https.HTTPSConnector; + +/** + * Local proxy class that hides HTTP calls to BaSys registry with enabled + * authorization. + * + * @author pneuschwander + */ +public class AuthorizedAASRegistryProxy extends AASRegistryProxy { + + /** + * Constructor for an AAS registry proxy based on a HTTP connection + * + * @param registryUrl + * The endpoint of the registry with a HTTP-REST interface + * @param authorizationSupplier + * Supplier for values to be placed in the HTTP Authorization request + * header + */ + public AuthorizedAASRegistryProxy(final String registryUrl, final IAuthorizationSupplier authorizationSupplier) { + super(new JSONConnector(new HTTPSConnector(harmonizeURL(registryUrl), authorizationSupplier))); + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryHelper.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryHelper.java new file mode 100644 index 00000000..bc8591ee --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryHelper.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.registration.mqtt; + +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; + +/** + * A helper class containing method and string constants of topics used by the + * AASRegistry. + * + * @author danish + * + */ +public class MqttAASRegistryHelper { + public static final String TOPIC_REGISTERAAS = "BaSyxRegistry_registeredAAS"; + public static final String TOPIC_REGISTERSUBMODEL = "BaSyxRegistry_registeredSubmodel"; + public static final String TOPIC_DELETEAAS = "BaSyxRegistry_deletedAAS"; + public static final String TOPIC_DELETESUBMODEL = "BaSyxRegistry_deletedSubmodel"; + + /** + * This function is for creating a message payload representing a descriptor + * change of a submodel of a specific AAS. + * + * @param aasId + * @param smId + */ + public static String createSubmodelDescriptorOfAASChangedPayload(IIdentifier aasId, IIdentifier smId) { + return "(" + aasId.getId() + "," + smId.getId() + ")"; + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java index 4181c5e0..1e3dfb17 100644 --- a/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryService.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.aas.registration.mqtt; @@ -23,8 +38,8 @@ import org.slf4j.LoggerFactory; /** - * Implementation variant for the AASRegistryService that triggers MQTT events for - * different operations on the registry. Has to be based on a backend + * Implementation variant for the AASRegistryService that triggers MQTT events + * for different operations on the registry. Has to be based on a backend * implementation of the IAASRegistryService to forward its method calls. * * @author haque @@ -33,21 +48,18 @@ public class MqttAASRegistryService extends MqttEventService implements IAASRegistry { private static Logger logger = LoggerFactory.getLogger(MqttAASRegistryService.class); - // List of topics - public static final String TOPIC_REGISTERAAS = "BaSyxRegistry_registeredAAS"; - public static final String TOPIC_REGISTERSUBMODEL = "BaSyxRegistry_registeredSubmodel"; - public static final String TOPIC_DELETEAAS = "BaSyxRegistry_deletedAAS"; - public static final String TOPIC_DELETESUBMODEL = "BaSyxRegistry_deletedSubmodel"; - // The underlying AASRegistryService protected IAASRegistry observedRegistryService; - + /** * Constructor for adding this MQTT extension on top of an AASRegistryService * - * @param observedRegistryService the underlying registry service - * @param serverEndpoint endpoint of mqtt broker - * @param clientId unique client identifier + * @param observedRegistryService + * the underlying registry service + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier * @throws MqttException */ public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId) throws MqttException { @@ -59,25 +71,31 @@ public MqttAASRegistryService(IAASRegistry observedRegistryService, String serve /** * Constructor for adding this MQTT extension on top of an AASRegistryService * - * @param observedRegistryService the underlying registry service - * @param serverEndpoint endpoint of mqtt broker - * @param clientId unique client identifier - * @param user username for authentication with broker - * @param pw password for authentication with broker + * @param observedRegistryService + * the underlying registry service + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param pw + * password for authentication with broker * @throws MqttException */ - public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId, String user, char[] pw) - throws MqttException { + public MqttAASRegistryService(IAASRegistry observedRegistryService, String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { super(serverEndpoint, clientId, user, pw); logger.info("Create new MQTT AAS Registry Service for endpoint " + serverEndpoint); this.observedRegistryService = observedRegistryService; } - + /** * Constructor for adding this MQTT extension on top of an AASRegistryService * - * @param observedRegistryService the underlying registry service - * @param client already configured client + * @param observedRegistryService + * the underlying registry service + * @param client + * already configured client * @throws MqttException */ public MqttAASRegistryService(IAASRegistry observedRegistryService, MqttClient client) throws MqttException { @@ -86,29 +104,28 @@ public MqttAASRegistryService(IAASRegistry observedRegistryService, MqttClient c this.observedRegistryService = observedRegistryService; } - @Override public void register(AASDescriptor deviceAASDescriptor) throws ProviderException { this.observedRegistryService.register(deviceAASDescriptor); - sendMqttMessage(TOPIC_REGISTERAAS, deviceAASDescriptor.getIdentifier().getId()); + sendMqttMessage(MqttAASRegistryHelper.TOPIC_REGISTERAAS, deviceAASDescriptor.getIdentifier().getId()); } @Override public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) throws ProviderException { this.observedRegistryService.register(aas, smDescriptor); - sendMqttMessage(TOPIC_REGISTERSUBMODEL, concatAasSmId(aas, smDescriptor.getIdentifier())); + sendMqttMessage(MqttAASRegistryHelper.TOPIC_REGISTERSUBMODEL, MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(aas, smDescriptor.getIdentifier())); } @Override public void delete(IIdentifier aasId) throws ProviderException { this.observedRegistryService.delete(aasId); - sendMqttMessage(TOPIC_DELETEAAS, aasId.getId()); + sendMqttMessage(MqttAASRegistryHelper.TOPIC_DELETEAAS, aasId.getId()); } @Override public void delete(IIdentifier aasId, IIdentifier smId) throws ProviderException { this.observedRegistryService.delete(aasId, smId); - sendMqttMessage(TOPIC_DELETESUBMODEL, concatAasSmId(aasId, smId)); + sendMqttMessage(MqttAASRegistryHelper.TOPIC_DELETESUBMODEL, MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(aasId, smId)); } @Override @@ -130,8 +147,4 @@ public List lookupSubmodels(IIdentifier aasId) throws Provid public SubmodelDescriptor lookupSubmodel(IIdentifier aasId, IIdentifier smId) throws ProviderException { return this.observedRegistryService.lookupSubmodel(aasId, smId); } - - public static String concatAasSmId(IIdentifier aasId, IIdentifier smId) { - return "(" + aasId.getId() + "," + smId.getId() + ")"; - } } diff --git a/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryServiceObserver.java b/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryServiceObserver.java new file mode 100644 index 00000000..37b93fcd --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/aas/registration/mqtt/MqttAASRegistryServiceObserver.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.aas.registration.mqtt; + +import org.eclipse.basyx.aas.registration.observing.IAASRegistryServiceObserver; +import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation variant for the AASRegistryServiceObserver that triggers MQTT + * events for different operations on the registry. + * + * @author haque + * + */ +public class MqttAASRegistryServiceObserver extends MqttEventService implements IAASRegistryServiceObserver { + private static Logger logger = LoggerFactory.getLogger(MqttAASRegistryServiceObserver.class); + + /** + * Constructor for adding this MQTT extension as an AAS Registry Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @throws MqttException + */ + public MqttAASRegistryServiceObserver(String serverEndpoint, String clientId) throws MqttException { + super(serverEndpoint, clientId); + logger.info("Create new MQTT AAS Registry Service Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an AAS Registry Observer with a + * custom mqtt client persistence + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param clientId + * unique client identifier + * @param mqttPersistence + * custom mqtt persistence strategy + * @throws MqttException + */ + public MqttAASRegistryServiceObserver(String serverEndpoint, String clientId, MqttClientPersistence mqttPersistence) throws MqttException { + super(serverEndpoint, clientId, mqttPersistence); + logger.info("Create new MQTT AAS Registry Service Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for creating an MqttClient with authentication and a custom + * persistence strategy + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param pw + * password for authentication with broker + * @param mqttPersistence + * custom mqtt persistence strategy + */ + public MqttAASRegistryServiceObserver(String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence mqttPersistence) throws MqttException { + super(serverEndpoint, clientId, user, pw, mqttPersistence); + } + + /** + * Constructor for adding this MQTT extension as an AAS Registry Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param pw + * password for authentication with broker + * @throws MqttException + */ + public MqttAASRegistryServiceObserver(String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + super(serverEndpoint, clientId, user, pw); + logger.info("Create new MQTT AAS Registry Service Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an AAS Registry Observer + * + * @param client + * already configured client + * @throws MqttException + */ + public MqttAASRegistryServiceObserver(MqttClient client) throws MqttException { + super(client); + logger.info("Create new MQTT AAS Registry Service Observer for endpoint " + client.getServerURI()); + } + + @Override + public void aasRegistered(String aasId) { + sendMqttMessage(MqttAASRegistryHelper.TOPIC_REGISTERAAS, aasId); + } + + @Override + public void submodelRegistered(IIdentifier aasId, IIdentifier smId) { + sendMqttMessage(MqttAASRegistryHelper.TOPIC_REGISTERSUBMODEL, MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(aasId, smId)); + } + + @Override + public void aasDeleted(String aasId) { + sendMqttMessage(MqttAASRegistryHelper.TOPIC_DELETEAAS, aasId); + } + + @Override + public void submodelDeleted(IIdentifier aasId, IIdentifier smId) { + sendMqttMessage(MqttAASRegistryHelper.TOPIC_DELETESUBMODEL, MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(aasId, smId)); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/authorization/SecurityContextAuthorizer.java b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/SecurityContextAuthorizer.java new file mode 100644 index 00000000..4524aab7 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/shared/authorization/SecurityContextAuthorizer.java @@ -0,0 +1,37 @@ +package org.eclipse.basyx.extensions.shared.authorization; + +import java.util.Optional; + +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * Checks authorization for a specific authority according to the current + * security context + * + * @author espen + * + */ +public class SecurityContextAuthorizer { + public void throwExceptionInCaseOfInsufficientAuthorization(final String requiredAuthority) { + final Optional authentication = getAuthentication(); + if (!authentication.isPresent()) { + throw new ProviderException("Access denied for unauthenticated requestor"); + } + if (!hasRequiredAuthority(authentication.get(), requiredAuthority)) { + throw new ProviderException("Access denied as required authority is missing for requestor"); + } + } + + private Optional getAuthentication() { + final SecurityContext context = SecurityContextHolder.getContext(); + return Optional.ofNullable(context.getAuthentication()); + } + + private boolean hasRequiredAuthority(final Authentication authentication, final String requiredAuthority) { + return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).anyMatch(requiredAuthority::equals); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java b/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java index 28f2f3c8..666a9348 100644 --- a/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java +++ b/src/main/java/org/eclipse/basyx/extensions/shared/mqtt/MqttEventService.java @@ -1,15 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.shared.mqtt; import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; @@ -19,9 +35,9 @@ import org.slf4j.LoggerFactory; /** - * Implementation of common parts of MQTT event propagation services. - * Extend this class to make a service MQTT extendable - * + * Implementation of common parts of MQTT event propagation services. Extend + * this class to make a service MQTT extendable + * * @author haque * */ @@ -33,43 +49,60 @@ public class MqttEventService { // QoS for MQTT messages (1, 2 or 3). protected int qos = 1; - + /** * Constructor for creating an MqttClient (no authentication) + * * @param serverEndpoint * @param clientId * @throws MqttException */ public MqttEventService(String serverEndpoint, String clientId) throws MqttException { - this.mqttClient = new MqttClient(serverEndpoint, clientId, new MqttDefaultFilePersistence()); + this(serverEndpoint, clientId, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for creating an MqttClient (with no authentication and a custom + * persistence strategy) + */ + public MqttEventService(String serverEndpoint, String clientId, MqttClientPersistence mqttPersistence) throws MqttException { + this.mqttClient = new MqttClient(serverEndpoint, clientId, mqttPersistence); mqttClient.connect(); } - + + /** + * Constructor for creating an MqttClient with authentication and a custom + * persistence strategy + */ + public MqttEventService(String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence mqttPersistence) throws MqttException { + this.mqttClient = new MqttClient(serverEndpoint, clientId, mqttPersistence); + MqttConnectOptions options = new MqttConnectOptions(); + options.setUserName(user); + options.setPassword(pw); + mqttClient.connect(options); + } + /** * Constructor for creating an MqttClient with authentication + * * @param serverEndpoint * @param clientId * @param user * @param pw * @throws MqttException */ - public MqttEventService(String serverEndpoint, String clientId, String user, char[] pw) - throws MqttException { - this.mqttClient = new MqttClient(serverEndpoint, clientId, new MqttDefaultFilePersistence()); - MqttConnectOptions options = new MqttConnectOptions(); - options.setUserName(user); - options.setPassword(pw); - mqttClient.connect(options); + public MqttEventService(String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + this(serverEndpoint, clientId, user, pw, new MqttDefaultFilePersistence()); } - + /** * Constructor for creating an MqttClient with existing client + * * @param client * @throws MqttException */ public MqttEventService(MqttClient client) throws MqttException { this.mqttClient = client; - mqttClient.connect(); } /** @@ -91,11 +124,14 @@ public void setQoS(int qos) { public int getQoS() { return this.qos; } - + /** * Sends MQTT message to connected broker - * @param topic in which the message will be published - * @param payload the actual message + * + * @param topic + * in which the message will be published + * @param payload + * the actual message */ protected void sendMqttMessage(String topic, String payload) { MqttMessage msg = new MqttMessage(payload.getBytes()); diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/AuthorizedDecoratingSubmodelAggregatorFactory.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/AuthorizedDecoratingSubmodelAggregatorFactory.java new file mode 100644 index 00000000..e7509230 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/AuthorizedDecoratingSubmodelAggregatorFactory.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.aggregator.authorization; + +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory; + +/** + * Api provider for constructing a new Submodel aggregator that is authorized + * + * @author espen + */ +public class AuthorizedDecoratingSubmodelAggregatorFactory implements ISubmodelAggregatorFactory { + private ISubmodelAggregatorFactory submodelAggregatorFactory; + + public AuthorizedDecoratingSubmodelAggregatorFactory(ISubmodelAggregatorFactory submodelAggregatorFactory) { + this.submodelAggregatorFactory = submodelAggregatorFactory; + } + + @Override + public ISubmodelAggregator create() { + return new AuthorizedSubmodelAggregator(submodelAggregatorFactory.create()); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/AuthorizedSubmodelAggregator.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/AuthorizedSubmodelAggregator.java new file mode 100644 index 00000000..d4d1cbce --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/AuthorizedSubmodelAggregator.java @@ -0,0 +1,90 @@ +package org.eclipse.basyx.extensions.submodel.aggregator.authorization; + +import java.util.Collection; + +import org.eclipse.basyx.extensions.shared.authorization.SecurityContextAuthorizer; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; + +/** + * Implementation variant for the SubmodelAggregator that authorized each access + * + * @author espen + * + */ +public class AuthorizedSubmodelAggregator implements ISubmodelAggregator { + private static final String SCOPE_AUTHORITY_PREFIX = "SCOPE_"; + public static final String READ_AUTHORITY = SCOPE_AUTHORITY_PREFIX + SubmodelAggregatorScopes.READ_SCOPE; + public static final String WRITE_AUTHORITY = SCOPE_AUTHORITY_PREFIX + SubmodelAggregatorScopes.WRITE_SCOPE; + + private final SecurityContextAuthorizer authorizer = new SecurityContextAuthorizer(); + private ISubmodelAggregator decoratedSubmodelAggregator; + + public AuthorizedSubmodelAggregator(ISubmodelAggregator decoratedSubmodelAggregator) { + this.decoratedSubmodelAggregator = decoratedSubmodelAggregator; + } + + @Override + public Collection getSubmodelList() { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAggregator.getSubmodelList(); + } + + @Override + public ISubmodel getSubmodel(IIdentifier identifier) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAggregator.getSubmodel(identifier); + } + + @Override + public ISubmodel getSubmodelbyIdShort(String idShort) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAggregator.getSubmodelbyIdShort(idShort); + } + + @Override + public ISubmodelAPI getSubmodelAPIById(IIdentifier identifier) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAggregator.getSubmodelAPIById(identifier); + } + + @Override + public ISubmodelAPI getSubmodelAPIByIdShort(String idShort) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAggregator.getSubmodelAPIByIdShort(idShort); + } + + @Override + public void createSubmodel(Submodel submodel) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAggregator.createSubmodel(submodel); + } + + @Override + public void createSubmodel(ISubmodelAPI submodelAPI) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAggregator.createSubmodel(submodelAPI); + } + + @Override + public void updateSubmodel(Submodel submodel) throws ResourceNotFoundException { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAggregator.updateSubmodel(submodel); + } + + @Override + public void deleteSubmodelByIdentifier(IIdentifier identifier) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAggregator.deleteSubmodelByIdentifier(identifier); + } + + @Override + public void deleteSubmodelByIdShort(String idShort) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAggregator.deleteSubmodelByIdShort(idShort); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/SubmodelAggregatorScopes.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/SubmodelAggregatorScopes.java new file mode 100644 index 00000000..084e7c1e --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/authorization/SubmodelAggregatorScopes.java @@ -0,0 +1,19 @@ +package org.eclipse.basyx.extensions.submodel.aggregator.authorization; + +/** + * Constants for the OAuth2 scopes related to the + * {@link AuthorizedSubmodelAggregator}. + * + * @author pneuschwander + * @see https://tools.ietf.org/html/rfc6749#section-3.3 + */ +public final class SubmodelAggregatorScopes { + public static final String READ_SCOPE = "urn:org.eclipse.basyx:scope:sm-aggregator:read"; + public static final String WRITE_SCOPE = "urn:org.eclipse.basyx:scope:sm-aggregator:write"; + + private SubmodelAggregatorScopes() { + // This class should not be instantiated as it serves as a holder for constants + // only + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttDecoratingSubmodelAggregatorFactory.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttDecoratingSubmodelAggregatorFactory.java new file mode 100644 index 00000000..f5774c7a --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttDecoratingSubmodelAggregatorFactory.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.extensions.submodel.aggregator.mqtt; + +import java.security.ProviderException; + +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory; +import org.eclipse.basyx.submodel.aggregator.observing.ObservableSubmodelAggregator; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; + +/** + * Factory decorating SubmodelAggregator with MQTT events by wrapping an + * ISubmodelAggregatorFactory + * + * @author fried + */ +public class MqttDecoratingSubmodelAggregatorFactory implements ISubmodelAggregatorFactory { + private ISubmodelAggregatorFactory submodelAggregatorFactory; + private MqttClient mqttClient; + + private ObservableSubmodelAggregator observedSubmodelAggregator; + protected MqttSubmodelAggregatorObserver observer; + + public MqttDecoratingSubmodelAggregatorFactory(ISubmodelAggregatorFactory submodelAggregatorFactory, MqttClient mqttClient) { + this.submodelAggregatorFactory = submodelAggregatorFactory; + this.mqttClient = mqttClient; + } + + @Override + public ISubmodelAggregator create() { + try { + ISubmodelAggregator aggregator = submodelAggregatorFactory.create(); + observedSubmodelAggregator = new ObservableSubmodelAggregator(aggregator); + observer = new MqttSubmodelAggregatorObserver(mqttClient); + observedSubmodelAggregator.addObserver(observer); + return observedSubmodelAggregator; + } catch (MqttException e) { + throw new ProviderException(e); + } + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttSubmodelAggregatorHelper.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttSubmodelAggregatorHelper.java new file mode 100644 index 00000000..2c5abb91 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttSubmodelAggregatorHelper.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.aggregator.mqtt; + +/** + * A helper class containing string constants of topics used by the + * SubmodelAggregator. + * + * @author fischer, jungjan + * + */ +public class MqttSubmodelAggregatorHelper { + public static final String TOPIC_CREATESUBMODEL = "BaSyxAggregator_createdSubmodel"; + public static final String TOPIC_DELETESUBMODEL = "BaSyxAggregator_deletedSubmodel"; + public static final String TOPIC_UPDATESUBMODEL = "BaSyxAggregator_updatedSubmodel"; + + public static String getCombinedMessage(String shellId, String submodelId) { + return "(" + shellId + "," + submodelId + ")"; + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttSubmodelAggregatorObserver.java b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttSubmodelAggregatorObserver.java new file mode 100644 index 00000000..f66e1a5d --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/aggregator/mqtt/MqttSubmodelAggregatorObserver.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.aggregator.mqtt; + +import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; +import org.eclipse.basyx.submodel.aggregator.observing.ISubmodelAggregatorObserver; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Observer for the SubmodelAggregator that triggers MQTT events for different + * operations on the aggregator. + * + * @author fischer, jungjan, fried + * + */ +public class MqttSubmodelAggregatorObserver extends MqttEventService implements ISubmodelAggregatorObserver { + private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAggregatorObserver.class); + + /** + * Constructor for adding this MQTT extension as an Submodel Aggregator Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @throws MqttException + */ + public MqttSubmodelAggregatorObserver(String serverEndpoint, String clientId) throws MqttException { + super(serverEndpoint, clientId); + logger.info("Create new MQTT Submodel Aggregator Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an Submodel Aggregator Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param user + * username for authentication with broker + * @param pw + * password for authentication with broker + * @throws MqttException + */ + public MqttSubmodelAggregatorObserver(String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + super(serverEndpoint, clientId, user, pw); + logger.info("Create new MQTT Submodel Aggregator Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an Submodel Aggregator Observer + * + * @param client + * already configured client + * @throws MqttException + */ + public MqttSubmodelAggregatorObserver(MqttClient client) throws MqttException { + super(client); + logger.info("Create new MQTT Submodel Aggregator Observer for endpoint " + client.getServerURI()); + } + + /** + * Constructor for adding this MQTT extension as an Submodel Aggregator Observer + * + * @param serverEndpoint + * endpoint of mqtt broker + * @param clientId + * unique client identifier + * @param persistence + * custom persistence strategy + * @throws MqttException + */ + public MqttSubmodelAggregatorObserver(String serverEndpoint, String clientId, MqttClientPersistence persistence) throws MqttException { + super(serverEndpoint, clientId, persistence); + logger.info("Create new MQTT Submodel Aggregator Observer for endpoint " + serverEndpoint); + } + + /** + * Constructor for adding this MQTT extension as an Submodel Aggregator Observer + * + * @param serverEndpoint + * endpoint of MQTT broker + * @param clientId + * unique client identifier + * @param user + * MQTT user + * @param pw + * MQTT password + * @param persistence + * custom persistence strategy + * @throws MqttException + */ + public MqttSubmodelAggregatorObserver(String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence persistence) throws MqttException { + super(serverEndpoint, clientId, user, pw, persistence); + logger.info("Create new MQTT Submodel Aggregator Observer for endpoint " + serverEndpoint); + } + + @Override + public void submodelCreated(String shellId, String submodelId) { + sendMqttMessage(MqttSubmodelAggregatorHelper.TOPIC_CREATESUBMODEL, MqttSubmodelAggregatorHelper.getCombinedMessage(shellId, submodelId)); + } + + @Override + public void submodelUpdated(String shellId, String submodelId) { + sendMqttMessage(MqttSubmodelAggregatorHelper.TOPIC_UPDATESUBMODEL, MqttSubmodelAggregatorHelper.getCombinedMessage(shellId, submodelId)); + } + + @Override + public void submodelDeleted(String shellId, String submodelId) { + sendMqttMessage(MqttSubmodelAggregatorHelper.TOPIC_DELETESUBMODEL, MqttSubmodelAggregatorHelper.getCombinedMessage(shellId, submodelId)); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/AuthorizedDecoratingSubmodelAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/AuthorizedDecoratingSubmodelAPIFactory.java new file mode 100644 index 00000000..439d5115 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/AuthorizedDecoratingSubmodelAPIFactory.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.authorization; + +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; + +/** + * Api provider for constructing a new SubmodelAPI that is authorized + * + * @author espen + */ +public class AuthorizedDecoratingSubmodelAPIFactory implements ISubmodelAPIFactory { + private ISubmodelAPIFactory submodelAPIFactory; + + public AuthorizedDecoratingSubmodelAPIFactory(ISubmodelAPIFactory submodelAPIFactory) { + this.submodelAPIFactory = submodelAPIFactory; + } + + @Override + public ISubmodelAPI getSubmodelAPI(Submodel submodel) { + return new AuthorizedSubmodelAPI(submodelAPIFactory.create(submodel)); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/AuthorizedSubmodelAPI.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/AuthorizedSubmodelAPI.java new file mode 100644 index 00000000..14ceb6d2 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/AuthorizedSubmodelAPI.java @@ -0,0 +1,100 @@ +package org.eclipse.basyx.extensions.submodel.authorization; + +import java.util.Collection; + +import org.eclipse.basyx.extensions.shared.authorization.SecurityContextAuthorizer; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; + +/** + * Implementation variant for the SubmodelAggregator that authorized each access + * + * @author espen + * + */ +public class AuthorizedSubmodelAPI implements ISubmodelAPI { + private static final String SCOPE_AUTHORITY_PREFIX = "SCOPE_"; + public static final String READ_AUTHORITY = SCOPE_AUTHORITY_PREFIX + SubmodelAPIScopes.READ_SCOPE; + public static final String WRITE_AUTHORITY = SCOPE_AUTHORITY_PREFIX + SubmodelAPIScopes.WRITE_SCOPE; + + private final SecurityContextAuthorizer authorizer = new SecurityContextAuthorizer(); + private ISubmodelAPI decoratedSubmodelAPI; + + public AuthorizedSubmodelAPI(ISubmodelAPI decoratedSubmodelAPI) { + this.decoratedSubmodelAPI = decoratedSubmodelAPI; + } + + @Override + public ISubmodel getSubmodel() { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.getSubmodel(); + } + + @Override + public void addSubmodelElement(ISubmodelElement elem) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAPI.addSubmodelElement(elem); + } + + @Override + public void addSubmodelElement(String idShortPath, ISubmodelElement elem) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAPI.addSubmodelElement(idShortPath, elem); + } + + @Override + public ISubmodelElement getSubmodelElement(String idShortPath) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.getSubmodelElement(idShortPath); + } + + @Override + public void deleteSubmodelElement(String idShortPath) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAPI.deleteSubmodelElement(idShortPath); + } + + @Override + public Collection getOperations() { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.getOperations(); + } + + @Override + public Collection getSubmodelElements() { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.getSubmodelElements(); + } + + @Override + public void updateSubmodelElement(String idShortPath, Object newValue) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(WRITE_AUTHORITY); + decoratedSubmodelAPI.updateSubmodelElement(idShortPath, newValue); + } + + @Override + public Object getSubmodelElementValue(String idShortPath) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.getSubmodelElementValue(idShortPath); + } + + @Override + public Object invokeOperation(String idShortPath, Object... params) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.invokeOperation(idShortPath, params); + } + + @Override + public Object invokeAsync(String idShortPath, Object... params) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.invokeAsync(idShortPath, params); + } + + @Override + public Object getOperationResult(String idShort, String requestId) { + authorizer.throwExceptionInCaseOfInsufficientAuthorization(READ_AUTHORITY); + return decoratedSubmodelAPI.getOperationResult(idShort, requestId); + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/SubmodelAPIScopes.java b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/SubmodelAPIScopes.java new file mode 100644 index 00000000..9117ac25 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/authorization/SubmodelAPIScopes.java @@ -0,0 +1,21 @@ +package org.eclipse.basyx.extensions.submodel.authorization; + +import org.eclipse.basyx.extensions.submodel.aggregator.authorization.AuthorizedSubmodelAggregator; + +/** + * Constants for the OAuth2 scopes related to the + * {@link AuthorizedSubmodelAggregator}. + * + * @author pneuschwander + * @see https://tools.ietf.org/html/rfc6749#section-3.3 + */ +public final class SubmodelAPIScopes { + public static final String READ_SCOPE = "urn:org.eclipse.basyx:scope:sm-api:read"; + public static final String WRITE_SCOPE = "urn:org.eclipse.basyx:scope:sm-api:write"; + + private SubmodelAPIScopes() { + // This class should not be instantiated as it serves as a holder for constants + // only + } +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttDecoratingSubmodelAPIFactory.java b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttDecoratingSubmodelAPIFactory.java new file mode 100644 index 00000000..abb519e3 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttDecoratingSubmodelAPIFactory.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.mqtt; + +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; +import org.eclipse.basyx.submodel.restapi.observing.ObservableSubmodelAPI; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; + +/** + * Factory decorating SubmodelAPI with MQTT events by wrapping an + * ISubmodelAPIFactory + * + * @author fried + */ +public class MqttDecoratingSubmodelAPIFactory implements ISubmodelAPIFactory { + private ISubmodelAPIFactory apiFactory; + private MqttClient client; + + public MqttDecoratingSubmodelAPIFactory(ISubmodelAPIFactory factoryToBeDecorated, MqttClient client) { + this.apiFactory = factoryToBeDecorated; + this.client = client; + } + + @Override + public ISubmodelAPI getSubmodelAPI(Submodel submodel) { + try { + ObservableSubmodelAPI observedAPI = new ObservableSubmodelAPI(apiFactory.create(submodel)); + new MqttSubmodelAPIObserver(observedAPI, client); + return observedAPI; + } catch (MqttException e) { + throw new ProviderException(e); + } + } + +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java index cdbd643e..4784ccc5 100644 --- a/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPI.java @@ -1,103 +1,122 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.extensions.submodel.mqtt; import java.util.Collection; -import java.util.HashSet; -import java.util.List; import java.util.Set; -import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; -import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; -import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.submodel.restapi.observing.ObservableSubmodelAPI; import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; import org.eclipse.paho.client.mqttv3.MqttException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; /** * Implementation variant for the SubmodelAPI that triggers MQTT events for * different CRUD operations on the submodel. Has to be based on a backend * implementation of the ISubmodelAPI to forward its method calls. * + * * @author espen * + * @deprecated Deprecated, please use {@link MqttDecoratingSubmodelAPIFactory} */ -public class MqttSubmodelAPI extends MqttEventService implements ISubmodelAPI { - private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAPI.class); - - // List of topics - public static final String TOPIC_CREATESUBMODEL = "BaSyxSubmodel_createdSubmodel"; - public static final String TOPIC_ADDELEMENT = "BaSyxSubmodel_addedSubmodelElement"; - public static final String TOPIC_DELETEELEMENT = "BaSyxSubmodel_removedSubmodelElement"; - public static final String TOPIC_UPDATEELEMENT = "BaSyxSubmodel_updatedSubmodelElement"; +@Deprecated +public class MqttSubmodelAPI implements ISubmodelAPI { // The underlying SubmodelAPI - protected ISubmodelAPI observedAPI; + protected ObservableSubmodelAPI observedAPI; - // Submodel Element whitelist for filtering - protected boolean useWhitelist = false; - protected Set whitelist = new HashSet<>(); + private MqttSubmodelAPIObserver observer; /** * Constructor for adding this MQTT extension on top of another SubmodelAPI * - * @param observedAPI The underlying submodelAPI + * @param observedAPI + * The underlying submodelAPI * @throws MqttException */ public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId) throws MqttException { - super(serverEndpoint, clientId); - logger.info("Create new MQTT submodel for endpoint " + serverEndpoint); - this.observedAPI = observedAPI; - sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId()); + this(observedAPI, serverEndpoint, clientId, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI with + * a custom persistence strategy + */ + public MqttSubmodelAPI(ISubmodelAPI observedAPI, String brokerEndpoint, String clientId, MqttClientPersistence persistence) throws MqttException { + this.observedAPI = new ObservableSubmodelAPI(observedAPI); + observer = new MqttSubmodelAPIObserver(this.observedAPI, brokerEndpoint, clientId, persistence); } /** * Constructor for adding this MQTT extension on top of another SubmodelAPI * - * @param observedAPI The underlying submodelAPI + * @param observedAPI + * The underlying submodelAPI * @throws MqttException */ - public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw) - throws MqttException { - super(serverEndpoint, clientId, user, pw); - logger.info("Create new MQTT submodel for endpoint " + serverEndpoint); - this.observedAPI = observedAPI; - sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId()); + public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + this(observedAPI, serverEndpoint, clientId, user, pw, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI. + */ + public MqttSubmodelAPI(ISubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence persistence) throws MqttException { + this.observedAPI = new ObservableSubmodelAPI(observedAPI); + observer = new MqttSubmodelAPIObserver(this.observedAPI, serverEndpoint, clientId, user, pw, persistence); } /** * Constructor for adding this MQTT extension on top of another SubmodelAPI. * - * @param observedAPI The underlying submodelAPI - * @param client An already connected mqtt client - * @throws MqttException + * @param observedAPI + * The underlying submodelAPI + * @param client + * An already connected mqtt client + * @throws MqttException */ public MqttSubmodelAPI(ISubmodelAPI observedAPI, MqttClient client) throws MqttException { - super(client); - this.observedAPI = observedAPI; - sendMqttMessage(TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId()); + this.observedAPI = new ObservableSubmodelAPI(observedAPI); + observer = new MqttSubmodelAPIObserver(this.observedAPI, client); } /** - * Adds a submodel element to the filter whitelist. Can also be a path for nested submodel elements. + * Adds a submodel element to the filter whitelist. Can also be a path for + * nested submodel elements. * * @param shortId */ public void observeSubmodelElement(String shortId) { - whitelist.add(VABPathTools.stripSlashes(shortId)); + observer.observeSubmodelElement(VABPathTools.stripSlashes(shortId)); } /** @@ -106,24 +125,21 @@ public void observeSubmodelElement(String shortId) { * @param shortIds */ public void setWhitelist(Set shortIds) { - this.whitelist.clear(); - for (String entry : shortIds) { - this.whitelist.add(VABPathTools.stripSlashes(entry)); - } + observer.setWhitelist(shortIds); } /** * Disables the submodel element filter whitelist */ public void disableWhitelist() { - useWhitelist = false; + observer.disableWhitelist(); } /** * Enables the submodel element filter whitelist */ public void enableWhitelist() { - useWhitelist = true; + observer.enableWhitelist(); } @Override @@ -134,17 +150,11 @@ public ISubmodel getSubmodel() { @Override public void addSubmodelElement(ISubmodelElement elem) { observedAPI.addSubmodelElement(elem); - if (filter(elem.getIdShort())) { - sendMqttMessage(TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), elem.getIdShort())); - } } @Override public void addSubmodelElement(String idShortPath, ISubmodelElement elem) { observedAPI.addSubmodelElement(idShortPath, elem); - if (filter(idShortPath)) { - sendMqttMessage(TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath)); - } } @Override @@ -155,9 +165,6 @@ public ISubmodelElement getSubmodelElement(String idShortPath) { @Override public void deleteSubmodelElement(String idShortPath) { observedAPI.deleteSubmodelElement(idShortPath); - if (filter(idShortPath)) { - sendMqttMessage(TOPIC_DELETEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath)); - } } @Override @@ -173,9 +180,6 @@ public Collection getSubmodelElements() { @Override public void updateSubmodelElement(String idShortPath, Object newValue) { observedAPI.updateSubmodelElement(idShortPath, newValue); - if (filter(idShortPath)) { - sendMqttMessage(TOPIC_UPDATEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath)); - } } @Override @@ -197,31 +201,9 @@ public Object invokeAsync(String idShortPath, Object... params) { public Object getOperationResult(String idShort, String requestId) { return observedAPI.getOperationResult(idShort, requestId); } - + public static String getCombinedMessage(String aasId, String submodelId, String elementPart) { elementPart = VABPathTools.stripSlashes(elementPart); return "(" + aasId + "," + submodelId + "," + elementPart + ")"; } - - private boolean filter(String idShort) { - idShort = VABPathTools.stripSlashes(idShort); - return !useWhitelist || whitelist.contains(idShort); - } - - private String getSubmodelId() { - ISubmodel submodel = getSubmodel(); - return submodel.getIdentification().getId(); - } - - private String getAASId() { - ISubmodel submodel = getSubmodel(); - IReference parentReference = submodel.getParent(); - if (parentReference != null) { - List keys = parentReference.getKeys(); - if (keys != null && keys.size() > 0) { - return keys.get(0).getValue(); - } - } - return null; - } } diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPIHelper.java b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPIHelper.java new file mode 100644 index 00000000..05e24657 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPIHelper.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.mqtt; + +/** + * A helper class containing string constants of topics used by the SubmodelAPI. + * + * @author danish + * + */ +public class MqttSubmodelAPIHelper { + public static final String TOPIC_CREATESUBMODEL = "BaSyxSubmodel_createdSubmodel"; + public static final String TOPIC_ADDELEMENT = "BaSyxSubmodel_addedSubmodelElement"; + public static final String TOPIC_DELETEELEMENT = "BaSyxSubmodel_removedSubmodelElement"; + public static final String TOPIC_UPDATEELEMENT = "BaSyxSubmodel_updatedSubmodelElement"; +} diff --git a/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPIObserver.java b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPIObserver.java new file mode 100644 index 00000000..4d5c9d0c --- /dev/null +++ b/src/main/java/org/eclipse/basyx/extensions/submodel/mqtt/MqttSubmodelAPIObserver.java @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.extensions.submodel.mqtt; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.basyx.extensions.shared.mqtt.MqttEventService; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.restapi.observing.ISubmodelAPIObserver; +import org.eclipse.basyx.submodel.restapi.observing.ObservableSubmodelAPI; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttClientPersistence; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of {@link ISubmodelAPIObserver} Triggers MQTT events for + * different CRUD operations on the submodel. + * + * @author conradi + * + */ +public class MqttSubmodelAPIObserver extends MqttEventService implements ISubmodelAPIObserver { + private static Logger logger = LoggerFactory.getLogger(MqttSubmodelAPIObserver.class); + + // The underlying SubmodelAPI + protected ObservableSubmodelAPI observedAPI; + + // Submodel Element whitelist for filtering + protected boolean useWhitelist = false; + protected Set whitelist = new HashSet<>(); + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI + * + * @param observedAPI + * The underlying submodelAPI + * @throws MqttException + */ + public MqttSubmodelAPIObserver(ObservableSubmodelAPI observedAPI, String serverEndpoint, String clientId) throws MqttException { + this(observedAPI, serverEndpoint, clientId, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI with + * a custom persistence strategy + */ + public MqttSubmodelAPIObserver(ObservableSubmodelAPI observedAPI, String brokerEndpoint, String clientId, MqttClientPersistence persistence) throws MqttException { + super(brokerEndpoint, clientId, persistence); + logger.info("Create new MQTT submodel for endpoint " + brokerEndpoint); + this.observedAPI = observedAPI; + observedAPI.addObserver(this); + sendMqttMessage(MqttSubmodelAPIHelper.TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId()); + } + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI + * + * @param observedAPI + * The underlying submodelAPI + * @throws MqttException + */ + public MqttSubmodelAPIObserver(ObservableSubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw) throws MqttException { + this(observedAPI, serverEndpoint, clientId, user, pw, new MqttDefaultFilePersistence()); + } + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI with + * credentials and persistency strategy + */ + public MqttSubmodelAPIObserver(ObservableSubmodelAPI observedAPI, String serverEndpoint, String clientId, String user, char[] pw, MqttClientPersistence persistence) throws MqttException { + super(serverEndpoint, clientId, user, pw); + logger.info("Create new MQTT submodel for endpoint " + serverEndpoint); + this.observedAPI = observedAPI; + observedAPI.addObserver(this); + sendMqttMessage(MqttSubmodelAPIHelper.TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId()); + } + + /** + * Constructor for adding this MQTT extension on top of another SubmodelAPI. + * + * @param observedAPI + * The underlying submodelAPI + * @param client + * An already connected mqtt client + * @throws MqttException + */ + public MqttSubmodelAPIObserver(ObservableSubmodelAPI observedAPI, MqttClient client) throws MqttException { + super(client); + this.observedAPI = observedAPI; + observedAPI.addObserver(this); + sendMqttMessage(MqttSubmodelAPIHelper.TOPIC_CREATESUBMODEL, observedAPI.getSubmodel().getIdentification().getId()); + } + + /** + * Adds a submodel element to the filter whitelist. Can also be a path for + * nested submodel elements. + * + * @param shortId + */ + public void observeSubmodelElement(String shortId) { + whitelist.add(VABPathTools.stripSlashes(shortId)); + } + + /** + * Sets a new filter whitelist. + * + * @param shortIds + */ + public void setWhitelist(Set shortIds) { + this.whitelist.clear(); + for (String entry : shortIds) { + this.whitelist.add(VABPathTools.stripSlashes(entry)); + } + } + + /** + * Disables the submodel element filter whitelist + * + */ + public void disableWhitelist() { + useWhitelist = false; + } + + /** + * Enables the submodel element filter whitelist + * + */ + public void enableWhitelist() { + useWhitelist = true; + } + + @Override + public void elementAdded(String idShortPath, Object newValue) { + if (filter(idShortPath)) { + sendMqttMessage(MqttSubmodelAPIHelper.TOPIC_ADDELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath)); + } + } + + @Override + public void elementDeleted(String idShortPath) { + if (filter(idShortPath)) { + sendMqttMessage(MqttSubmodelAPIHelper.TOPIC_DELETEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath)); + } + } + + @Override + public void elementUpdated(String idShortPath, Object newValue) { + if (filter(idShortPath)) { + sendMqttMessage(MqttSubmodelAPIHelper.TOPIC_UPDATEELEMENT, getCombinedMessage(getAASId(), getSubmodelId(), idShortPath)); + } + } + + public static String getCombinedMessage(String aasId, String submodelId, String elementPart) { + elementPart = VABPathTools.stripSlashes(elementPart); + return "(" + aasId + "," + submodelId + "," + elementPart + ")"; + } + + private boolean filter(String idShort) { + idShort = VABPathTools.stripSlashes(idShort); + return !useWhitelist || whitelist.contains(idShort); + } + + private String getSubmodelId() { + ISubmodel submodel = observedAPI.getSubmodel(); + return submodel.getIdentification().getId(); + } + + private String getAASId() { + ISubmodel submodel = observedAPI.getSubmodel(); + IReference parentReference = submodel.getParent(); + if (parentReference != null) { + List keys = parentReference.getKeys(); + if (keys != null && keys.size() > 0) { + return keys.get(0).getValue(); + } + } + return null; + } + +} diff --git a/src/main/java/org/eclipse/basyx/submodel/aggregator/SubmodelAggregator.java b/src/main/java/org/eclipse/basyx/submodel/aggregator/SubmodelAggregator.java new file mode 100644 index 00000000..1766eaa2 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/aggregator/SubmodelAggregator.java @@ -0,0 +1,115 @@ +package org.eclipse.basyx.submodel.aggregator; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; +import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; + +/** + * A class for aggregating local submodels based on the ISubmodelAPI + * + * @author espen + * + */ +public class SubmodelAggregator implements ISubmodelAggregator { + protected Map smApiMap = new HashMap<>(); + + /** + * Store Submodel API Provider. By default, uses the VAB Submodel Provider + */ + protected ISubmodelAPIFactory smApiFactory; + + public SubmodelAggregator() { + smApiFactory = new VABSubmodelAPIFactory(); + } + + public SubmodelAggregator(ISubmodelAPIFactory smApiFactory) { + this.smApiFactory = smApiFactory; + } + + @Override + public Collection getSubmodelList() { + return smApiMap.values().stream().map(ISubmodelAPI::getSubmodel).collect(Collectors.toList()); + } + + @Override + public ISubmodel getSubmodel(IIdentifier identifier) throws ResourceNotFoundException { + ISubmodelAPI api = getSubmodelAPIById(identifier); + return api.getSubmodel(); + } + + private String getIdShort(IIdentifier identifier) { + for (ISubmodelAPI api : smApiMap.values()) { + ISubmodel submodel = api.getSubmodel(); + String idValue = submodel.getIdentification().getId(); + if (idValue.equals(identifier.getId())) { + return submodel.getIdShort(); + } + } + throw new ResourceNotFoundException("The submodel with id '" + identifier.getId() + "' could not be found"); + } + + @Override + public void createSubmodel(Submodel submodel) { + updateSubmodel(submodel); + } + + @Override + public void updateSubmodel(Submodel submodel) throws ResourceNotFoundException { + ISubmodelAPI submodelAPI = smApiFactory.create(submodel); + createSubmodel(submodelAPI); + } + + @Override + public void createSubmodel(ISubmodelAPI submodelAPI) { + smApiMap.put(submodelAPI.getSubmodel().getIdShort(), submodelAPI); + } + + @Override + public ISubmodel getSubmodelbyIdShort(String idShort) throws ResourceNotFoundException { + ISubmodelAPI api = smApiMap.get(idShort); + if (api == null) { + throw new ResourceNotFoundException("The submodel with idShort '" + idShort + "' could not be found"); + } else { + return api.getSubmodel(); + } + } + + @Override + public void deleteSubmodelByIdentifier(IIdentifier identifier) { + try { + String idShort = getIdShort(identifier); + smApiMap.remove(idShort); + } catch (ResourceNotFoundException exception) { + } + } + + @Override + public void deleteSubmodelByIdShort(String idShort) { + smApiMap.remove(idShort); + } + + @Override + public ISubmodelAPI getSubmodelAPIById(IIdentifier identifier) throws ResourceNotFoundException { + String idShort = getIdShort(identifier); + return smApiMap.get(idShort); + } + + @Override + public ISubmodelAPI getSubmodelAPIByIdShort(String idShort) throws ResourceNotFoundException { + ISubmodelAPI api = smApiMap.get(idShort); + if (api == null) { + throw new ResourceNotFoundException("The submodel with idShort '" + idShort + "' could not be found"); + } + return api; + } +} diff --git a/src/main/java/org/eclipse/basyx/submodel/aggregator/SubmodelAggregatorFactory.java b/src/main/java/org/eclipse/basyx/submodel/aggregator/SubmodelAggregatorFactory.java new file mode 100644 index 00000000..bd611916 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/aggregator/SubmodelAggregatorFactory.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.submodel.aggregator; + +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregatorFactory; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory; +import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory; + +/** + * + * Factory that constructs a SubmodelAggregator with the given API + * + * @author fried + * + */ +public class SubmodelAggregatorFactory implements ISubmodelAggregatorFactory { + + ISubmodelAPIFactory submodelAPIFactory; + + public SubmodelAggregatorFactory() { + submodelAPIFactory = new VABSubmodelAPIFactory(); + } + + public SubmodelAggregatorFactory(ISubmodelAPIFactory submodelAPIFactory) { + this.submodelAPIFactory = submodelAPIFactory; + } + + @Override + public ISubmodelAggregator create() { + return new SubmodelAggregator(submodelAPIFactory); + } + +} diff --git a/src/main/java/org/eclipse/basyx/submodel/aggregator/api/ISubmodelAggregator.java b/src/main/java/org/eclipse/basyx/submodel/aggregator/api/ISubmodelAggregator.java new file mode 100644 index 00000000..c20d3fe2 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/aggregator/api/ISubmodelAggregator.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.submodel.aggregator.api; + +import java.util.Collection; + +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; + +/** + * Interface for the Submodel Aggregator API
+ * It is used to manage multiple Submodels at the same endpoint + * + * @author espen + * + */ +public interface ISubmodelAggregator { + /** + * Retrieves all Submodels from the endpoint + * + * @return a List of all found Submodels + */ + public Collection getSubmodelList(); + + /** + * Retrieves a specific Submodel + * + * @param identifier + * the Id of the Submodel + * @return the requested Submodel + */ + public ISubmodel getSubmodel(IIdentifier identifier) throws ResourceNotFoundException; + + /** + * Retrieves a specific Submodel + * + * @param idShort + * the IdShort of the Submodel + * @return the requested Submodel + */ + public ISubmodel getSubmodelbyIdShort(String idShort) throws ResourceNotFoundException; + + /** + * Retrieves the API for a specific Submodel + * + * @param identifier + * the ID of the Submodel + * @return the requested Submodel API + */ + public ISubmodelAPI getSubmodelAPIById(IIdentifier identifier) throws ResourceNotFoundException; + + /** + * Retrieves the API for a specific Submodel + * + * @param idShort + * the idShort of the Submodel + * @return the requested Submodel API + */ + public ISubmodelAPI getSubmodelAPIByIdShort(String idShort) throws ResourceNotFoundException; + + /** + * Creates a new Submodel at the endpoint + * + * @param submodel + * the Submodel to be created + */ + public void createSubmodel(Submodel submodel); + + /** + * Creates a new Submodel using an API + * + * @param submodelAPI + * the Submodel API to be added + */ + public void createSubmodel(ISubmodelAPI submodelAPI); + + /** + * Updates a specific Submodel + * + * @param submodel + * the updated Submodel + */ + public void updateSubmodel(Submodel submodel) throws ResourceNotFoundException; + + /** + * Deletes a specific Submodel + * + * @param identifier + * the ID of the Submodel to be deleted + */ + public void deleteSubmodelByIdentifier(IIdentifier identifier); + + /** + * Deletes a specific Submodel + * + * @param idShort + * the idShort of the Submodel to be deleted + */ + public void deleteSubmodelByIdShort(String idShort); +} diff --git a/src/main/java/org/eclipse/basyx/submodel/aggregator/api/ISubmodelAggregatorFactory.java b/src/main/java/org/eclipse/basyx/submodel/aggregator/api/ISubmodelAggregatorFactory.java new file mode 100644 index 00000000..f1bdacf3 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/aggregator/api/ISubmodelAggregatorFactory.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.submodel.aggregator.api; + +/** + * Interface for providing an SubmodelAggregator + * + * @author schnicke + * + */ +public interface ISubmodelAggregatorFactory { + /** + * Return a constructed SubmodelAggregator + * + * @return + */ + public ISubmodelAggregator create(); +} diff --git a/src/main/java/org/eclipse/basyx/submodel/aggregator/observing/ISubmodelAggregatorObserver.java b/src/main/java/org/eclipse/basyx/submodel/aggregator/observing/ISubmodelAggregatorObserver.java new file mode 100644 index 00000000..e50e3ca1 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/aggregator/observing/ISubmodelAggregatorObserver.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.submodel.aggregator.observing; + +import org.eclipse.basyx.submodel.observer.IObserver; + +/** + * Interface for an observer of {@link ObservableSubmodelAggregator} + * + * @author fischer, jungjan, fried + * + */ +public interface ISubmodelAggregatorObserver extends IObserver { + + /** + * Is called when an submodel is created + * + * @param submodelId + * id of the created submodel + */ + public void submodelCreated(String shellId, String submodelId); + + /** + * Is called when an submodel is updated + * + * @param submodelId + * id of the updated submodel + */ + public void submodelUpdated(String shellId, String submodelId); + + /** + * Is called when an submodel is deleted + * + * @param submodelId + * id of the deleted submodel + */ + public void submodelDeleted(String shellId, String submodelId); +} diff --git a/src/main/java/org/eclipse/basyx/submodel/aggregator/observing/ObservableSubmodelAggregator.java b/src/main/java/org/eclipse/basyx/submodel/aggregator/observing/ObservableSubmodelAggregator.java new file mode 100644 index 00000000..d9349ac2 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/aggregator/observing/ObservableSubmodelAggregator.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.submodel.aggregator.observing; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.observer.Observable; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; + +/** + * + * Implementation of {@link ISubmodelAggregator} that calls back registered + * {@link ISubmodelAggregatorObserver} when changes on Submodel occur + * + * @author fischer, jungjan, fried + * + */ +public class ObservableSubmodelAggregator extends Observable implements ISubmodelAggregator { + + private ISubmodelAggregator submodelAggregator; + + public ObservableSubmodelAggregator(ISubmodelAggregator aggregator) { + this.submodelAggregator = aggregator; + } + + @Override + public Collection getSubmodelList() { + return submodelAggregator.getSubmodelList(); + } + + @Override + public ISubmodel getSubmodel(IIdentifier submodelIdentifier) throws ResourceNotFoundException { + return submodelAggregator.getSubmodel(submodelIdentifier); + } + + @Override + public ISubmodel getSubmodelbyIdShort(String submodelIdShort) throws ResourceNotFoundException { + return submodelAggregator.getSubmodelbyIdShort(submodelIdShort); + } + + @Override + public ISubmodelAPI getSubmodelAPIById(IIdentifier submodelIdentifier) throws ResourceNotFoundException { + return submodelAggregator.getSubmodelAPIById(submodelIdentifier); + } + + @Override + public ISubmodelAPI getSubmodelAPIByIdShort(String submodelIdShort) throws ResourceNotFoundException { + return submodelAggregator.getSubmodelAPIByIdShort(submodelIdShort); + } + + @Override + public void createSubmodel(Submodel submodel) { + submodelAggregator.createSubmodel(submodel); + observers.stream().forEach(observer -> observer.submodelCreated(getParentAASId(submodel), submodel.getIdentification().getId())); + } + + @Override + public void createSubmodel(ISubmodelAPI submodelAPI) { + submodelAggregator.createSubmodel(submodelAPI); + observers.stream().forEach(observer -> observer.submodelCreated(getParentAASId(submodelAPI.getSubmodel()), submodelAPI.getSubmodel().getIdentification().getId())); + } + + @Override + public void updateSubmodel(Submodel submodel) throws ResourceNotFoundException { + submodelAggregator.updateSubmodel(submodel); + observers.stream().forEach(observer -> observer.submodelUpdated(getParentAASId(submodel), submodel.getIdentification().getId())); + } + + @Override + public void deleteSubmodelByIdentifier(IIdentifier submodelIdentifier) { + String parentAASId = getParentAASId(submodelAggregator.getSubmodel(submodelIdentifier)); + submodelAggregator.deleteSubmodelByIdentifier(submodelIdentifier); + observers.stream().forEach(observer -> observer.submodelDeleted(parentAASId, submodelIdentifier.getId())); + } + + @Override + public void deleteSubmodelByIdShort(String submodelIdShort) { + ISubmodel submodel = submodelAggregator.getSubmodelbyIdShort(submodelIdShort); + String parentAASId = getParentAASId(submodel); + submodelAggregator.deleteSubmodelByIdShort(submodelIdShort); + observers.stream().forEach(observer -> observer.submodelDeleted(parentAASId, submodel.getIdentification().getId())); + } + + private String getParentAASId(ISubmodel submodel) { + IReference parentReference = submodel.getParent(); + if (parentReference == null) { + return null; + } + List keys = parentReference.getKeys(); + if (keys != null && keys.size() > 0) { + return keys.get(0).getValue(); + } + return null; + } +} diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java index 6ed37b82..44c89283 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/XMLHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2022 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml; @@ -21,24 +36,25 @@ /** * A Helper class containing tools for the XML converter * - * @author conradi + * @author conradi, jungjan * */ public class XMLHelper { public static final String TEXT = "#text"; - - + /** * The XML Parser returns a Map if a requested XML-Element exists only once,
* but a List of Maps if it exists multiple times. This function makes sure,
- * that it is always a List of Maps, by either casting or putting the Map into a List. + * that it is always a List of Maps, by either casting or putting the Map into a + * List. * - * @param xmlObject a XML Object, that is either a Map or a List of Maps + * @param xmlObject + * a XML Object, that is either a Map or a List of Maps * @return a List of Maps */ @SuppressWarnings("unchecked") public static List> getList(Object xmlObject) { - if(xmlObject instanceof List) { + if (xmlObject instanceof List) { return (List>) xmlObject; } else if (xmlObject instanceof Map) { List> list = new ArrayList<>(); @@ -47,21 +63,24 @@ public static List> getList(Object xmlObject) { } return new ArrayList<>(); } - - + /** - * If the content of a XML-Element is requested, the parser returns an Object or null, if it doesn't exist.
- * This function casts the Object into a String and replaces null with an empty String. + * If the content of a XML-Element is requested, the parser returns an Object or + * null, if it doesn't exist.
+ * This function casts the Object into a String and replaces null with an empty + * String. * - * @param object a Object that is either a String or null + * @param object + * a Object that is either a String or null * @return the given String or an empty String */ public static String getString(Object object) { return object instanceof String ? ((String) object).trim() : ""; } - + /** - * adapts AASX value type to local value types + * adapts AASX value type to local value types + * * @param valueType * @return */ @@ -70,24 +89,73 @@ public static ValueType convertAASXValueTypeToLocal(String valueType) { if (Strings.isNullOrEmpty(valueType)) { return ValueType.AnySimpleType; } - + // Enables parsing external aasx-files with anyURI instead of anyuri else if (valueType.equals("anyURI")) { return ValueType.AnyURI; } - + // Enables parsing external aasx-files with date instead of dateTime else if (valueType.equals("date")) { return ValueType.DateTime; } - + // Enables parsing external aasx-files with decimal instead of double else if (valueType.equals("decimal")) { return ValueType.Double; } - + else { return ValueTypeHelper.fromName(valueType); } } + + public static Object convertAASXValueToLocal(String xmlStringValue, ValueType valueType) { + switch (valueType) { + case Boolean: + return verifiedBoolean(xmlStringValue); + case Double: + return verifiedDecimal(xmlStringValue); + case Integer: + return verifiedInt(xmlStringValue); + default: + return xmlStringValue; + } + } + + private static boolean verifiedBoolean(String booleanString) { + if (!isLegalBooleanString(booleanString)) + throw new IllegalArgumentException(String.format("The passed value '" + booleanString + "' is not compatible with type Boolean", booleanString)); + return Boolean.parseBoolean(booleanString); + } + + private static Double verifiedDecimal(String decimalString) { + if (isStringNullOrEmpty(decimalString)) { + return null; + } + try { + return Double.parseDouble(decimalString); + } catch (NumberFormatException e) { + throw new NumberFormatException(String.format("The passed value '" + decimalString + "' is no compatible decimal type", decimalString)); + } + } + + private static Integer verifiedInt(String intString) { + if (isStringNullOrEmpty(intString)) { + return null; + } + try { + return Integer.parseInt(intString); + } catch (NumberFormatException e) { + throw new NumberFormatException(String.format("The passed value '" + intString + "' is not compatible with type Integer", intString)); + } + } + + private static boolean isLegalBooleanString(String booleanString) { + return booleanString.equalsIgnoreCase("true") || booleanString.equalsIgnoreCase("false") || booleanString.equalsIgnoreCase("1") || booleanString.equalsIgnoreCase("0"); + } + + private static boolean isStringNullOrEmpty(String decimalString) { + return decimalString.isEmpty() || decimalString == null; + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java index 645e591b..fc754723 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/dataspecification/DataSpecificationIEC61360XMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.api.dataspecification; @@ -29,8 +44,8 @@ import org.w3c.dom.Element; /** - * Handles the conversion between a DataSpecificationIEC61360 object and the XML tag - * <aas:dataSpecificationIEC61360> in both directions + * Handles the conversion between a DataSpecificationIEC61360 object and the XML + * tag <aas:dataSpecificationIEC61360> in both directions * * @author conradi, espen * @@ -58,12 +73,13 @@ public class DataSpecificationIEC61360XMLConverter { public static final String IEC61360_VALUE = "IEC61360:value"; public static final String IEC61360_VALUEID = "IEC61360:valueId"; public static final String IEC61360_LEVELTYPE = "IEC61360:levelType"; - - + /** * Parses the DataSpecificationIEC61360 object from XML * - * @param contentObj the XML map containing the <aas:dataSpecificationIEC61360> tag + * @param contentObj + * the XML map containing the <aas:dataSpecificationIEC61360> + * tag * @return the parsed DataSpecificationIEC61360 object */ @SuppressWarnings("unchecked") @@ -72,20 +88,17 @@ public static DataSpecificationIEC61360Content parseDataSpecificationContent(Map if (contentObj == null) { return spec; } - + // PreferredName - LangStrings - LangStrings preferredName = LangStringsXMLConverter - .parseLangStrings(contentObj.get(IEC61360_PREFERREDNAME), IEC61360_LANGSTRING); + LangStrings preferredName = LangStringsXMLConverter.parseLangStrings(contentObj.get(IEC61360_PREFERREDNAME), IEC61360_LANGSTRING); spec.setPreferredName(preferredName); // ShortName - LangStrings - LangStrings shortName = LangStringsXMLConverter - .parseLangStrings(contentObj.get(IEC61360_SHORTNAME), IEC61360_LANGSTRING); + LangStrings shortName = LangStringsXMLConverter.parseLangStrings(contentObj.get(IEC61360_SHORTNAME), IEC61360_LANGSTRING); spec.setShortName(shortName); // Unit - String spec.setUnit(XMLHelper.getString(contentObj.get(IEC61360_UNIT))); // UnitId - IReference - spec.setUnitId(ReferenceXMLConverter.parseReference((Map) contentObj.get(IEC61360_UNITID), - IEC61360_KEYS, IEC61360_KEY)); + spec.setUnitId(ReferenceXMLConverter.parseReference((Map) contentObj.get(IEC61360_UNITID), IEC61360_KEYS, IEC61360_KEY)); // Source Of Definition - String spec.setSourceOfDefinition(XMLHelper.getString(contentObj.get(IEC61360_SOURCEOFDEFINITION))); // Symbol - String @@ -93,8 +106,7 @@ public static DataSpecificationIEC61360Content parseDataSpecificationContent(Map // Data Type - DataTypeIEC61360 spec.setDataType(DataTypeIEC61360.fromString(XMLHelper.getString(contentObj.get(IEC61360_DATATYPE)))); // Definition - LangStrings - LangStrings definition = LangStringsXMLConverter - .parseLangStrings(contentObj.get(IEC61360_DEFINITION), IEC61360_LANGSTRING); + LangStrings definition = LangStringsXMLConverter.parseLangStrings(contentObj.get(IEC61360_DEFINITION), IEC61360_LANGSTRING); spec.setDefinition(definition); // ValueFormat - String spec.setValueFormat(XMLHelper.getString(contentObj.get(IEC61360_VALUEFORMAT))); @@ -103,17 +115,18 @@ public static DataSpecificationIEC61360Content parseDataSpecificationContent(Map // Value - String spec.setValue(XMLHelper.getString(contentObj.get(IEC61360_VALUE))); // ValueId - Ref - spec.setValueId(ReferenceXMLConverter.parseReference((Map) contentObj.get(IEC61360_VALUEID), - IEC61360_KEYS, IEC61360_KEY)); + spec.setValueId(ReferenceXMLConverter.parseReference((Map) contentObj.get(IEC61360_VALUEID), IEC61360_KEYS, IEC61360_KEY)); // LevelType - LevelType spec.setLevelType(LevelType.fromString(XMLHelper.getString(contentObj.get(IEC61360_LEVELTYPE)))); return spec; } - + /** * Parses the Collection object from XML * - * @param xmlObj the XML map containing the <IEC61360:valueReferencePair> tags + * @param xmlObj + * the XML map containing the <IEC61360:valueReferencePair> + * tags * @return the parsed collection of IValueReferencePair */ @SuppressWarnings("unchecked") @@ -133,20 +146,22 @@ private static Collection parseValueList(Map valueList) { + private static void buildValueListXML(Document document, Element valueListRoot, Collection valueList) { for (IValueReferencePair pair : valueList) { Element pairRoot = document.createElement(IEC61360_REFERENCEPAIR); IReference valueId = pair.getValueId(); Element valueIdRoot = document.createElement(IEC61360_PAIRID); - valueIdRoot - .appendChild( - ReferenceXMLConverter.buildReferenceXML(document, valueId, IEC61360_KEYS, IEC61360_KEY)); + valueIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, valueId, IEC61360_KEYS, IEC61360_KEY)); pairRoot.appendChild(valueIdRoot); Element valueRoot = document.createElement(IEC61360_PAIRVALUE); @@ -256,5 +266,5 @@ private static void buildValueListXML(Document document, Element valueListRoot, valueListRoot.appendChild(pairRoot); } } - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java index a46f9db9..a4d43242 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/api/parts/ConceptDescriptionXMLConverter.java @@ -1,16 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.api.parts; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -30,7 +46,8 @@ import org.w3c.dom.Element; /** - * Handles the conversion between IConceptDescription objects and the XML tag <aas:conceptDescriptions> in both directions + * Handles the conversion between IConceptDescription objects and the XML tag + * <aas:conceptDescriptions> in both directions * * @author conradi * @@ -40,39 +57,44 @@ public class ConceptDescriptionXMLConverter { public static final String CONCEPT_DESCRIPTIONS = "aas:conceptDescriptions"; public static final String CONCEPT_DESCRIPTION = "aas:conceptDescription"; public static final String IS_CASE_OF = "aas:isCaseOf"; - - + /** - * Parses <aas:conceptDescriptions> and builds the IConceptDescription objects from it + * Parses <aas:conceptDescriptions> and builds the IConceptDescription + * objects from it * - * @param xmlObject a Map containing the content of the XML tag <aas:conceptDescriptions> + * @param xmlObject + * a Map containing the content of the XML tag + * <aas:conceptDescriptions> * @return a List of IConceptDescription objects parsed form the given XML Map */ public static List parseConceptDescriptions(Map xmlObject) { - - List> xmlConceptDescriptionList = XMLHelper.getList(xmlObject.get(CONCEPT_DESCRIPTION)); + if (xmlObject == null) { + return Collections.emptyList(); + } + List conceptDescriptions = new ArrayList<>(); - + List> xmlConceptDescriptionList = XMLHelper.getList(xmlObject.get(CONCEPT_DESCRIPTION)); + for (Map xmlConceptDescription : xmlConceptDescriptionList) { ConceptDescription conceptDescription = new ConceptDescription(); - + IdentifiableXMLConverter.populateIdentifiable(xmlConceptDescription, Identifiable.createAsFacadeNonStrict(conceptDescription, KeyElements.CONCEPTDESCRIPTION)); HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlConceptDescription, HasDataSpecification.createAsFacade(conceptDescription)); - + Collection handleIsCaseOf = parseIsCaseOfRefs(xmlConceptDescription); conceptDescription.setIsCaseOf(handleIsCaseOf); - + conceptDescriptions.add(conceptDescription); } - + return conceptDescriptions; } - /** * Parses <aas:isCaseOf> and builds a Reference object from it * - * @param xmlObject a Map containing the XML tag <aas:isCaseOf> + * @param xmlObject + * a Map containing the XML tag <aas:isCaseOf> * @return a Reference object parsed form the given XML Map */ private static Collection parseIsCaseOfRefs(Map xmlObject) { @@ -83,51 +105,54 @@ private static Collection parseIsCaseOfRefs(Map xmlOb } return references; } - - - - + /** - * Builds <aas:conceptDescriptions> from a given Collection of IConceptDescription objects + * Builds <aas:conceptDescriptions> from a given Collection of + * IConceptDescription objects * - * @param document the XML document - * @param conceptDescriptions a Collection of IConceptDescription objects to build the XML for - * @return the <aas:conceptDescriptions> XML tag for the given IConceptDescription objects + * @param document + * the XML document + * @param conceptDescriptions + * a Collection of IConceptDescription objects to build the XML for + * @return the <aas:conceptDescriptions> XML tag for the given + * IConceptDescription objects */ public static Element buildConceptDescriptionsXML(Document document, Collection conceptDescriptions) { Element root = document.createElement(CONCEPT_DESCRIPTIONS); - + List xmlConceptDescriptionList = new ArrayList(); - for(IConceptDescription conceptDescription: conceptDescriptions) { + for (IConceptDescription conceptDescription : conceptDescriptions) { Element conceptDescriptionRoot = document.createElement(CONCEPT_DESCRIPTION); IdentifiableXMLConverter.populateIdentifiableXML(document, conceptDescriptionRoot, conceptDescription); HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, conceptDescriptionRoot, conceptDescription); buildIsCaseOf(document, conceptDescriptionRoot, conceptDescription); xmlConceptDescriptionList.add(conceptDescriptionRoot); - + } - - for(Element element: xmlConceptDescriptionList) { + + for (Element element : xmlConceptDescriptionList) { root.appendChild(element); } return root; } - - + /** * Builds <aas:isCaseOf> from a given IConceptDescription object * - * @param document the XML document - * @param xmlConceptDescription the XML tag to be populated - * @param conceptDescription the IConceptDescription object to build the XML for + * @param document + * the XML document + * @param xmlConceptDescription + * the XML tag to be populated + * @param conceptDescription + * the IConceptDescription object to build the XML for */ - private static void buildIsCaseOf(Document document, Element xmlConceptDescription, IConceptDescription conceptDescription) { + private static void buildIsCaseOf(Document document, Element xmlConceptDescription, IConceptDescription conceptDescription) { Collection references = conceptDescription.getIsCaseOf(); Element xmlIsCaseOf = document.createElement(IS_CASE_OF); Element keysElement = ReferenceXMLConverter.buildReferencesXML(document, references); - if(keysElement != null) { + if (keysElement != null) { xmlIsCaseOf.appendChild(keysElement); xmlConceptDescription.appendChild(xmlIsCaseOf); } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java index 9347f8eb..9489d3a5 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/SubmodelXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters; @@ -34,7 +49,8 @@ import org.w3c.dom.Element; /** - * Handles the conversion between ISubmodel objects and the XML tag <aas:submodels> in both directions + * Handles the conversion between ISubmodel objects and the XML tag + * <aas:submodels> in both directions * * @author conradi * @@ -43,52 +59,52 @@ public class SubmodelXMLConverter { public static final String SUBMODELS = "aas:submodels"; public static final String SUBMODEL = "aas:submodel"; - + /** * Parses <aas:submodels> and builds the Submodel objects from it * - * @param xmlObject a Map containing the content of the XML tag <aas:submodels> + * @param xmlObject + * a Map containing the content of the XML tag <aas:submodels> * @return a List of ISubmodel objects parsed form the given XML Map */ public static List parseSubmodels(Map xmlObject) { List> xmlSubmodels = XMLHelper.getList(xmlObject.get(SUBMODEL)); List submodels = new ArrayList<>(); - + for (Map xmlSubmodel : xmlSubmodels) { Submodel submodel = new Submodel(); - + IdentifiableXMLConverter.populateIdentifiable(xmlSubmodel, Identifiable.createAsFacadeNonStrict(submodel, KeyElements.SUBMODEL)); HasSemanticsXMLConverter.populateHasSemantics(xmlSubmodel, HasSemantics.createAsFacade(submodel)); HasDataSpecificationXMLConverter.populateHasDataSpecification(xmlSubmodel, HasDataSpecification.createAsFacade(submodel)); QualifiableXMLConverter.populateQualifiable(xmlSubmodel, Qualifiable.createAsFacade(submodel)); HasKindXMLConverter.populateHasKind(xmlSubmodel, HasKind.createAsFacade(submodel)); - + List submodelElements = SubmodelElementXMLConverter.parseSubmodelElements(xmlSubmodel); - + for (ISubmodelElement submdoElement : submodelElements) { submodel.addSubmodelElement(submdoElement); } - + submodels.add(submodel); } return submodels; } - - - - + /** * Builds <aas:submodels> from a given Collection of ISubmodel objects * - * @param document the XML document - * @param subModels a Collection of ISubmodel objects to build the XML for + * @param document + * the XML document + * @param subModels + * a Collection of ISubmodel objects to build the XML for * @return the <aas:submodels> XML tag for the given ISubmodel objects */ public static Element buildSubmodelsXML(Document document, Collection subModels) { Element root = document.createElement(SUBMODELS); - + List xmlSubmodelList = new ArrayList<>(); - for(ISubmodel subModel: subModels) { + for (ISubmodel subModel : subModels) { Element subModelRoot = document.createElement(SUBMODEL); IdentifiableXMLConverter.populateIdentifiableXML(document, subModelRoot, subModel); @@ -96,16 +112,16 @@ public static Element buildSubmodelsXML(Document document, Collection HasSemanticsXMLConverter.populateHasSemanticsXML(document, subModelRoot, subModel); QualifiableXMLConverter.populateQualifiableXML(document, subModelRoot, subModel); HasDataSpecificationXMLConverter.populateHasDataSpecificationXML(document, subModelRoot, subModel); - + Collection submodelElements = (Collection) subModel.getSubmodelElements().values(); Element xmlSubmodelElements = SubmodelElementXMLConverter.buildSubmodelElementsXML(document, submodelElements); subModelRoot.appendChild(xmlSubmodelElements); - + xmlSubmodelList.add(subModelRoot); } - - for(Element element: xmlSubmodelList) { + + for (Element element : xmlSubmodelList) { root.appendChild(element); } return root; diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java index d0798261..23661f18 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasDataSpecificationXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier; @@ -31,7 +46,8 @@ import org.w3c.dom.Element; /** - * Handles the conversion between an IHasDataSpecification object and the XML tag
+ * Handles the conversion between an IHasDataSpecification object and the XML + * tag
* <aas:embeddedDataSpecification> in both directions * * @author conradi, espen @@ -44,17 +60,22 @@ public class HasDataSpecificationXMLConverter { public static final String DATA_SPECIFICATION_CONTENT = "aas:dataSpecificationContent"; /** - * Populates a given IHasDataSpecification object with the data form the given XML + * Populates a given IHasDataSpecification object with the data form the given + * XML * - * @param xmlObject the XML map containing the <aas:embeddedDataSpecification> tag - * @param hasDataSpecification the IHasDataSpecification object to be populated -treated as Map here- + * @param xmlObject + * the XML map containing the <aas:embeddedDataSpecification> + * tag + * @param hasDataSpecification + * the IHasDataSpecification object to be populated -treated as Map + * here- */ - public static void populateHasDataSpecification(Map xmlObject, - HasDataSpecification hasDataSpecification) { - if (xmlObject == null || hasDataSpecification == null) return; - + public static void populateHasDataSpecification(Map xmlObject, HasDataSpecification hasDataSpecification) { + if (xmlObject == null || hasDataSpecification == null) + return; + Object xmlDataSpecObj = xmlObject.get(EMBEDDED_DATA_SPECIFICATION); - if (xmlDataSpecObj != null ) { + if (xmlDataSpecObj != null) { List embeddedSpecList = new ArrayList<>(); List> xmlSpecList = XMLHelper.getList(xmlDataSpecObj); for (Map xmlSpec : xmlSpecList) { @@ -66,19 +87,22 @@ public static void populateHasDataSpecification(Map xmlObject, spec.setContent((DataSpecificationIEC61360Content) content); embeddedSpecList.add(spec); } - hasDataSpecification.setEmbeddedDataSpecifications(embeddedSpecList); + hasDataSpecification.setEmbeddedDataSpecifications(embeddedSpecList); } - // Note: DataSpecificationReferences are not serialized in XML - // "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0" could always be added here, + // "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0" + // could always be added here, // as the serialization only supports this template } - + /** - * Parses a Reference Object from the <aas:embeddedDataSpecification> XML tag + * Parses a Reference Object from the <aas:embeddedDataSpecification> XML + * tag * - * @param xmlObject the XML map containing the <aas:embeddedDataSpecification> XML tag + * @param xmlObject + * the XML map containing the <aas:embeddedDataSpecification> + * XML tag * @return the parsed Reference object */ @SuppressWarnings("unchecked") @@ -91,9 +115,12 @@ private static Reference parseReference(Map xmlSpec) { } /** - * Parses a DataSpecificationContent Object from the <aas:embeddedDataSpecification> XML tag + * Parses a DataSpecificationContent Object from the + * <aas:embeddedDataSpecification> XML tag * - * @param xmlObject the XML map containing the <aas:embeddedDataSpecification> XML tag + * @param xmlObject + * the XML map containing the <aas:embeddedDataSpecification> + * XML tag * @return the parsed Content object */ @SuppressWarnings("unchecked") @@ -113,12 +140,16 @@ private static IDataSpecificationContent parseContent(Map xmlSpe } /** - * Populates a given XML map with the data from a given IHasDataSpecification object
+ * Populates a given XML map with the data from a given IHasDataSpecification + * object
* Creates the <aas:embeddedDataSpecification> tag in the given root * - * @param document the XML document - * @param root the XML root Element to be populated - * @param hasDataSpecification the IHasDataSpecification object to be converted to XML + * @param document + * the XML document + * @param root + * the XML root Element to be populated + * @param hasDataSpecification + * the IHasDataSpecification object to be converted to XML */ @SuppressWarnings("unchecked") public static void populateHasDataSpecificationXML(Document document, Element root, IHasDataSpecification hasDataSpecification) { @@ -135,8 +166,7 @@ public static void populateHasDataSpecificationXML(Document document, Element ro // Assume its an IEC61360Content (only type of content supported) Element dataSpecIEC61360Root = document.createElement(DATA_SPECIFICATION_IEC61360); dataSpecContentRoot.appendChild(dataSpecIEC61360Root); - populateContent(document, dataSpecIEC61360Root, - DataSpecificationIEC61360Content.createAsFacade((Map) content)); + populateContent(document, dataSpecIEC61360Root, DataSpecificationIEC61360Content.createAsFacade((Map) content)); } // Add template reference IReference dataSpecTemplate = spec.getDataSpecificationTemplate(); @@ -146,19 +176,22 @@ public static void populateHasDataSpecificationXML(Document document, Element ro root.appendChild(embeddedDataSpecRoot); } } - /** - * Populates a DataSpecificationContent XML from the IDataSpecificationContent object + * Populates a DataSpecificationContent XML from the IDataSpecificationContent + * object * - * @param document the XML document - * @param contentRoot the XML root Element to be populated - * @param content the IDataSpecification object to be converted to XML + * @param document + * the XML document + * @param contentRoot + * the XML root Element to be populated + * @param content + * the IDataSpecification object to be converted to XML */ private static void populateContent(Document document, Element contentRoot, IDataSpecificationContent content) { // Currently, the XML-Schema only supports this data specification - - // for the future, this method will also need to support additionaly data specification templates - DataSpecificationIEC61360XMLConverter.populateIEC61360ContentXML(document, contentRoot, - (IDataSpecificationIEC61360Content) content); + // for the future, this method will also need to support additionaly data + // specification templates + DataSpecificationIEC61360XMLConverter.populateIEC61360ContentXML(document, contentRoot, (IDataSpecificationIEC61360Content) content); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java index 48438372..3dd6fad0 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/HasSemanticsXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier; @@ -19,7 +34,8 @@ import org.w3c.dom.Element; /** - * Handles the conversion between an IHasSemantics object and the XML tag <aas:semanticId> in both directions + * Handles the conversion between an IHasSemantics object and the XML tag + * <aas:semanticId> in both directions * * @author conradi * @@ -27,13 +43,14 @@ public class HasSemanticsXMLConverter { public static final String SEMANTIC_ID = "aas:semanticId"; - /** * Populates a given HasSemantics object with the data form the given XML * - * @param xmlObject the XML map containing the <aas:semanticId> tag - * @param hasSemantics the HasSemantics object to be populated + * @param xmlObject + * the XML map containing the <aas:semanticId> tag + * @param hasSemantics + * the HasSemantics object to be populated */ @SuppressWarnings("unchecked") public static void populateHasSemantics(Map xmlObject, HasSemantics hasSemantics) { @@ -42,23 +59,23 @@ public static void populateHasSemantics(Map xmlObject, HasSemant hasSemantics.setSemanticId(ReferenceXMLConverter.parseReference(xmlSemanticIDObj)); } } - - - - + /** * Populates a given XML map with the data from a given IHasSemantics object
* Creates the <aas:semanticId> tag in the given root * - * @param document the XML document - * @param root the XML root Element to be populated - * @param hasSemantics the IHasSemantics object to be converted to XML + * @param document + * the XML document + * @param root + * the XML root Element to be populated + * @param hasSemantics + * the IHasSemantics object to be converted to XML */ public static void populateHasSemanticsXML(Document document, Element root, IHasSemantics hasSemantics) { IReference semanticId = hasSemantics.getSemanticId(); - if(semanticId != null) { + if (semanticId != null) { Element semanticIdRoot = document.createElement(SEMANTIC_ID); - semanticIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, semanticId)); + semanticIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, semanticId)); root.appendChild(semanticIdRoot); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java index b16ac0d9..16f533a1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/IdentifiableXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier; @@ -38,18 +53,20 @@ public class IdentifiableXMLConverter { public static final String REVISION = "aas:revision"; public static final String IDENTIFICATION = "aas:identification"; public static final String IDTYPE = "idType"; - - + /** * Populates a given Identifiable object with the data form the given XML * - * @param xmlObject the XML map containing the <aas:administration> and <aas:identification> tags - * @param identifiable the Identifiable object to be populated + * @param xmlObject + * the XML map containing the <aas:administration> and + * <aas:identification> tags + * @param identifiable + * the Identifiable object to be populated */ @SuppressWarnings("unchecked") public static void populateIdentifiable(Map xmlObject, Identifiable identifiable) { ReferableXMLConverter.populateReferable(xmlObject, identifiable); - + Map identierFromXML = (Map) xmlObject.get(IDENTIFICATION); if (identierFromXML == null) { throw createInvalidIdentifierException(xmlObject); @@ -60,92 +77,94 @@ public static void populateIdentifiable(Map xmlObject, Identifia // Warns without exception to enable parsing external aasx-files without id logger.warn("Invalid XML of Identifiable. No valid identification is present. " + xmlObject.toString()); } - + if (Strings.isNullOrEmpty(idType)) { // Warns without exception to enable parsing external aasx-files without idType logger.warn("Invalid XML of Identifiable. empty identifierType changed to default identifierType Custom. " + xmlObject.toString()); idType = IdentifierType.CUSTOM.toString(); } - + // Enables parsing external aasx-files with URI instead of IRI if (idType.equalsIgnoreCase("URI")) { idType = IdentifierType.IRI.toString(); } - + identifiable.setIdentification(IdentifierType.fromString(idType), id); Map administrationFromXML = (Map) xmlObject.get(ADMINISTRATION); - if(administrationFromXML != null) { + if (administrationFromXML != null) { String version = XMLHelper.getString(administrationFromXML.get(VERSION)); String revision = XMLHelper.getString(administrationFromXML.get(REVISION)); - + // Enables parsing external aasx-files with revision and empty version if (!Strings.isNullOrEmpty(revision) && Strings.isNullOrEmpty(version)) { version = "0.0.1"; } - + identifiable.setAdministration(new AdministrativeInformation(version, revision)); } } - - - /** * Populates a given XML map with the data from a given IIdentifiable object
- * Creates the <aas:administration> and <aas:identification> tags in the given root + * Creates the <aas:administration> and <aas:identification> tags in + * the given root * - * @param document the XML document - * @param root the XML root Element to be populated - * @param identifiable the IIdentifiable object to be converted to XML + * @param document + * the XML document + * @param root + * the XML root Element to be populated + * @param identifiable + * the IIdentifiable object to be converted to XML */ public static void populateIdentifiableXML(Document document, Element root, IIdentifiable identifiable) { ReferableXMLConverter.populateReferableXML(document, root, identifiable); - - //Build the identification if present + + // Build the identification if present if (identifiable.getIdentification() != null) { String id = identifiable.getIdentification().getId(); Element identificationRoot = document.createElement(IDENTIFICATION); identificationRoot.appendChild(document.createTextNode(id)); - if(identifiable.getIdentification().getIdType() != null) { + if (identifiable.getIdentification().getIdType() != null) { IdentifierType idType = identifiable.getIdentification().getIdType(); identificationRoot.setAttribute(IDTYPE, idType.toString()); } root.appendChild(identificationRoot); } - - //Build the administration if present - if(identifiable.getAdministration() != null) { + + // Build the administration if present + if (identifiable.getAdministration() != null) { Element version = null; Element revision = null; - + String versionString = identifiable.getAdministration().getVersion(); - if(versionString != null && !versionString.isEmpty()) { + if (versionString != null && !versionString.isEmpty()) { version = document.createElement(VERSION); version.appendChild(document.createTextNode(versionString)); - + } - + String revisionString = identifiable.getAdministration().getRevision(); - if(revisionString != null && !revisionString.isEmpty()) { + if (revisionString != null && !revisionString.isEmpty()) { revision = document.createElement(REVISION); revision.appendChild(document.createTextNode(revisionString)); } - - //If one at least one f the elements exists, create the aas:administration element - if(version != null || revision != null) { + + // If one at least one f the elements exists, create the aas:administration + // element + if (version != null || revision != null) { Element administrationRoot = document.createElement(ADMINISTRATION); - if(version != null) { + if (version != null) { administrationRoot.appendChild(version); } - if(revision != null) { + if (revision != null) { administrationRoot.appendChild(revision); } root.appendChild(administrationRoot); } - } + } } - + private static RuntimeException createInvalidIdentifierException(Map xmlObject) { return new RuntimeException("Invalid XML of Identifiable. No valid identification is present. " + xmlObject.toString()); } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java index 3fc5461e..325fc5fb 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/LangStringsXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier; @@ -20,21 +35,22 @@ import org.w3c.dom.Element; /** - * Handles the conversion between a LangStrings object and the XML tag <aas:langString> in both directions + * Handles the conversion between a LangStrings object and the XML tag + * <aas:langString> in both directions * * @author conradi * */ public class LangStringsXMLConverter { - + public static final String LANG = "lang"; public static final String LANG_STRING = "aas:langString"; - - + /** * Parses the LangStrings object from XML * - * @param xmlObject the XML map containing the <aas:langString> tags + * @param xmlObject + * the XML map containing the <aas:langString> tags * @return the parsed LangStrings object */ public static LangStrings parseLangStrings(Map xmlObject) { @@ -42,10 +58,13 @@ public static LangStrings parseLangStrings(Map xmlObject) { } /** - * Parses the LangStrings object from XML/String with a custom lang string xml tag + * Parses the LangStrings object from XML/String with a custom lang string xml + * tag * - * @param obj the LangString objects or a single string - * @param tagName the custom <*langString*> tagName + * @param obj + * the LangString objects or a single string + * @param tagName + * the custom <*langString*> tagName * @return the parsed LangStrings object */ @SuppressWarnings("unchecked") @@ -58,27 +77,32 @@ public static LangStrings parseLangStrings(Object obj, String tagName) { return parseLangStringsFromString((String) obj); } } - + /** * Parses the LangStrings object from String description - * @param str given description + * + * @param str + * given description * @return parsed LangStrings object */ private static LangStrings parseLangStringsFromString(String str) { LangString langString = new LangString("EN", str); return new LangStrings(langString); } - + /** * Parses the LangStrings object from XML with a custom lang string xml tag - * @param xmlObject given XML object - * @param tagName the custom <*langString*> tagName + * + * @param xmlObject + * given XML object + * @param tagName + * the custom <*langString*> tagName * @return the parsed LangStrings object */ private static LangStrings parseLangStringsFromMap(Map xmlObject, String tagName) { LangStrings langStrings = new LangStrings(); - - if(xmlObject != null) { + + if (xmlObject != null) { List> xmlLangStrings = XMLHelper.getList(xmlObject.get(tagName)); for (Map xmlLangString : xmlLangStrings) { String text = XMLHelper.getString(xmlLangString.get(XMLHelper.TEXT)); @@ -88,16 +112,17 @@ private static LangStrings parseLangStringsFromMap(Map xmlObject } return langStrings; } - - - - + /** * Builds XML from a given LangStrings object * - * @param document the XML document - * @param root the root Element where the <aas:langString> tags should be in - * @param langStrings the LangStrings object to be converted to XML + * @param document + * the XML document + * @param root + * the root Element where the <aas:langString> tags should be + * in + * @param langStrings + * the LangStrings object to be converted to XML */ public static void buildLangStringsXML(Document document, Element root, LangStrings langStrings) { buildLangStringsXML(document, root, LANG_STRING, langStrings); @@ -106,21 +131,25 @@ public static void buildLangStringsXML(Document document, Element root, LangStri /** * Builds XML from a given LangStrings object with a custom langString tagName * - * @param document the XML document - * @param root the root Element where the <langString> tags should be in - * @param tagName the custom <*langString*> tagName - * @param langStrings the LangStrings object to be converted to XML + * @param document + * the XML document + * @param root + * the root Element where the <langString> tags should be in + * @param tagName + * the custom <*langString*> tagName + * @param langStrings + * the LangStrings object to be converted to XML */ public static void buildLangStringsXML(Document document, Element root, String tagName, LangStrings langStrings) { if (langStrings != null) { Set languages = langStrings.getLanguages(); - for(String language: languages) { + for (String language : languages) { Element langStringRoot = document.createElement(tagName); String text = langStrings.get(language); langStringRoot.setAttribute(LANG, language); langStringRoot.appendChild(document.createTextNode(text)); - + root.appendChild(langStringRoot); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java index a7def922..666b52b7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/ReferableXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier; @@ -27,14 +42,15 @@ /** * Handles the conversion between an IReferable object and the XML tags
- * <aas:idShort>, <aas:category>, <aas:parent> and <aas:description> in both directions + * <aas:idShort>, <aas:category>, <aas:parent> and + * <aas:description> in both directions * * @author conradi * */ public class ReferableXMLConverter { private static final Logger logger = LoggerFactory.getLogger(AdministrativeInformation.class); - + public static final String ID_SHORT = "aas:idShort"; public static final String CATEGORY = "aas:category"; public static final String PARENT = "aas:parent"; @@ -43,23 +59,25 @@ public class ReferableXMLConverter { /** * Populates a given Referable object with the data form the given XML * - * @param xmlObject the XML map containing the tag relevant for IReferable - * @param referable the Referable object to be populated + * @param xmlObject + * the XML map containing the tag relevant for IReferable + * @param referable + * the Referable object to be populated */ @SuppressWarnings("unchecked") public static void populateReferable(Map xmlObject, Referable referable) { String idShort = XMLHelper.getString(xmlObject.get(ID_SHORT)); String category = XMLHelper.getString(xmlObject.get(CATEGORY)); - + LangStrings description = parseDescription(xmlObject); - + Reference parent = ReferenceXMLConverter.parseReference((Map) xmlObject.get(PARENT)); if (Strings.isNullOrEmpty(idShort)) { // Warning without exception for empty idshort for parsing external aasx-files logger.warn("Invalid XML of Referable. No valid idShort is present. " + xmlObject.toString()); } referable.setIdShort(idShort); - + if (!Strings.isNullOrEmpty(category)) { referable.setCategory(category); } @@ -70,35 +88,34 @@ public static void populateReferable(Map xmlObject, Referable re referable.setParent(parent); } } - /** * Parses the <aas:description> tag * - * @param xmlObject the XML map containing the <aas:description> tag + * @param xmlObject + * the XML map containing the <aas:description> tag * @return a LangStrings Object parsed form the XML */ private static LangStrings parseDescription(Map xmlObject) { Object descObj = xmlObject.get(DESCRIPTION); - + if (descObj == null) { return null; } - + return LangStringsXMLConverter.parseLangStrings(descObj, LangStringsXMLConverter.LANG_STRING); } - - - - - + /** * Populates a given XML map with the data from a given IReferable object
* Creates the relevant tags in the given root * - * @param document the XML document - * @param root the XML root Element to be populated - * @param referable the IReferable object to be converted to XML + * @param document + * the XML document + * @param root + * the XML root Element to be populated + * @param referable + * the IReferable object to be converted to XML */ public static void populateReferableXML(Document document, Element root, IReferable referable) { if (referable.getIdShort() != null) { @@ -106,26 +123,26 @@ public static void populateReferableXML(Document document, Element root, IRefera idShortElem.appendChild(document.createTextNode(referable.getIdShort())); root.appendChild(idShortElem); } - + if (referable.getCategory() != null) { Element categoryElem = document.createElement(CATEGORY); categoryElem.appendChild(document.createTextNode(referable.getCategory())); root.appendChild(categoryElem); } - - if(referable.getDescription() != null && !referable.getDescription().isEmpty()) { + + if (referable.getDescription() != null && !referable.getDescription().isEmpty()) { Element descriptionRoot = document.createElement(DESCRIPTION); LangStringsXMLConverter.buildLangStringsXML(document, descriptionRoot, referable.getDescription()); root.appendChild(descriptionRoot); } - - if(referable.getParent() != null) { + + if (referable.getParent() != null) { Element xmlParent = ReferenceXMLConverter.buildReferenceXML(document, referable.getParent()); Element parentElem = document.createElement(PARENT); parentElem.appendChild(xmlParent); root.appendChild(parentElem); } - - } + + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java index d9e850dd..f8f1e99e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/haskind/HasKindXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.haskind; @@ -21,21 +36,23 @@ import com.google.common.base.Strings; /** - * Handles the conversion between an IHasKind object and the XML tag <aas:kind> in both directions + * Handles the conversion between an IHasKind object and the XML tag + * <aas:kind> in both directions * * @author conradi * */ public class HasKindXMLConverter { - + public static final String KIND = "aas:kind"; - - + /** * Populates a given HasKind object with the data form the given XML * - * @param xmlObject the XML map containing the <aas:kind> tag - * @param hasKind the HasKind object to be populated + * @param xmlObject + * the XML map containing the <aas:kind> tag + * @param hasKind + * the HasKind object to be populated */ public static void populateHasKind(Map xmlObject, HasKind hasKind) { String hasKindValue = XMLHelper.getString(xmlObject.get(KIND)); @@ -44,23 +61,25 @@ public static void populateHasKind(Map xmlObject, HasKind hasKin if (hasKindValue.equals("Type")) { hasKindValue = ModelingKind.TEMPLATE.toString(); } - hasKind.setModelingKind(ModelingKind.fromString(hasKindValue)); + hasKind.setKind(ModelingKind.fromString(hasKindValue)); } } - - + /** * Populates a given XML map with the data from a given IHasKind object
* Creates the <aas:kind> tag in the given root * - * @param document the XML document - * @param root the XML root Element to be populated - * @param hasKind the IHasKind object to be converted to XML + * @param document + * the XML document + * @param root + * the XML root Element to be populated + * @param hasKind + * the IHasKind object to be converted to XML */ public static void populateHasKindXML(Document document, Element root, IHasKind hasKind) { - if(hasKind.getModelingKind() != null) { + if (hasKind.getKind() != null) { Element kindRoot = document.createElement(KIND); - kindRoot.appendChild(document.createTextNode(hasKind.getModelingKind().toString())); + kindRoot.appendChild(document.createTextNode(hasKind.getKind().toString())); root.appendChild(kindRoot); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java index 50f680de..5df7955e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/qualifier/qualifiable/QualifiableXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.qualifiable; @@ -33,13 +48,14 @@ import org.w3c.dom.Element; /** - * Handles the conversion between an IQualifiable object and the XML tag <aas:qualifier> in both directions + * Handles the conversion between an IQualifiable object and the XML tag + * <aas:qualifier> in both directions * * @author conradi * */ public class QualifiableXMLConverter { - + private static Logger logger = LoggerFactory.getLogger(QualifiableXMLConverter.class); public static final String QUALIFIER = "aas:qualifier"; @@ -50,13 +66,14 @@ public class QualifiableXMLConverter { public static final String VALUE = "aas:value"; public static final String VALUE_TYPE = "aas:valueType"; public static final String VALUE_ID = "aas:valueId"; - /** * Populates a given Qualifiable object with the data form the given XML * - * @param xmlObject the XML map containing the <aas:qualifier> tag - * @param qualifiable the Qualifiable object to be populated + * @param xmlObject + * the XML map containing the <aas:qualifier> tag + * @param qualifiable + * the Qualifiable object to be populated */ @SuppressWarnings("unchecked") public static void populateQualifiable(Map xmlObject, Qualifiable qualifiable) { @@ -65,55 +82,56 @@ public static void populateQualifiable(Map xmlObject, Qualifiabl qualifiable.setQualifiers(parseConstraints(qualifierObj)); } } - - + /** * Parses the IConstraint objects form XML * - * @param xmlConstraints the XML map containing the <aas:formula> and <aas:qualifier> tags + * @param xmlConstraints + * the XML map containing the <aas:formula> and + * <aas:qualifier> tags * @return the Set of IConstraint objects parsed */ private static Collection parseConstraints(Map xmlConstraints) { Collection constraints = new HashSet<>(); - - if(xmlConstraints == null) return constraints; - + + if (xmlConstraints == null) + return constraints; + List> xmlQualifier = XMLHelper.getList(xmlConstraints.get(QUALIFIER)); xmlQualifier.stream().map(QualifiableXMLConverter::parseQualifier).forEach(constraints::add); - List> xmlFormula = XMLHelper.getList(xmlConstraints.get(FORMULA)); xmlFormula.stream().map(QualifiableXMLConverter::parseFormula).forEach(constraints::add); - - + return constraints; } - - + /** * Parses a Formula object form XML * - * @param xmlFormula the XML map containing the content of the <aas:formula> tag + * @param xmlFormula + * the XML map containing the content of the <aas:formula> tag * @return the parsed Formula object */ @SuppressWarnings("unchecked") private static Formula parseFormula(Map xmlFormula) { Map dependsOnObj = (Map) xmlFormula.get(DEPENDS_ON_REFS); Collection referenceList = new HashSet<>(); - + List> xmlReferenceList = XMLHelper.getList(dependsOnObj.get(REFERENCE)); for (Map xmlReference : xmlReferenceList) { referenceList.add(ReferenceXMLConverter.parseReference(xmlReference)); } - + return new Formula(referenceList); } - - + /** * Parses a Qualifier object form XML * - * @param xmlQualifier the XML map containing the content of the <aas:qualifier> tag + * @param xmlQualifier + * the XML map containing the content of the <aas:qualifier> + * tag * @return the parsed Qualifier object */ @SuppressWarnings("unchecked") @@ -122,12 +140,12 @@ private static Qualifier parseQualifier(Map xmlQualifier) { String value = XMLHelper.getString(xmlQualifier.get(VALUE)); String valueType = XMLHelper.getString(xmlQualifier.get(VALUE_TYPE)); Map qualifierValueIdObj = (Map) xmlQualifier.get(VALUE_ID); - + Reference ref = ReferenceXMLConverter.parseReference(qualifierValueIdObj); - + Qualifier qualifier = new Qualifier(); HasSemanticsXMLConverter.populateHasSemantics(xmlQualifier, HasSemantics.createAsFacade(qualifier)); - + qualifier.setType(type); qualifier.setValue(value); qualifier.setValueId(ref); @@ -140,33 +158,32 @@ private static Qualifier parseQualifier(Map xmlQualifier) { return qualifier; } - - - /** * Populates a given XML map with the data from a given IQualifiable object
* Creates the <aas:qualifier> tag in the given root * - * @param document the XML document - * @param root the XML root Element to be populated - * @param qualifiable the IQualifiable object to be converted to XML + * @param document + * the XML document + * @param root + * the XML root Element to be populated + * @param qualifiable + * the IQualifiable object to be converted to XML */ public static void populateQualifiableXML(Document document, Element root, IQualifiable qualifiable) { - if(qualifiable.getQualifiers() == null || qualifiable.getQualifiers().size() == 0) return; - - + if (qualifiable.getQualifiers() == null || qualifiable.getQualifiers().size() == 0) + return; + Collection constraints = qualifiable.getQualifiers(); - + Element qualifierRoot = document.createElement(QUALIFIER); - + for (IConstraint constraint : constraints) { qualifierRoot.appendChild(buildQualifiersXML(document, constraint)); } root.appendChild(qualifierRoot); } - - + /** * Builds XML from a given IConstraint objcet * @@ -178,22 +195,23 @@ public static void populateQualifiableXML(Document document, Element root, IQual */ private static Element buildQualifiersXML(Document document, IConstraint constraint) { - //the constraints can be IFormula or IQualifier - if(constraint instanceof IFormula) { + // the constraints can be IFormula or IQualifier + if (constraint instanceof IFormula) { return buildFormulaXML(document, (IFormula) constraint); - } else if(constraint instanceof IQualifier) { + } else if (constraint instanceof IQualifier) { return buildQualifierXML(document, (IQualifier) constraint); } - + throw new RuntimeException("Unknown qualifier type " + constraint); } - - + /** * Builds XML from a given IFormula object * - * @param document the XML document - * @param formula the IFormula to be converted to XML + * @param document + * the XML document + * @param formula + * the IFormula to be converted to XML * @return the <aas:formula> XML tag build from the IFormula */ private static Element buildFormulaXML(Document document, IFormula formula) { @@ -206,13 +224,14 @@ private static Element buildFormulaXML(Document document, IFormula formula) { formulaRoot.appendChild(dependsOnRoot); return formulaRoot; } - - + /** * Builds XML from a given IQualifier object * - * @param document the XML document - * @param qualifier the IQualifier to be converted to XML + * @param document + * the XML document + * @param qualifier + * the IQualifier to be converted to XML * @return the <aas:qualifier> XML tag build from the IQualifier */ private static Element buildQualifierXML(Document document, IQualifier qualifier) { @@ -221,10 +240,10 @@ private static Element buildQualifierXML(Document document, IQualifier qualifier String value = XMLHelper.getString(qualifier.getValue()); String valueType = qualifier.getValueType().toString(); Element qualifierRoot = document.createElement(QUALIFIER); - + Element qualifierValueId = document.createElement(VALUE_ID); Element keysElement = ReferenceXMLConverter.buildReferenceXML(document, qualId); - if(keysElement != null) { + if (keysElement != null) { qualifierValueId.appendChild(keysElement); } qualifierRoot.appendChild(qualifierValueId); @@ -232,17 +251,17 @@ private static Element buildQualifierXML(Document document, IQualifier qualifier Element qualifierValue = document.createElement(VALUE); qualifierValue.appendChild(document.createTextNode(value)); qualifierRoot.appendChild(qualifierValue); - + Element qualifierType = document.createElement(TYPE); qualifierType.appendChild(document.createTextNode(type)); qualifierRoot.appendChild(qualifierType); - + Element qualifierValueType = document.createElement(VALUE_TYPE); qualifierValueType.appendChild(document.createTextNode(valueType)); qualifierRoot.appendChild(qualifierValueType); - + HasSemanticsXMLConverter.populateHasSemanticsXML(document, qualifierRoot, qualifier); - + return qualifierRoot; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java index b0c972f9..71418223 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/reference/ReferenceXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.reference; @@ -28,7 +43,8 @@ import com.google.common.base.Strings; /** - * Handles the conversion between an IReference object and the XML tag <aas:keys> in both directions + * Handles the conversion between an IReference object and the XML tag + * <aas:keys> in both directions * * @author conradi, espen * @@ -39,12 +55,12 @@ public class ReferenceXMLConverter { public static final String IDTYPE = "idType"; public static final String KEYS = "aas:keys"; public static final String KEY = "aas:key"; - - + /** * Parses the Reference object from XML * - * @param xmlObject the XML map containing the <aas:keys> tag + * @param xmlObject + * the XML map containing the <aas:keys> tag * @return the parsed Reference object */ public static Reference parseReference(Map xmlObject) { @@ -54,13 +70,16 @@ public static Reference parseReference(Map xmlObject) { reference.setKeys(parseKeys(xmlObject, KEYS, KEY)); return reference; } - + /** * Parses the Reference object from XML with a custom keys tagName * - * @param xmlObject the XML map containing the <keys> tag - * @param keysTagName the custom <*keys*> tagName - * @param keyTagName the custom <*key*> tagName + * @param xmlObject + * the XML map containing the <keys> tag + * @param keysTagName + * the custom <*keys*> tagName + * @param keyTagName + * the custom <*key*> tagName * @return the parsed Reference object */ public static Reference parseReference(Map xmlObject, String keysTagName, String keyTagName) { @@ -70,36 +89,41 @@ public static Reference parseReference(Map xmlObject, String key reference.setKeys(parseKeys(xmlObject, keysTagName, keyTagName)); return reference; } - + /** * Parses the Key objects from XML * - * @param xmlObject the XML map containing the <aas:keys> tag - * @param keysTagName the custom <*keys*> tagName - * @param keyTagName the custom <*key*> tagName + * @param xmlObject + * the XML map containing the <aas:keys> tag + * @param keysTagName + * the custom <*keys*> tagName + * @param keyTagName + * the custom <*key*> tagName * @return a List of the parsed Key objects */ @SuppressWarnings("unchecked") private static List parseKeys(Map xmlObject, String keysTagName, String keyTagName) { List keyList = new ArrayList<>(); - if(xmlObject == null) return keyList; - + if (xmlObject == null) + return keyList; + Map keysObject = (Map) xmlObject.get(keysTagName); - if(keysObject == null) return keyList; - + if (keysObject == null) + return keyList; + List> xmlKeys = XMLHelper.getList(keysObject.get(keyTagName)); - for (Map xmlKey: xmlKeys) { + for (Map xmlKey : xmlKeys) { keyList.add(parseKey(xmlKey)); } - + return keyList; } - - + /** * Parses a single Key object from XML * - * @param xmlObject the XML map containing the contents of the <aas:key> tag + * @param xmlObject + * the XML map containing the contents of the <aas:key> tag * @return the parsed Key object */ private static Key parseKey(Map xmlObject) { @@ -107,29 +131,31 @@ private static Key parseKey(Map xmlObject) { String idType = XMLHelper.getString(xmlObject.get(IDTYPE)); String type = XMLHelper.getString(xmlObject.get(TYPE)); boolean local = Boolean.parseBoolean(XMLHelper.getString(xmlObject.get(LOCAL))); - + // Enables parsing external aasx-files with empty or null id type if (Strings.isNullOrEmpty(idType)) { idType = KeyType.CUSTOM.toString(); } - + // Enables parsing external aasx-files with URI instead of IRI if (idType.equalsIgnoreCase("URI")) { idType = KeyType.IRI.toString(); } - + // Enables parsing external aasx-files with empty or null key type if (Strings.isNullOrEmpty(type)) { type = KeyElements.REFERENCEELEMENT.toString(); } return new Key(KeyElements.fromString(type), local, text, KeyType.fromString(idType)); } - + /** * Builds XML from a given Collection of IReference objects * - * @param document the XML document - * @param references a Collection of IReference objects to be converted to XML + * @param document + * the XML document + * @param references + * a Collection of IReference objects to be converted to XML * @return the <aas:keys> XML tag build from the IReference objects */ public static Element buildReferencesXML(Document document, Collection references) { @@ -139,51 +165,60 @@ public static Element buildReferencesXML(Document document, Collection references, String keysTagName, - String keyTagName) { + public static Element buildReferencesXML(Document document, Collection references, String keysTagName, String keyTagName) { Element xmlKeys = document.createElement(keysTagName); - if(references == null) return xmlKeys; - - for(IReference reference: references) { - if(reference != null) { - for(IKey key: reference.getKeys()) { + if (references == null) + return xmlKeys; + + for (IReference reference : references) { + if (reference != null) { + for (IKey key : reference.getKeys()) { xmlKeys.appendChild(buildKey(document, key, keyTagName)); } } } return xmlKeys; } - - + /** * Builds XML from a given single IReference object * - * @param document the XML document - * @param reference the IReference object to be converted to XML + * @param document + * the XML document + * @param reference + * the IReference object to be converted to XML * @return the <aas:keys> XML tag build from the IReference object */ public static Element buildReferenceXML(Document document, IReference reference) { - if(reference == null) return document.createElement(KEYS); + if (reference == null) + return document.createElement(KEYS); return buildReferencesXML(document, Arrays.asList(reference), KEYS, KEY); } - + /** * Builds XML from a given single IReference object * - * @param document the XML document - * @param reference the IReference object to be converted to XML - * @param keysTagName the custom <*keys*> tagName - * @param keyTagName the custom <*key*> tagName + * @param document + * the XML document + * @param reference + * the IReference object to be converted to XML + * @param keysTagName + * the custom <*keys*> tagName + * @param keyTagName + * the custom <*key*> tagName * @return the <aas:keys> XML tag build from the IReference object */ - public static Element buildReferenceXML(Document document, IReference reference, String keysTagName, - String keyTagName) { + public static Element buildReferenceXML(Document document, IReference reference, String keysTagName, String keyTagName) { if (reference == null) return document.createElement(keysTagName); return buildReferencesXML(document, Arrays.asList(reference), keysTagName, keyTagName); @@ -192,9 +227,12 @@ public static Element buildReferenceXML(Document document, IReference reference, /** * Builds XML from a given IKey object * - * @param document the XML document - * @param key the IKey object to be converted to XML - * @param keyTagName the custom <*key*> tagName + * @param document + * the XML document + * @param key + * the IKey object to be converted to XML + * @param keyTagName + * the custom <*key*> tagName * @return the <aas:key> XML tag build from the IKey object */ private static Element buildKey(Document document, IKey key, String keyTagName) { @@ -203,7 +241,7 @@ private static Element buildKey(Document document, IKey key, String keyTagName) xmlKey.setAttribute(IDTYPE, key.getIdType().toString()); xmlKey.setAttribute(LOCAL, String.valueOf(key.isLocal())); xmlKey.setAttribute(TYPE, key.getType().toString()); - + return xmlKey; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/CapabilityXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/CapabilityXMLConverter.java index 99fa84b4..843fae70 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/CapabilityXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/CapabilityXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java index 01c9d62e..f0c2e759 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementCollectionXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement; @@ -21,8 +36,10 @@ import org.w3c.dom.Element; /** - * Parses <aas:submodelElementCollection> and builds the SubmodelElementCollection object from it
- * Builds <aas:submodelElementCollection> from a given SubmodelElementCollection object + * Parses <aas:submodelElementCollection> and builds the + * SubmodelElementCollection object from it
+ * Builds <aas:submodelElementCollection> from a given + * SubmodelElementCollection object * * @author conradi * @@ -32,12 +49,14 @@ public class SubmodelElementCollectionXMLConverter extends SubmodelElementXMLCon public static final String SUBMODEL_ELEMENT_COLLECTION = "aas:submodelElementCollection"; public static final String ORDERED = "aas:ordered"; public static final String ALLOW_DUPLICATES = "aas:allowDuplicates"; - - + /** - * Parses a Map containing the content of XML tag <aas:submodelElementCollection> + * Parses a Map containing the content of XML tag + * <aas:submodelElementCollection> * - * @param xmlObject the Map with the content of XML tag <aas:submodelElementCollection> + * @param xmlObject + * the Map with the content of XML tag + * <aas:submodelElementCollection> * @return the parsed SubmodelElementCollection */ @SuppressWarnings("unchecked") @@ -50,36 +69,37 @@ public static SubmodelElementCollection parseSubmodelElementCollection(Map elems = smElemCollection.getSubmodelElements().values(); - - //recursively build the SubmodelElements contained in the ElementCollection - if(elems != null) { + + // recursively build the SubmodelElements contained in the ElementCollection + if (elems != null) { Element valueRoot = document.createElement(VALUE); smElemCollectionRoot.appendChild(valueRoot); buildSubmodelElements(document, valueRoot, elems); diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java index 3b24b91e..23399bc5 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/SubmodelElementXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement; @@ -69,14 +84,16 @@ import org.w3c.dom.Element; /** - * Parses <aas:submodelElements> and builds the SubmodelElement objects from it
- * Builds <aas:submodelElements> from a given Collection of SubmodelElement + * Parses <aas:submodelElements> and builds the SubmodelElement objects + * from it
+ * Builds <aas:submodelElements> from a given Collection of + * SubmodelElement * * @author conradi * */ public class SubmodelElementXMLConverter { - + public static final String SUBMODEL_ELEMENTS = "aas:submodelElements"; public static final String SUBMODEL_ELEMENT = "aas:submodelElement"; public static final String DATA_ELEMENT = "aas:dataElement"; @@ -85,115 +102,100 @@ public class SubmodelElementXMLConverter { public static final String VALUE_ID = "aas:valueId"; public static final String MIME_TYPE = "aas:mimeType"; - /** * Parses a given Map containing the XML tag <aas:submodelElements> * - * @param xmlSubmodelElements a Map of the XML tag <aas:submodelElements> - * @return a List with the ISubmodelElement Objects parsed from the XML + * @param xmlSubmodelElements + * a Map of the XML tag <aas:submodelElements> + * @return a List with the ISubmodelElement Objects parsed from the XML */ @SuppressWarnings("unchecked") public static List parseSubmodelElements(Map xmlSubmodelElements) { Map xmlSubmodelElementsMap = (Map) xmlSubmodelElements.get(SUBMODEL_ELEMENTS); return getSubmodelElements(xmlSubmodelElementsMap); } - /** * Parses the individual <aas:submodelElement> tags from the Map * - * @param xmlObject a Map of <aas:submodelElement> tags - * @return a List with the ISubmodelElement Objects parsed from the XML + * @param xmlObject + * a Map of <aas:submodelElement> tags + * @return a List with the ISubmodelElement Objects parsed from the XML */ protected static List getSubmodelElements(Map xmlObject) { List submodelElemList = new ArrayList<>(); - if(xmlObject == null) return submodelElemList; - + if (xmlObject == null) + return submodelElemList; + List> xmlSubmodelElemList = XMLHelper.getList(xmlObject.get(SUBMODEL_ELEMENT)); - for (Map xmlSubmodelElem: xmlSubmodelElemList) { + for (Map xmlSubmodelElem : xmlSubmodelElemList) { submodelElemList.add(getSubmodelElement(xmlSubmodelElem)); } - + return submodelElemList; } - - + /** * Parses the one SubmodelElement * - * @param xmlObject a Map of the SubmodelElement XML - * @return a List with the ISubmodelElement Objects parsed from the XML + * @param xmlObject + * a Map of the SubmodelElement XML + * @return a List with the ISubmodelElement Objects parsed from the XML */ @SuppressWarnings("unchecked") public static SubmodelElement getSubmodelElement(Map xmlObject) { - + if (xmlObject.containsKey(PropertyXMLConverter.PROPERTY)) { xmlObject = (Map) xmlObject.get(PropertyXMLConverter.PROPERTY); return PropertyXMLConverter.parseProperty(xmlObject); - } - else if (xmlObject.containsKey(BasicEventXMLConverter.BASIC_EVENT)) { + } else if (xmlObject.containsKey(BasicEventXMLConverter.BASIC_EVENT)) { xmlObject = (Map) xmlObject.get(BasicEventXMLConverter.BASIC_EVENT); return BasicEventXMLConverter.parseBasicEvent(xmlObject); - } - else if (xmlObject.containsKey(CapabilityXMLConverter.CAPABILITY)) { + } else if (xmlObject.containsKey(CapabilityXMLConverter.CAPABILITY)) { xmlObject = (Map) xmlObject.get(CapabilityXMLConverter.CAPABILITY); return CapabilityXMLConverter.parseCapability(xmlObject); - } - else if (xmlObject.containsKey(EntityXMLConverter.ENTITY)) { + } else if (xmlObject.containsKey(EntityXMLConverter.ENTITY)) { xmlObject = (Map) xmlObject.get(EntityXMLConverter.ENTITY); return EntityXMLConverter.parseEntity(xmlObject); - } - else if (xmlObject.containsKey(MultiLanguagePropertyXMLConverter.MULTI_LANGUAGE_PROPERTY)) { - xmlObject = (Map) xmlObject.get( - MultiLanguagePropertyXMLConverter.MULTI_LANGUAGE_PROPERTY); + } else if (xmlObject.containsKey(MultiLanguagePropertyXMLConverter.MULTI_LANGUAGE_PROPERTY)) { + xmlObject = (Map) xmlObject.get(MultiLanguagePropertyXMLConverter.MULTI_LANGUAGE_PROPERTY); return MultiLanguagePropertyXMLConverter.parseMultiLanguageProperty(xmlObject); - } - else if (xmlObject.containsKey(RangeXMLConverter.RANGE)) { + } else if (xmlObject.containsKey(RangeXMLConverter.RANGE)) { xmlObject = (Map) xmlObject.get(RangeXMLConverter.RANGE); return RangeXMLConverter.parseRange(xmlObject); - } - else if (xmlObject.containsKey(FileXMLConverter.FILE)) { + } else if (xmlObject.containsKey(FileXMLConverter.FILE)) { xmlObject = (Map) xmlObject.get(FileXMLConverter.FILE); return FileXMLConverter.parseFile(xmlObject); - } - else if(xmlObject.containsKey(BlobXMLConverter.BLOB)) { + } else if (xmlObject.containsKey(BlobXMLConverter.BLOB)) { xmlObject = (Map) xmlObject.get(BlobXMLConverter.BLOB); return BlobXMLConverter.parseBlob(xmlObject); - } - else if(xmlObject.containsKey(ReferenceElementXMLConverter.REFERENCE_ELEMENT)) { - xmlObject = (Map) xmlObject.get( - ReferenceElementXMLConverter.REFERENCE_ELEMENT); + } else if (xmlObject.containsKey(ReferenceElementXMLConverter.REFERENCE_ELEMENT)) { + xmlObject = (Map) xmlObject.get(ReferenceElementXMLConverter.REFERENCE_ELEMENT); return ReferenceElementXMLConverter.parseReferenceElement(xmlObject); - } - else if(xmlObject.containsKey(SubmodelElementCollectionXMLConverter.SUBMODEL_ELEMENT_COLLECTION)) { - xmlObject = (Map) xmlObject.get( - SubmodelElementCollectionXMLConverter.SUBMODEL_ELEMENT_COLLECTION); + } else if (xmlObject.containsKey(SubmodelElementCollectionXMLConverter.SUBMODEL_ELEMENT_COLLECTION)) { + xmlObject = (Map) xmlObject.get(SubmodelElementCollectionXMLConverter.SUBMODEL_ELEMENT_COLLECTION); return SubmodelElementCollectionXMLConverter.parseSubmodelElementCollection(xmlObject); - } - else if(xmlObject.containsKey(RelationshipElementXMLConverter.RELATIONSHIP_ELEMENT)) { - xmlObject = (Map) xmlObject.get( - RelationshipElementXMLConverter.RELATIONSHIP_ELEMENT); + } else if (xmlObject.containsKey(RelationshipElementXMLConverter.RELATIONSHIP_ELEMENT)) { + xmlObject = (Map) xmlObject.get(RelationshipElementXMLConverter.RELATIONSHIP_ELEMENT); return RelationshipElementXMLConverter.parseRelationshipElement(xmlObject); - } - else if(xmlObject.containsKey(AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT)) { - xmlObject = (Map) xmlObject.get( - AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT); + } else if (xmlObject.containsKey(AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT)) { + xmlObject = (Map) xmlObject.get(AnnotatedRelationshipElementXMLConverter.ANNOTATED_RELATIONSHIP_ELEMENT); return AnnotatedRelationshipElementXMLConverter.parseAnnotatedRelationshipElement(xmlObject); - } - else if(xmlObject.containsKey(OperationXMLConverter.OPERATION)) { + } else if (xmlObject.containsKey(OperationXMLConverter.OPERATION)) { xmlObject = (Map) xmlObject.get(OperationXMLConverter.OPERATION); return OperationXMLConverter.parseOperation(xmlObject); } - + return null; } - /** - * Populates a SubmodelElement with the standard information from a XML tag + * Populates a SubmodelElement with the standard information from a XML tag * - * @param xmlObject the Map with the content of XML tag <aas:blob> - * @param submodelElement the SubmodelElement to be populated + * @param xmlObject + * the Map with the content of XML tag <aas:blob> + * @param submodelElement + * the SubmodelElement to be populated */ @SuppressWarnings("unchecked") protected static void populateSubmodelElement(Map xmlObject, ISubmodelElement submodelElement) { @@ -203,15 +205,14 @@ protected static void populateSubmodelElement(Map xmlObject, ISu HasSemanticsXMLConverter.populateHasSemantics(xmlObject, HasSemantics.createAsFacade((Map) submodelElement)); HasKindXMLConverter.populateHasKind(xmlObject, HasKind.createAsFacade((Map) submodelElement)); } - - - /** * Builds the SubmodelElemensts XML tag <aas:submodelElements> * - * @param document the XML document - * @param submodelElements the SubmodelElements of the Submodel + * @param document + * the XML document + * @param submodelElements + * the SubmodelElements of the Submodel * @return XML Element with the root tag <aas:submodelElements> */ public static Element buildSubmodelElementsXML(Document document, Collection submodelElements) { @@ -219,15 +220,18 @@ public static Element buildSubmodelElementsXML(Document document, Collection + * Builds the individual SubmodelElement XML tags from a List of + * SubmodelElements and
* populates the given root Element with them * - * @param document the XML document - * @param root the XML Element <aas:submodelElements> - * @param submodelElements a List of SubmodelElements + * @param document + * the XML document + * @param root + * the XML Element <aas:submodelElements> + * @param submodelElements + * a List of SubmodelElements */ protected static void buildSubmodelElements(Document document, Element root, Collection submodelElements) { for (ISubmodelElement submodelElement : submodelElements) { @@ -238,61 +242,60 @@ protected static void buildSubmodelElements(Document document, Element root, Col } } - /** * Builds one SubmodelElement XML tag * - * @param document the XML document - * @param submodelElement the SubmodelElement to build the XML for + * @param document + * the XML document + * @param submodelElement + * the SubmodelElement to build the XML for * @return the SubmodelElement XML tag */ public static Element buildSubmodelElement(Document document, ISubmodelElement submodelElement) { - String type = submodelElement.getModelType(); - + String type = submodelElement.getModelType(); + switch (type) { - case Property.MODELTYPE: - return PropertyXMLConverter.buildProperty(document, (IProperty) submodelElement); - case BasicEvent.MODELTYPE: - return BasicEventXMLConverter.buildBasicEvent(document, (IBasicEvent) submodelElement); - case MultiLanguageProperty.MODELTYPE: - return MultiLanguagePropertyXMLConverter.buildMultiLanguageProperty( - document, (IMultiLanguageProperty) submodelElement); - case Range.MODELTYPE: - return RangeXMLConverter.buildRange(document, (IRange) submodelElement); - case Entity.MODELTYPE: - return EntityXMLConverter.buildEntity(document, (IEntity) submodelElement); - case File.MODELTYPE: - return FileXMLConverter.buildFile(document, (IFile) submodelElement); - case Blob.MODELTYPE: - return BlobXMLConverter.buildBlob(document, (IBlob) submodelElement); - case ReferenceElement.MODELTYPE: - return ReferenceElementXMLConverter.buildReferenceElement( - document, (IReferenceElement) submodelElement); - case SubmodelElementCollection.MODELTYPE: - return SubmodelElementCollectionXMLConverter.buildSubmodelElementCollection( - document, (ISubmodelElementCollection) submodelElement); - case RelationshipElement.MODELTYPE: - return RelationshipElementXMLConverter.buildRelationshipElement( - document, (IRelationshipElement) submodelElement); - case AnnotatedRelationshipElement.MODELTYPE: - return AnnotatedRelationshipElementXMLConverter.buildAnnotatedRelationshipElement( - document, (IAnnotatedRelationshipElement) submodelElement); - case Operation.MODELTYPE: - return OperationXMLConverter.buildOperation(document, (IOperation) submodelElement); - case Capability.MODELTYPE: - return CapabilityXMLConverter.buildCapability(document, (ICapability) submodelElement); - default: - return null; + case Property.MODELTYPE: + return PropertyXMLConverter.buildProperty(document, (IProperty) submodelElement); + case BasicEvent.MODELTYPE: + return BasicEventXMLConverter.buildBasicEvent(document, (IBasicEvent) submodelElement); + case MultiLanguageProperty.MODELTYPE: + return MultiLanguagePropertyXMLConverter.buildMultiLanguageProperty(document, (IMultiLanguageProperty) submodelElement); + case Range.MODELTYPE: + return RangeXMLConverter.buildRange(document, (IRange) submodelElement); + case Entity.MODELTYPE: + return EntityXMLConverter.buildEntity(document, (IEntity) submodelElement); + case File.MODELTYPE: + return FileXMLConverter.buildFile(document, (IFile) submodelElement); + case Blob.MODELTYPE: + return BlobXMLConverter.buildBlob(document, (IBlob) submodelElement); + case ReferenceElement.MODELTYPE: + return ReferenceElementXMLConverter.buildReferenceElement(document, (IReferenceElement) submodelElement); + case SubmodelElementCollection.MODELTYPE: + return SubmodelElementCollectionXMLConverter.buildSubmodelElementCollection(document, (ISubmodelElementCollection) submodelElement); + case RelationshipElement.MODELTYPE: + return RelationshipElementXMLConverter.buildRelationshipElement(document, (IRelationshipElement) submodelElement); + case AnnotatedRelationshipElement.MODELTYPE: + return AnnotatedRelationshipElementXMLConverter.buildAnnotatedRelationshipElement(document, (IAnnotatedRelationshipElement) submodelElement); + case Operation.MODELTYPE: + return OperationXMLConverter.buildOperation(document, (IOperation) submodelElement); + case Capability.MODELTYPE: + return CapabilityXMLConverter.buildCapability(document, (ICapability) submodelElement); + default: + return null; } - } - + } /** - * Populates a SubmodelElement XML tag with the standard information of a SubmodelElement + * Populates a SubmodelElement XML tag with the standard information of a + * SubmodelElement * - * @param document the XML document - * @param root the root Element of the SubmodelElement - * @param submodelElement the SubmodelElement + * @param document + * the XML document + * @param root + * the root Element of the SubmodelElement + * @param submodelElement + * the SubmodelElement */ protected static void populateSubmodelElement(Document document, Element root, ISubmodelElement submodelElement) { ReferableXMLConverter.populateReferableXML(document, root, submodelElement); diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java index d3b7485a..52893cb1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/BlobXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement; @@ -28,12 +43,12 @@ public class BlobXMLConverter extends SubmodelElementXMLConverter { public static final String BLOB = "aas:blob"; - - + /** * Parses a Map containing the content of XML tag <aas:blob> * - * @param xmlObject the Map with the content of XML tag <aas:blob> + * @param xmlObject + * the Map with the content of XML tag <aas:blob> * @return the parsed Blob */ public static Blob parseBlob(Map xmlObject) { @@ -46,36 +61,35 @@ public static Blob parseBlob(Map xmlObject) { return blob; } - - - /** * Builds the <aas:blob> XML tag for a Blob * - * @param document the XML document - * @param blob the IBlob to build the XML for + * @param document + * the XML document + * @param blob + * the IBlob to build the XML for * @return the <aas:blob> XML tag for the given Blob */ public static Element buildBlob(Document document, IBlob blob) { Element blobRoot = document.createElement(BLOB); - + populateSubmodelElement(document, blobRoot, blob); - + // Base64 encoded string String value = blob.getValue(); String mimeType = blob.getMimeType(); - - if(value != null) { + + if (value != null) { Element valueRoot = document.createElement(VALUE); valueRoot.appendChild(document.createTextNode(value)); blobRoot.appendChild(valueRoot); } - if(mimeType != null) { + if (mimeType != null) { Element mimeTypeRoot = document.createElement(MIME_TYPE); mimeTypeRoot.appendChild(document.createTextNode(mimeType)); blobRoot.appendChild(mimeTypeRoot); } - + return blobRoot; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java index ae36ce42..3304f149 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/FileXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement; @@ -25,15 +40,15 @@ * @author conradi * */ -public class FileXMLConverter extends SubmodelElementXMLConverter{ +public class FileXMLConverter extends SubmodelElementXMLConverter { public static final String FILE = "aas:file"; - - + /** * Parses a Map containing the content of XML tag <aas:file> * - * @param xmlObject the Map with the content of XML tag <aas:file> + * @param xmlObject + * the Map with the content of XML tag <aas:file> * @return the parsed File */ public static File parseFile(Map xmlObject) { @@ -43,35 +58,34 @@ public static File parseFile(Map xmlObject) { populateSubmodelElement(xmlObject, file); return file; } - - - - + /** * Builds the <aas:file> XML tag for a File * - * @param document the XML document - * @param file the IFile to build the XML for + * @param document + * the XML document + * @param file + * the IFile to build the XML for * @return the <aas:file> XML tag for the given File */ public static Element buildFile(Document document, IFile file) { Element fileRoot = document.createElement(FILE); - + populateSubmodelElement(document, fileRoot, file); - + String mimeType = file.getMimeType(); String value = file.getValue(); - if(mimeType != null) { + if (mimeType != null) { Element mimeTypeRoot = document.createElement(MIME_TYPE); mimeTypeRoot.appendChild(document.createTextNode(mimeType)); fileRoot.appendChild(mimeTypeRoot); } - if(value != null) { + if (value != null) { Element valueRoot = document.createElement(VALUE); valueRoot.appendChild(document.createTextNode(value)); fileRoot.appendChild(valueRoot); } - + return fileRoot; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java index 518db1ed..6acb8a78 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/MultiLanguagePropertyXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement; @@ -23,20 +38,25 @@ import org.w3c.dom.Element; /** - * Parses <aas:multiLanguageProperty> and builds the MultiLanguageProperty object from it
- * Builds <aas:multiLanguageProperty> from a given MultiLanguageProperty object + * Parses <aas:multiLanguageProperty> and builds the MultiLanguageProperty + * object from it
+ * Builds <aas:multiLanguageProperty> from a given MultiLanguageProperty + * object * * @author conradi * */ public class MultiLanguagePropertyXMLConverter extends SubmodelElementXMLConverter { - + public static final String MULTI_LANGUAGE_PROPERTY = "aas:multiLanguageProperty"; - + /** - * Parses a Map containing the content of XML tag <aas:multiLanguageProperty> + * Parses a Map containing the content of XML tag + * <aas:multiLanguageProperty> * - * @param xmlObject the Map with the content of XML tag <aas:multiLanguageProperty> + * @param xmlObject + * the Map with the content of XML tag + * <aas:multiLanguageProperty> * @return the parsed MultiLanguageProperty */ @SuppressWarnings("unchecked") @@ -50,30 +70,32 @@ public static MultiLanguageProperty parseMultiLanguageProperty(Map * Builds <aas:property> from a given Property object * - * @author conradi + * @author conradi, jungjan * */ public class PropertyXMLConverter extends SubmodelElementXMLConverter { - + private static Logger logger = LoggerFactory.getLogger(PropertyXMLConverter.class); - + public static final String PROPERTY = "aas:property"; - /** * Parses a Map containing the content of XML tag <aas:property> * - * @param xmlObject the Map with the content of XML tag <aas:property> + * @param xmlObject + * the Map with the content of XML tag <aas:property> * @return the parsed Property */ @SuppressWarnings("unchecked") public static Property parseProperty(Map xmlObject) { - + Property property = new Property(); - + populateSubmodelElement(xmlObject, property); - + String valueType = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE_TYPE)); - String value = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE)); - + String xmlStringValue = XMLHelper.getString(xmlObject.get(SubmodelElementXMLConverter.VALUE)); + + ValueType propertyType = XMLHelper.convertAASXValueTypeToLocal(valueType); + Object propertyValue = XMLHelper.convertAASXValueToLocal(xmlStringValue, propertyType); + Map xmlValueId = (Map) xmlObject.get(VALUE_ID); Reference valueId = ReferenceXMLConverter.parseReference(xmlValueId); - - property.set(value, XMLHelper.convertAASXValueTypeToLocal(valueType)); - - if(valueId != null) { + + property.set(propertyValue, propertyType); + + if (valueId != null) { property.setValueId(valueId); } - + return property; } - - - - + /** * Builds the <aas:property> XML tag for a Property * - * @param document the XML document - * @param prop the ISingleProperty to build the XML for + * @param document + * the XML document + * @param prop + * the ISingleProperty to build the XML for * @return the <aas:property> XML tag for the given Property */ public static Element buildProperty(Document document, IProperty prop) { Element propertyRoot = document.createElement(PROPERTY); - + populateSubmodelElement(document, propertyRoot, prop); String value = null; - + IReference valueId = prop.getValueId(); - if(valueId != null) { + if (valueId != null) { Element valueIdRoot = document.createElement(VALUE_ID); - valueIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, valueId)); + valueIdRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, valueId)); propertyRoot.appendChild(valueIdRoot); - } - - //for some reason, get() in ISingleProperty might throw an Exception + } + + // for some reason, get() in ISingleProperty might throw an Exception try { Object valueObj = prop.getValue(); value = valueObj == null ? null : valueObj.toString(); } catch (Exception e) { logger.error("Exeption in buildProperty!", e); } - + if (value != null) { Element valueEle = document.createElement(SubmodelElementXMLConverter.VALUE); valueEle.appendChild(document.createTextNode(value)); propertyRoot.appendChild(valueEle); } - + String valueType = prop.getValueType().toString(); if (valueType != null) { Element valueTypeElem = document.createElement(SubmodelElementXMLConverter.VALUE_TYPE); valueTypeElem.appendChild(document.createTextNode(valueType)); propertyRoot.appendChild(valueTypeElem); } - + return propertyRoot; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java index 4b937881..21fc44c3 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/RangeXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement; @@ -30,12 +45,12 @@ public class RangeXMLConverter extends SubmodelElementXMLConverter { public static final String RANGE = "aas:range"; public static final String MIN = "aas:min"; public static final String MAX = "aas:max"; - - + /** * Parses a Map containing the content of XML tag <aas:range> * - * @param xmlObject the Map with the content of XML tag <aas:range> + * @param xmlObject + * the Map with the content of XML tag <aas:range> * @return the parsed Range */ public static Range parseRange(Map xmlObject) { @@ -46,45 +61,44 @@ public static Range parseRange(Map xmlObject) { populateSubmodelElement(xmlObject, range); return range; } - - - - + /** * Builds the <aas:range> XML tag for a Range * - * @param document the XML document - * @param range the IRange to build the XML for + * @param document + * the XML document + * @param range + * the IRange to build the XML for * @return the <aas:range> XML tag for the given Range */ public static Element buildRange(Document document, IRange range) { Element rangeRoot = document.createElement(RANGE); populateSubmodelElement(document, rangeRoot, range); - + Object maxObj = range.getMax(); String max = maxObj == null ? null : maxObj.toString(); - if(max != null) { + if (max != null) { Element maxRoot = document.createElement(MAX); maxRoot.appendChild(document.createTextNode(max)); rangeRoot.appendChild(maxRoot); } - + Object minObj = range.getMin(); String min = minObj == null ? null : minObj.toString(); - if(min != null) { + if (min != null) { Element minRoot = document.createElement(MIN); minRoot.appendChild(document.createTextNode(min)); rangeRoot.appendChild(minRoot); } - + String valueType = range.getValueType().toString(); - if(valueType != null) { + if (valueType != null) { Element valueTypeRoot = document.createElement(VALUE_TYPE); valueTypeRoot.appendChild(document.createTextNode(valueType)); rangeRoot.appendChild(valueTypeRoot); } - + return rangeRoot; } - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java index c81c656b..d430441b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/dataelement/ReferenceElementXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.dataelement; @@ -20,21 +35,22 @@ import org.w3c.dom.Element; /** - * Parses <aas:referenceElement> and builds the ReferenceElement object from it
+ * Parses <aas:referenceElement> and builds the ReferenceElement object + * from it
* Builds <aas:referenceElement> from a given ReferenceElement object * * @author conradi * */ public class ReferenceElementXMLConverter extends SubmodelElementXMLConverter { - + public static final String REFERENCE_ELEMENT = "aas:referenceElement"; - /** * Parses a Map containing the content of XML tag <aas:referenceElement> * - * @param xmlObject the Map with the content of XML tag <aas:referenceElement> + * @param xmlObject + * the Map with the content of XML tag <aas:referenceElement> * @return the parsed ReferenceElement */ @SuppressWarnings("unchecked") @@ -44,28 +60,28 @@ public static ReferenceElement parseReferenceElement(Map xmlObje populateSubmodelElement(xmlObject, refElement); return refElement; } - - - - + /** * Builds the <aas:referenceElement> XML tag for a ReferenceElement * - * @param document the XML document - * @param refElem the IReferenceElement to build the XML for - * @return the <aas:referenceElement> XML tag for the given ReferenceElement + * @param document + * the XML document + * @param refElem + * the IReferenceElement to build the XML for + * @return the <aas:referenceElement> XML tag for the given + * ReferenceElement */ public static Element buildReferenceElement(Document document, IReferenceElement refElem) { Element refElemRoot = document.createElement(REFERENCE_ELEMENT); - + populateSubmodelElement(document, refElemRoot, refElem); IReference value = refElem.getValue(); - if(value != null) { + if (value != null) { Element derivedFromRoot = document.createElement(VALUE); - derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, value)); + derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, value)); refElemRoot.appendChild(derivedFromRoot); - } + } return refElemRoot; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java index c65b3f2f..5b90a1a7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/entity/EntityXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.entity; @@ -33,17 +48,17 @@ * */ public class EntityXMLConverter extends SubmodelElementXMLConverter { - + public static final String ENTITY = "aas:entity"; public static final String ENTITY_TYPE = "aas:entityType"; public static final String STATEMENTS = "aas:statements"; public static final String ASSET_REF = "aas:assetRef"; - - + /** * Parses a Map containing the content of XML tag <aas:entity> * - * @param xmlObject the Map with the content of XML tag <aas:entity> + * @param xmlObject + * the Map with the content of XML tag <aas:entity> * @return the parsed Entity */ @SuppressWarnings("unchecked") @@ -58,41 +73,40 @@ public static Entity parseEntity(Map xmlObject) { populateSubmodelElement(xmlObject, entity); return entity; } - - - - + /** * Builds the <aas:entity> XML tag for an Entity * - * @param document the XML document - * @param entity the IEntity to build the XML for + * @param document + * the XML document + * @param entity + * the IEntity to build the XML for * @return the <aas:entity> XML tag for the given Entity */ public static Element buildEntity(Document document, IEntity entity) { Element entityRoot = document.createElement(ENTITY); - + populateSubmodelElement(document, entityRoot, entity); - + IReference assetRef = entity.getAsset(); - if(assetRef != null) { + if (assetRef != null) { Element assetRefRoot = document.createElement(ASSET_REF); assetRefRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, assetRef)); entityRoot.appendChild(assetRefRoot); } - + Object entityTypeObj = entity.getEntityType(); String entityType = entityTypeObj == null ? null : entityTypeObj.toString(); - if(entityType != null) { + if (entityType != null) { Element entityTypeRoot = document.createElement(ENTITY_TYPE); entityTypeRoot.appendChild(document.createTextNode(entityType)); entityRoot.appendChild(entityTypeRoot); } - + Collection statement = entity.getStatements(); - - //recursively build the SubmodelElements contained in the statement - if(statement != null) { + + // recursively build the SubmodelElements contained in the statement + if (statement != null) { Element statementsRoot = document.createElement(STATEMENTS); entityRoot.appendChild(statementsRoot); buildSubmodelElements(document, statementsRoot, statement); diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java index e12e7501..299c7fa8 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/event/BasicEventXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.event; @@ -28,15 +43,15 @@ * */ public class BasicEventXMLConverter extends SubmodelElementXMLConverter { - + public static final String BASIC_EVENT = "aas:basicEvent"; public static final String OBSERVED = "aas:observed"; - /** * Parses a Map containing the content of XML tag <aas:basicEvent> * - * @param xmlObject the Map with the content of XML tag <aas:basicEvent> + * @param xmlObject + * the Map with the content of XML tag <aas:basicEvent> * @return the parsed BasicEvent */ @SuppressWarnings("unchecked") @@ -47,29 +62,28 @@ public static BasicEvent parseBasicEvent(Map xmlObject) { populateSubmodelElement(xmlObject, basicEvent); return basicEvent; } - - - - + /** * Builds the <aas:basicEvent> XML tag for a BasicEvent * - * @param document the XML document - * @param basicEvent the IBasicEvent to build the XML for + * @param document + * the XML document + * @param basicEvent + * the IBasicEvent to build the XML for * @return the <aas:basicEvent> XML tag for the given BasicEvent */ public static Element buildBasicEvent(Document document, IBasicEvent basicEvent) { Element basicEventRoot = document.createElement(BASIC_EVENT); - + populateSubmodelElement(document, basicEventRoot, basicEvent); - + IReference observed = basicEvent.getObserved(); - if(observed != null) { + if (observed != null) { Element observedRoot = document.createElement(OBSERVED); observedRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, observed)); basicEventRoot.appendChild(observedRoot); } - + return basicEventRoot; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java index e982a38a..8a051ab4 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/operation/OperationXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.operation; @@ -14,6 +29,7 @@ import java.util.List; import java.util.Map; +import org.eclipse.basyx.aas.factory.xml.AASXPackageExplorerCompatibilityHandler; import org.eclipse.basyx.submodel.factory.xml.XMLHelper; import org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.SubmodelElementXMLConverter; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; @@ -33,51 +49,50 @@ * */ public class OperationXMLConverter extends SubmodelElementXMLConverter { - + public static final String OPERATION = "aas:operation"; public static final String INPUT_VARIABLE = "aas:inputVariable"; public static final String OUTPUT_VARIABLE = "aas:outputVariable"; public static final String INOUTPUT_VARIABLE = "aas:inoutputVariable"; public static final String OPERATION_VARIABLE = "aas:operationVariable"; - /** * Parses a Map containing the content of XML tag <aas:operation> * - * @param xmlObject the Map with the content of XML tag <aas:operation> + * @param xmlObject + * the Map with the content of XML tag <aas:operation> * @return the parsed Operation */ - @SuppressWarnings("unchecked") public static Operation parseOperation(Map xmlObject) { List inList = new ArrayList<>(); List outList = new ArrayList<>(); List inoutList = new ArrayList<>(); - - Map inObj = (Map) xmlObject.get(INPUT_VARIABLE); + + Map inObj = AASXPackageExplorerCompatibilityHandler.prepareOperationVariableMap(xmlObject.get(INPUT_VARIABLE)); if (inObj != null) { inList = getOperationVariables(inObj); } - - Map outObj = (Map) xmlObject.get(OUTPUT_VARIABLE); + + Map outObj = AASXPackageExplorerCompatibilityHandler.prepareOperationVariableMap(xmlObject.get(OUTPUT_VARIABLE)); if (outObj != null) { outList = getOperationVariables(outObj); } - - Map inoutObj = (Map) xmlObject.get(INOUTPUT_VARIABLE); + + Map inoutObj = AASXPackageExplorerCompatibilityHandler.prepareOperationVariableMap(xmlObject.get(INOUTPUT_VARIABLE)); if (inoutObj != null) { - inoutList = getOperationVariables(inoutObj); + inoutList = getOperationVariables(inoutObj); } - + Operation operation = new Operation(inList, outList, inoutList, null); populateSubmodelElement(xmlObject, operation); return operation; } - /** * Parses a Map containing the content of XML tag <aas:operationVariable> * - * @param xmlObject the Map with the content of XML tag <aas:operationVariable> + * @param xmlObject + * the Map with the content of XML tag <aas:operationVariable> * @return the parsed OperationVariable */ @SuppressWarnings("unchecked") @@ -86,66 +101,67 @@ private static OperationVariable parseOperationVariable(Map xmlO OperationVariable operationVariable = new OperationVariable(submodelElement); return operationVariable; } - - - - + /** * Builds the <aas:operation> XML tag for an Operation * - * @param document the XML document - * @param operation the IOperation to build the XML for + * @param document + * the XML document + * @param operation + * the IOperation to build the XML for * @return the <aas:operation> XML tag for the given Operation */ public static Element buildOperation(Document document, IOperation operation) { Element operationRoot = document.createElement(OPERATION); - + populateSubmodelElement(document, operationRoot, operation); - + Collection inout = operation.getInOutputVariables(); - if(inout != null) { + if (inout != null) { Element valueRoot = document.createElement(INOUTPUT_VARIABLE); operationRoot.appendChild(valueRoot); - for(IOperationVariable operationVariable: inout) { + for (IOperationVariable operationVariable : inout) { valueRoot.appendChild(buildOperationVariable(document, operationVariable)); } } - + Collection in = operation.getInputVariables(); - if(in != null) { + if (in != null) { Element valueRoot = document.createElement(INPUT_VARIABLE); operationRoot.appendChild(valueRoot); - for(IOperationVariable operationVariable: in) { + for (IOperationVariable operationVariable : in) { valueRoot.appendChild(buildOperationVariable(document, operationVariable)); } } - + Collection out = operation.getOutputVariables(); - if(out != null) { + if (out != null) { Element valueRoot = document.createElement(OUTPUT_VARIABLE); operationRoot.appendChild(valueRoot); - for(IOperationVariable operationVariable: out) { + for (IOperationVariable operationVariable : out) { valueRoot.appendChild(buildOperationVariable(document, operationVariable)); } } return operationRoot; } - - + /** * Builds the <aas:operationVariable> XML tag for an OperationVariable * - * @param document the XML document - * @param operationVariable the IOperationVariable to build the XML for - * @return the <aas:operationVariable> XML tag for the given OperationVariable + * @param document + * the XML document + * @param operationVariable + * the IOperationVariable to build the XML for + * @return the <aas:operationVariable> XML tag for the given + * OperationVariable */ private static Element buildOperationVariable(Document document, IOperationVariable operationVariable) { Element operationVariableRoot = document.createElement(OPERATION_VARIABLE); - + ISubmodelElement value = operationVariable.getValue(); - - if(value != null) { + + if (value != null) { Element valueRoot = document.createElement(VALUE); valueRoot.appendChild(buildSubmodelElement(document, value)); operationVariableRoot.appendChild(valueRoot); @@ -153,29 +169,24 @@ private static Element buildOperationVariable(Document document, IOperationVaria return operationVariableRoot; } - + /** * Gets Operation Variables In/Out/InOut from variable map - * @param varObj map containing variables + * + * @param varObj + * map containing variables * @return List of OperationVariable */ private static List getOperationVariables(Map varObj) { List variableList = new ArrayList<>(); Object operationVarObj = varObj.get(OPERATION_VARIABLE); - - //TODO: Remove after non-existing aas:operationVariable problem fixed in AAS Package Explorer - if (operationVarObj == null) { - if (varObj.get(VALUE) != null) { - operationVarObj = varObj; - } - } - + List> xmlOpVars = XMLHelper.getList(operationVarObj); - - for(Map map : xmlOpVars) { + + for (Map map : xmlOpVars) { variableList.add(parseOperationVariable(map)); } - + return variableList; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java index 74cbb53d..6ed4825f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/AnnotatedRelationshipElementXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship; @@ -23,8 +38,10 @@ import org.w3c.dom.Element; /** - * Parses <aas:annotatedRelationshipElement> and builds an AnnotatedRelationshipElement object from it
- * Builds <aas:annotatedRelationshipElement> from a given AnnotatedRelationshipElement + * Parses <aas:annotatedRelationshipElement> and builds an + * AnnotatedRelationshipElement object from it
+ * Builds <aas:annotatedRelationshipElement> from a given + * AnnotatedRelationshipElement * * @author conradi * @@ -36,59 +53,61 @@ public class AnnotatedRelationshipElementXMLConverter { /** * Builds a AnnotatedRelationshipElement object from the given XML * - * @param xmlObject the Map with the content of XML tag <aas:annotatedRelationshipElement> + * @param xmlObject + * the Map with the content of XML tag + * <aas:annotatedRelationshipElement> * @return the parsed AnnotatedRelationshipElement */ @SuppressWarnings("unchecked") public static AnnotatedRelationshipElement parseAnnotatedRelationshipElement(Map xmlObject) { AnnotatedRelationshipElement annotatedElement = new AnnotatedRelationshipElement(); - + RelationshipElementXMLConverter.populateRelationshipElement(xmlObject, annotatedElement); - + Map xmlAnnotations = (Map) xmlObject.get(ANNOTATIONS); List> xmlDataElements = XMLHelper.getList(xmlAnnotations.get(SubmodelElementCollectionXMLConverter.DATA_ELEMENT)); - - + List dataElements = new ArrayList<>(); - for(Map element: xmlDataElements) { + for (Map element : xmlDataElements) { ISubmodelElement smElement = SubmodelElementCollectionXMLConverter.getSubmodelElement(element); - + // Check if all Elements contained in is an IDataElement - if(smElement instanceof IDataElement) { + if (smElement instanceof IDataElement) { dataElements.add((IDataElement) smElement); } else { throw new RuntimeException("AnnotatedRelationshipElement '" + annotatedElement.getIdShort() + "' can only contain IDataElement as annotation"); } } - + annotatedElement.setAnnotation(dataElements); return annotatedElement; } - - - - + /** - * Builds the <aas:annotatedRelationshipElement> XML tag for a AnnotatedRelationshipElement + * Builds the <aas:annotatedRelationshipElement> XML tag for a + * AnnotatedRelationshipElement * - * @param document the XML document - * @param annotatedElement the IAnnotatedRelationshipElement to build the XML for - * @return the <aas:annotatedRelationshipElement> XML tag for the given AnnotatedRelationshipElement + * @param document + * the XML document + * @param annotatedElement + * the IAnnotatedRelationshipElement to build the XML for + * @return the <aas:annotatedRelationshipElement> XML tag for the given + * AnnotatedRelationshipElement */ public static Element buildAnnotatedRelationshipElement(Document document, IAnnotatedRelationshipElement annotatedElement) { Element root = document.createElement(ANNOTATED_RELATIONSHIP_ELEMENT); RelationshipElementXMLConverter.populateRelationshipElement(document, root, annotatedElement); - + Element annotationsRoot = document.createElement(ANNOTATIONS); root.appendChild(annotationsRoot); - - for(IDataElement dataElement: annotatedElement.getValue().getAnnotations()) { + + for (IDataElement dataElement : annotatedElement.getValue().getAnnotations()) { Element dataElementRoot = document.createElement(SubmodelElementCollectionXMLConverter.DATA_ELEMENT); Element dataElementContent = SubmodelElementCollectionXMLConverter.buildSubmodelElement(document, dataElement); dataElementRoot.appendChild(dataElementContent); annotationsRoot.appendChild(dataElementRoot); } - + return root; } diff --git a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java index d6eaf68b..2c3600af 100644 --- a/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/factory/xml/converters/submodelelement/relationship/RelationshipElementXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.factory.xml.converters.submodelelement.relationship; @@ -22,23 +37,26 @@ import org.w3c.dom.Element; /** - * Parses <aas:relationshipElement> and builds the RelationshipElement object from it
- * Builds <aas:relationshipElement> from a given RelationshipElement object + * Parses <aas:relationshipElement> and builds the RelationshipElement + * object from it
+ * Builds <aas:relationshipElement> from a given RelationshipElement + * object * * @author conradi * */ public class RelationshipElementXMLConverter extends SubmodelElementXMLConverter { - + public static final String RELATIONSHIP_ELEMENT = "aas:relationshipElement"; public static final String FIRST = "aas:first"; public static final String SECOND = "aas:second"; - - + /** * Builds a RelationshipElement object from the given XML * - * @param xmlObject the Map with the content of XML tag <aas:relationshipElement> + * @param xmlObject + * the Map with the content of XML tag + * <aas:relationshipElement> * @return the parsed RelationshipElement */ public static RelationshipElement parseRelationshipElement(Map xmlObject) { @@ -46,65 +64,74 @@ public static RelationshipElement parseRelationshipElement(Map x populateRelationshipElement(xmlObject, relElement); return relElement; } - + /** - * Parses a Map containing the content of XML tag <aas:relationshipElement> - * and populates a given RelationshipElement object + * Parses a Map containing the content of XML tag + * <aas:relationshipElement> and populates a given RelationshipElement + * object * - * @param xmlObject the Map with the content of XML tag <aas:relationshipElement> - * @param relElement the RelationshipElement to be populated + * @param xmlObject + * the Map with the content of XML tag + * <aas:relationshipElement> + * @param relElement + * the RelationshipElement to be populated */ @SuppressWarnings("unchecked") public static void populateRelationshipElement(Map xmlObject, IRelationshipElement relElement) { Map firstMap = (Map) xmlObject.get(FIRST); Reference first = ReferenceXMLConverter.parseReference(firstMap); - + Map secondMap = (Map) xmlObject.get(SECOND); Reference second = ReferenceXMLConverter.parseReference(secondMap); - + relElement.setValue(new RelationshipElementValue(first, second)); - + populateSubmodelElement(xmlObject, relElement); } - - + /** * Builds the <aas:relationshipElement> XML tag for a RelationshipElement * - * @param document the XML document - * @param relElem the IRelationshipElement to build the XML for - * @return the <aas:relationshipElement> XML tag for the given RelationshipElement + * @param document + * the XML document + * @param relElem + * the IRelationshipElement to build the XML for + * @return the <aas:relationshipElement> XML tag for the given + * RelationshipElement */ public static Element buildRelationshipElement(Document document, IRelationshipElement relElem) { Element relElemRoot = document.createElement(RELATIONSHIP_ELEMENT); populateRelationshipElement(document, relElemRoot, relElem); return relElemRoot; } - + /** * Builds the content for a given <aas:relationshipElement> XML tag * - * @param document the XML document - * @param root the root Element of the new RelationshipElement - * @param relElem the RelationShipElement + * @param document + * the XML document + * @param root + * the root Element of the new RelationshipElement + * @param relElem + * the RelationShipElement */ public static void populateRelationshipElement(Document document, Element root, IRelationshipElement relElem) { populateSubmodelElement(document, root, relElem); - + RelationshipElementValue value = relElem.getValue(); - + IReference first = value.getFirst(); - if(first != null) { + if (first != null) { Element derivedFromRoot = document.createElement(FIRST); - derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, first)); + derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, first)); root.appendChild(derivedFromRoot); - } + } IReference second = value.getSecond(); - if(second != null) { + if (second != null) { Element derivedFromRoot = document.createElement(SECOND); - derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, second)); + derivedFromRoot.appendChild(ReferenceXMLConverter.buildReferenceXML(document, second)); root.appendChild(derivedFromRoot); } - + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java index bcb7d10d..550a6172 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElement.java @@ -1,15 +1,29 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api; - /** * Base interface for all AAS elements * diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java index cb27a8a7..2dfa7ffc 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/IElementContainer.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api; @@ -49,16 +64,18 @@ public interface IElementContainer { * @return */ public Map getOperations(); - + /** * Gets a submodel element by name + * * @param id * @return submodel element */ ISubmodelElement getSubmodelElement(String id); - + /** * Deletes a submodel element by name + * * @param id */ void deleteSubmodelElement(String id); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java index ba54b6b2..5ba66f69 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/ISubmodel.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api; @@ -18,8 +33,7 @@ import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable; /** - * A submodel defines a specific aspect of the asset represented by the - * AAS.
+ * A submodel defines a specific aspect of the asset represented by the AAS.
*
* A submodel is used to structure the digital representation and technical * functionality of an Administration Shell into distinguishable parts. Each @@ -31,12 +45,13 @@ * */ public interface ISubmodel extends IElement, IHasSemantics, IIdentifiable, IQualifiable, IHasDataSpecification, IHasKind, IElementContainer { - + /** - * Gets a {@literal Map} containing the values of all submodelElements + * Gets a {@literal Map} containing the values + * of all submodelElements * * @return a Map with the values of all submodelElements */ public Map getValues(); - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java index bf446692..21087810 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecification.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java index 8b9d837a..f6232326 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationContent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java index 955a51ca..181f02a3 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IDataSpecificationIEC61360Content.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification; @@ -17,24 +32,37 @@ import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings; /** - * Interface for DataSpecification - * In DAAS, this element is named DataSpecificationIEC61360, but for clarity "Content" is added to the interface name + * Interface for DataSpecification In DAAS, this element is named + * DataSpecificationIEC61360, but for clarity "Content" is added to the + * interface name * * @author rajashek, espen * */ public interface IDataSpecificationIEC61360Content extends IDataSpecificationContent { public LangStrings getPreferredName(); + public LangStrings getShortName(); + public String getUnit(); + public IReference getUnitId(); + public String getSourceOfDefinition(); + public String getSymbol(); + public DataTypeIEC61360 getDataType(); + public LangStrings getDefinition(); + public String getValueFormat(); + public Collection getValueList(); + public String getValue(); + public IReference getValueId(); + public LevelType getLevelType(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java index b86fcf98..3dd87063 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IEmbeddedDataSpecification.java @@ -1,20 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** - * DataSpecification containing a DataSpecificationContent - * Difference to the IDataSpecification: - * It is not identifiable, but has a reference to an identifiable DataSpecification template + * DataSpecification containing a DataSpecificationContent Difference to the + * IDataSpecification: It is not identifiable, but has a reference to an + * identifiable DataSpecification template * * @author espen * diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java index e9603f5c..9a634c50 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/IValueReferencePair.java @@ -1,19 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; /** - * A value reference pair within a value list within a value list of the DataSpecificationIEC61360. - * Each value has a global unique id defining its semantic. + * A value reference pair within a value list within a value list of the + * DataSpecificationIEC61360. Each value has a global unique id defining its + * semantic. * * @author espen * diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java index 7dc731c1..c60490ca 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/DataTypeIEC61360.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification.enums; @@ -13,16 +28,15 @@ import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper; /** - * Possible value data types as defined in DAAS for IEC61360 data specification templates + * Possible value data types as defined in DAAS for IEC61360 data specification + * templates * * @author espen * */ public enum DataTypeIEC61360 implements StandardizedLiteralEnum { - BOOLEAN("BOOLEAN"), DATE("DATE"), RATIONAL("RATIONAL"), RATIONAL_MEASURE("RATIONAL_MEASURE"), - REAL_COUNT("REAL_COUNT"), REAL_CURRENCY("REAL_CURRENCY"), REAL_MEASURE("REAL_MEASURE"), STRING("STRING"), - STRING_TRANSLATABLE("STRING_TRANSLATABLE"), - TIME("TIME"), TIME_STAMP("TIME_STAMP"), URL("URL"); + BOOLEAN("BOOLEAN"), DATE("DATE"), RATIONAL("RATIONAL"), RATIONAL_MEASURE("RATIONAL_MEASURE"), REAL_COUNT("REAL_COUNT"), REAL_CURRENCY("REAL_CURRENCY"), REAL_MEASURE("REAL_MEASURE"), STRING("STRING"), STRING_TRANSLATABLE( + "STRING_TRANSLATABLE"), TIME("TIME"), TIME_STAMP("TIME_STAMP"), URL("URL"); private String standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java index 436b2b43..85a3c8f2 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/dataspecification/enums/LevelType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.dataspecification.enums; @@ -13,14 +28,15 @@ import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper; /** - * Possible level types as defined in DAAS for IEC61360 data specification templates + * Possible level types as defined in DAAS for IEC61360 data specification + * templates * * @author espen * */ public enum LevelType implements StandardizedLiteralEnum { MIN("Min"), MAX("Max"), NOM("Nom"), TYP("Typ"); - + private String standardizedLiteral; private LevelType(String standardizedLiteral) { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java index 4fb6faaa..9a9e3102 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IIdentifier.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.identifier; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java index 2775687d..f2a5b256 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/identifier/IdentifierType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.identifier; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java index e75cd689..c6a49ae6 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/parts/IConceptDescription.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.parts; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java index 0809b44b..98198811 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IAdministrativeInformation.java @@ -1,15 +1,29 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier; - /** * Administrative metainformation for an element like version information. * @@ -23,7 +37,7 @@ public interface IAdministrativeInformation extends IHasDataSpecification { * @return */ public String getVersion(); - + /** * Gets the revision of the element * diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java index 9914831d..70b43242 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasDataSpecification.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java index 08cc1cc7..e73f705f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IHasSemantics.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java index 617425e8..4639bd6d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IIdentifiable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier; @@ -18,14 +33,14 @@ * */ -public interface IIdentifiable extends IReferable { +public interface IIdentifiable extends IReferable { /** * Gets the administrative information of an identifiable element. * * @return */ public IAdministrativeInformation getAdministration(); - + /** * Gets theglobally unique identification of the element. * diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java index 2343ffab..b4d12646 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IReferable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java index 79c96e99..66d781c7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/IdShortValidator.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java index 2581347f..774efdf9 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/IHasKind.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind; @@ -14,7 +29,14 @@ * * @author rajashek * -*/ + */ public interface IHasKind { + public default ModelingKind getKind() { + return getModelingKind(); + } + + /** + * @deprecated Please use {@link #getKind()} instead. + */ public ModelingKind getModelingKind(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java index f42d6521..f34addcf 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/haskind/ModelingKind.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind; @@ -41,7 +56,7 @@ private ModelingKind(String standardizedLiteral) { public String getStandardizedLiteral() { return standardizedLiteral; } - + @Override public String toString() { return standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java index b7050ad4..a913cdef 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IConstraint.java @@ -1,18 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable; + /** * Interface for Constraint + * * @author rajashek * -*/ + */ public interface IConstraint { } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java index 0cc79da5..930acc9d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IFormula.java @@ -1,22 +1,39 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable; import java.util.Collection; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; + /** * Interface for Formula + * * @author rajashek * -*/ + */ public interface IFormula extends IConstraint { public Collection getDependsOn(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java index a27ee2f5..f939174e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifiable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable; @@ -13,9 +28,10 @@ /** * Interface for Qualifiable + * * @author rajashek * -*/ + */ public interface IQualifiable { public Collection getQualifiers(); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java index c7c1e811..4dbd7aa8 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/qualifier/qualifiable/IQualifier.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable; @@ -26,6 +41,6 @@ public interface IQualifier extends IHasSemantics, IConstraint { public Object getValue(); public IReference getValueId(); - - public ValueType getValueType(); + + public ValueType getValueType(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java index 5c6f27c7..5ec3bfef 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IKey.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.reference; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java index 852a2e39..f46564ce 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/IReference.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.reference; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java index d8c6347d..81e1ca9c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyElements.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.reference.enums; @@ -26,40 +41,19 @@ public enum KeyElements implements StandardizedLiteralEnum { /** * Enum values of KeyElements */ - GLOBALREFERENCE("GlobalReference"), - FRAGMENTREFERENCE("FragmentReference"), - + GLOBALREFERENCE("GlobalReference"), FRAGMENTREFERENCE("FragmentReference"), + /** * Enum values of ReferableElements */ - ACCESSPERMISSIONRULE("AccessPermissionRule"), - ANNOTATEDRELATIONSHIPELEMENT("AnnotatedRelationshipElement"), - BASICEVENT("BasicEvent"), - BLOB("Blob"), - CAPABILITY("Capability"), - CONCEPTDICTIONARY("ConceptDictionary"), - DATAELEMENT("DataElement"), - FILE("File"), - ENTITY("Entity"), - EVENT("Event"), - MULTILANGUAGEPROPERTY("MultiLanguageProperty"), - OPERATION("Operation"), - PROPERTY("Property"), - RANGE("Range"), - REFERENCEELEMENT("ReferenceElement"), - RELATIONSHIPELEMENT("RelationshipElement"), - SUBMODELELEMENT("SubmodelElement"), - SUBMODELELEMENTCOLLECTION("SubmodelElementCollection"), - VIEW("View"), - + ACCESSPERMISSIONRULE("AccessPermissionRule"), ANNOTATEDRELATIONSHIPELEMENT("AnnotatedRelationshipElement"), BASICEVENT("BasicEvent"), BLOB("Blob"), CAPABILITY("Capability"), CONCEPTDICTIONARY("ConceptDictionary"), DATAELEMENT( + "DataElement"), FILE("File"), ENTITY("Entity"), EVENT("Event"), MULTILANGUAGEPROPERTY("MultiLanguageProperty"), OPERATION("Operation"), PROPERTY( + "Property"), RANGE("Range"), REFERENCEELEMENT("ReferenceElement"), RELATIONSHIPELEMENT("RelationshipElement"), SUBMODELELEMENT("SubmodelElement"), SUBMODELELEMENTCOLLECTION("SubmodelElementCollection"), VIEW("View"), + /** * Enum values of IdentifiableElements */ - ASSET("Asset"), - ASSETADMINISTRATIONSHELL("AssetAdministrationShell"), - CONCEPTDESCRIPTION("ConceptDescription"), - SUBMODEL("Submodel"); - + ASSET("Asset"), ASSETADMINISTRATIONSHELL("AssetAdministrationShell"), CONCEPTDESCRIPTION("ConceptDescription"), SUBMODEL("Submodel"); private String standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java index b8f517ec..4fc4e3f3 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/reference/enums/KeyType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.reference.enums; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java index 69f8e35f..7c8ef6e7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ICapability.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java index 2fde991b..7adf06f8 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement; @@ -26,9 +41,9 @@ */ public interface ISubmodelElement extends IElement, IHasDataSpecification, IReferable, IQualifiable, IHasSemantics, IHasKind { public String getModelType(); - + public Object getValue(); - + public void setValue(Object value); public SubmodelElement getLocalCopy(); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java index 321afdf2..d8361e17 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/ISubmodelElementCollection.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement; @@ -22,21 +37,21 @@ * */ public interface ISubmodelElementCollection extends ISubmodelElement, IElementContainer { - + /** * Gets if the collection is ordered or unordered * * @return */ public boolean isOrdered(); - + /** * Gets if the collection allows duplicates * * @return */ public boolean isAllowDuplicates(); - + /** * Gets all the elements contained in the collection * @@ -60,4 +75,12 @@ public interface ISubmodelElementCollection extends ISubmodelElement, IElementCo */ @Override public Map getOperations(); + + /** + * Gets a {@literal Map} containing the values + * of all submodelElements + * + * @return a Map with the values of all submodelElements + */ + public Map getValues(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java index d7c36173..22140ab6 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/SubmodelElementIdShortBlacklist.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java index 62824a5c..779ed827 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IBlob.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; @@ -18,14 +33,14 @@ */ public interface IBlob extends IDataElement { /** - * Gets the value of the Blob instance of a blob data element. - * The returned value is Base64 encoded. + * Gets the value of the Blob instance of a blob data element. The returned + * value is Base64 encoded. * * @return */ @Override public String getValue(); - + /** * Sets a Base64 encoded value of the BLOB instance of a blob data element. * diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java index 1b216128..1d73894f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IDataElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java index 4c86bcb0..5035607d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IFile.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; @@ -25,7 +40,7 @@ public interface IFile extends IDataElement { */ @Override public String getValue(); - + /** * Sets path and name of the referenced file (with file extension). The path can * be absolute or relative. diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java index af10ec85..2b955e35 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IMultiLanguageProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java index 9f5c4864..9610508b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java index 889ade78..5ddab743 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IRange.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java index 76341558..af9a8999 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/dataelement/IReferenceElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java index 9c0f124d..e2222afc 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/EntityType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity; @@ -25,14 +40,14 @@ public enum EntityType implements StandardizedLiteralEnum { * be part of a self-managed entity. */ COMANAGEDENTITY("CoManagedEntity"), - + /** * Self-Managed Entities have their own AAS but can be part of the bill of * material of a composite self-managed entity. The asset of an I4.0 Component * is a self-managed entity per definition. */ SELFMANAGEDENTITY("SelfManagedEntity"); - + private String standardizedLiteral; private EntityType(String standardizedLiteral) { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java index be095a8d..27ceb96d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/entity/IEntity.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java index 51cd2eea..c67d06de 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IBasicEvent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.event; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java index 7871fa12..080c7884 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/event/IEvent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.event; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java index 583d12a7..7574f327 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IAsyncInvocation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation; @@ -16,7 +31,7 @@ * */ public interface IAsyncInvocation { - + /** * Gets the result of the async Invocation
* Will block if execution is not finished yet @@ -24,12 +39,12 @@ public interface IAsyncInvocation { * @return the result of the Invocation */ public Object getResult(); - + /** * Gets the status of the async Invocation * * @return true if execution is completed; false otherwise */ public boolean isFinished(); - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java index 20a399ed..eae987d1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation; @@ -47,39 +62,52 @@ public interface IOperation extends IElement, ISubmodelElement { /** * Invoke operation with given parameter * - * + * @deprecated Please use either {@link #invoke(SubmodelElement...)} for passing + * SubmodelElements or {@link #invokeSimple(Object...)} for directly + * passing values. * @param params - * Operation parameter + * Operation parameter * @return If multiple values are returned, Object is here a list of Objects */ + @Deprecated public Object invoke(Object... params); - + /** * Invoke operation with parameters wrapped as SubmodelElements * * * @param elems - * Operation parameters + * Operation parameters * @return List of results */ public SubmodelElement[] invoke(SubmodelElement... elems); + /** + * Invoke operation with raw parameters, i.e. not wrapped as SubmodelElements + * + * @param params + * Raw operation parameters + * @return Raw result + */ + public Object invokeSimple(Object... params); + /** * Invoke operation with given parameter asynchronously * * @param params - * Operation parameter + * Operation parameter * @return An IAsyncInvocation */ public IAsyncInvocation invokeAsync(Object... params); /** - * Invoke operation with given parameter asynchronously and use a user-defined timeout + * Invoke operation with given parameter asynchronously and use a user-defined + * timeout * * @param timeout - * The timeout in ms + * The timeout in ms * @param params - * Operation parameter + * Operation parameter * @return An IAsyncInvocation */ public IAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java index 258a8367..30e6077f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/operation/IOperationVariable.java @@ -1,20 +1,37 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; + /** * Interface for OperationVariable + * * @author rajashek * -*/ + */ public interface IOperationVariable { public ISubmodelElement getValue(); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java index 7573d3d5..4aee7ede 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IAnnotatedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java index ce976e8e..da98aaf1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/api/submodelelement/relationship/IRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.api.submodelelement.relationship; @@ -20,7 +35,7 @@ * */ public interface IRelationshipElement extends ISubmodelElement { - + @Override RelationshipElementValue getValue(); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java index a9dcc330..55b4ea98 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected; @@ -17,7 +32,8 @@ import org.eclipse.basyx.vab.modelprovider.VABElementProxy; /** - * Conntected Element superclass; Extends HashMap for local caching used for c# proxy + * Conntected Element superclass; Extends LinkedHashMap for local caching used + * for c# proxy * * @author pschorn * @@ -36,7 +52,6 @@ public ConnectedElement(VABElementProxy proxy) { this.proxy = proxy; } - /** * Returns a live variant of the map. Only use this if access to dynamic data is * intended. Otherwise use {@link #getElem()} diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java index d5c0fa65..6dfdb7bd 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/ConnectedSubmodel.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected; @@ -40,7 +55,6 @@ import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.VABPathTools; - /** * "Connected" implementation of Submodel * @@ -95,7 +109,12 @@ public Collection getEmbeddedDataSpecifications() { @Override public ModelingKind getModelingKind() { - return HasKind.createAsFacade(getElem()).getModelingKind(); + return this.getKind(); + } + + @Override + public ModelingKind getKind() { + return HasKind.createAsFacade(getElem()).getKind(); } @Override @@ -117,7 +136,7 @@ public LangStrings getDescription() { public IReference getParent() { return Referable.createAsFacade(getElem(), getKeyElement()).getParent(); } - + @Override public Collection getQualifiers() { return Qualifiable.createAsFacade(getElem()).getQualifiers(); @@ -130,11 +149,11 @@ public void addSubmodelElement(ISubmodelElement element) { if (element instanceof SubmodelElement) { ((SubmodelElement) element).setParent(getReference()); - + // Convert "value" in SubmodelElementCollection from Map to Collection if (element instanceof SubmodelElementCollection) { Map converted = SubmodelElementMapCollectionConverter.smElementToMap((Map) element); - + getProxy().setValue(path, converted); return; } @@ -144,22 +163,19 @@ public void addSubmodelElement(ISubmodelElement element) { @Override public Map getProperties() { - return ConnectedSubmodelElementFactory.getProperties(getProxy(), MultiSubmodelElementProvider.ELEMENTS, - MultiSubmodelElementProvider.ELEMENTS); + return ConnectedSubmodelElementFactory.getProperties(getProxy(), MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); } @Override public Map getOperations() { - return ConnectedSubmodelElementFactory.getOperations(getProxy(), MultiSubmodelElementProvider.ELEMENTS, - MultiSubmodelElementProvider.ELEMENTS); + return ConnectedSubmodelElementFactory.getOperations(getProxy(), MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); } @Override public Map getSubmodelElements() { - return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(), - MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); + return ConnectedSubmodelElementFactory.getConnectedSubmodelElements(getProxy(), MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); } - + @SuppressWarnings("unchecked") @Override public Map getValues() { @@ -184,19 +200,21 @@ public Submodel getLocalCopy() { /** * Get submodel element by given id + * * @param id * @return specific submodel element */ @SuppressWarnings("unchecked") @Override public ISubmodelElement getSubmodelElement(String id) { - Map node =(Map) getProxy().getValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, id)); + Map node = (Map) getProxy().getValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, id)); ISubmodelElement element = ConnectedSubmodelElementFactory.getConnectedSubmodelElement(getProxy(), MultiSubmodelElementProvider.ELEMENTS, id, node); - return element; + return element; } /** * Delete a submodel element by given id + * * @param id */ @Override diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedCapability.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedCapability.java index 933ae09c..a4b6a9ab 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedCapability.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedCapability.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java index a92532eb..558c01b6 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedEvent.java @@ -1,18 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement; /** - * "Connected" implementation of Event + * "Connected" implementation of Event + * * @author rajashek * */ -public class ConnectedEvent { +public class ConnectedEvent { } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java index d7a365b7..2a66a495 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement; @@ -32,18 +47,19 @@ /** * "Connected" implementation of SubmodelElement + * * @author rajashek * */ public abstract class ConnectedSubmodelElement extends ConnectedElement implements ISubmodelElement { public ConnectedSubmodelElement(VABElementProxy proxy) { - super(proxy); + super(proxy); } protected KeyElements getKeyElement() { return KeyElements.SUBMODELELEMENT; } - + @Override public String getIdShort() { return Referable.createAsFacade(getElem(), getKeyElement()).getIdShort(); @@ -74,9 +90,18 @@ public IReference getSemanticId() { return HasSemantics.createAsFacade(getElem()).getSemanticId(); } + /** + * @deprecated Please use {@link #getKind()} instead. + */ @Override public ModelingKind getModelingKind() { - return HasKind.createAsFacade(getElem()).getModelingKind(); + return this.getKind(); + + } + + @Override + public ModelingKind getKind() { + return HasKind.createAsFacade(getElem()).getKind(); } @@ -89,18 +114,18 @@ public Collection getDataSpecificationReferences() { public Collection getEmbeddedDataSpecifications() { return HasDataSpecification.createAsFacade(getElem()).getEmbeddedDataSpecifications(); } - + @Override @SuppressWarnings("unchecked") public String getModelType() { return (String) ((Map) getElem().get(ModelType.MODELTYPE)).get(ModelType.NAME); } - + @Override public IReference getReference() { return Referable.createAsFacade(getElem(), getKeyElement()).getReference(); } - + @Override public void setValue(Object value) { getProxy().setValue(MultiSubmodelElementProvider.VALUE, value); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java index 7a5a23d3..261c36ee 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementCollection.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement; @@ -65,36 +80,39 @@ public Map getProperties() { public Map getOperations() { return ConnectedSubmodelElementFactory.getOperations(getProxy(), Property.VALUE, ""); } - + @Override protected KeyElements getKeyElement() { return KeyElements.SUBMODELELEMENTCOLLECTION; } - + /** * Get submodel element by given id + * * @param id * @return specific submodel element */ @SuppressWarnings("unchecked") @Override public ISubmodelElement getSubmodelElement(String id) { - Map node =(Map) getProxy().getValue(id); + Map node = (Map) getProxy().getValue(id); ISubmodelElement element = ConnectedSubmodelElementFactory.getConnectedSubmodelElement(getProxy(), "", id, node); - return element; + return element; } /** * Delete a submodel element by given id + * * @param id */ @Override public void deleteSubmodelElement(String id) { getProxy().deleteValue(id); } - + /** * adds a submodel element to the collection + * * @param element */ @SuppressWarnings("unchecked") @@ -110,7 +128,7 @@ public void addSubmodelElement(ISubmodelElement element) { return; } } - + getProxy().setValue(element.getIdShort(), element); } @@ -118,4 +136,9 @@ public void addSubmodelElement(ISubmodelElement element) { public SubmodelElementCollection getLocalCopy() { return SubmodelElementCollection.createAsFacade(getElem()).getLocalCopy(); } + + @Override + public Map getValues() { + return SubmodelElementCollection.createAsFacade(getElemLive()).getValues(); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java index 2deccf4f..8cd95ff8 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/ConnectedSubmodelElementFactory.java @@ -1,18 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement; - import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; @@ -46,7 +60,6 @@ import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.VABPathTools; - /** * Factory creating connected ISubmodelElements from a given VABElementProxy * @@ -58,19 +71,22 @@ public class ConnectedSubmodelElementFactory { /** * Creates connected ISubmodelElements from a VABElementProxy * - * @param rootProxy proxy for the root element - * @param collectionPath path in the proxy for accessing all elements - * @param elementPath path in the proxy for accessing single elements by short ids - * @return A Map containing the created connected ISubmodelElements and their IDs + * @param rootProxy + * proxy for the root element + * @param collectionPath + * path in the proxy for accessing all elements + * @param elementPath + * path in the proxy for accessing single elements by short ids + * @return A Map containing the created connected ISubmodelElements and their + * IDs */ @SuppressWarnings("unchecked") - public static Map getConnectedSubmodelElements(VABElementProxy rootProxy, - String collectionPath, String elementPath) { + public static Map getConnectedSubmodelElements(VABElementProxy rootProxy, String collectionPath, String elementPath) { // Query the whole list of elements - Collection> mapElemList = (Collection>) rootProxy - .getValue(collectionPath); - // Get the type and idShort for each element and create the corresponding connected variant - Map ret = new HashMap<>(); + Collection> mapElemList = (Collection>) rootProxy.getValue(collectionPath); + // Get the type and idShort for each element and create the corresponding + // connected variant + Map ret = new LinkedHashMap<>(); for (Map node : mapElemList) { String idShort = Referable.createAsFacade(node, KeyElements.SUBMODELELEMENT).getIdShort(); ISubmodelElement element = getConnectedSubmodelElement(rootProxy, elementPath, idShort, node); @@ -82,18 +98,20 @@ public static Map getConnectedSubmodelElements(VABElem /** * Creates a Collection of connected ISubmodelElements from a VABElementProxy * - * @param rootProxy proxy for the root element - * @param collectionPath path in the proxy for accessing all elements - * @param elementPath path in the proxy for accessing single elements by short ids + * @param rootProxy + * proxy for the root element + * @param collectionPath + * path in the proxy for accessing all elements + * @param elementPath + * path in the proxy for accessing single elements by short ids * @return A Collection containing the created connected ISubmodelElements */ @SuppressWarnings("unchecked") - public static Collection getElementCollection(VABElementProxy rootProxy, - String collectionPath, String elementPath) { + public static Collection getElementCollection(VABElementProxy rootProxy, String collectionPath, String elementPath) { // Query the whole list of elements - Collection> mapElemList = (Collection>) rootProxy - .getValue(collectionPath); - // Get the type and idShort for each element and create the corresponding connected variant + Collection> mapElemList = (Collection>) rootProxy.getValue(collectionPath); + // Get the type and idShort for each element and create the corresponding + // connected variant Collection ret = new ArrayList<>(); for (Map node : mapElemList) { String idShort = Referable.createAsFacade(node, KeyElements.SUBMODELELEMENT).getIdShort(); @@ -102,18 +120,19 @@ public static Collection getElementCollection(VABElementProxy } return ret; } - + /** * Creates a connected ISubmodelElement by idShort, proxy and map content * - * @param rootProxy proxy for the root element - * @param elementPath path in the proxy for accessing single elements by short ids + * @param rootProxy + * proxy for the root element + * @param elementPath + * path in the proxy for accessing single elements by short ids * @param idShort * @param mapContent * @return The connected variant of the requested submodel element */ - public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy, - String elementPath, String idShort, Map mapContent) { + public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy, String elementPath, String idShort, Map mapContent) { String subPath = VABPathTools.concatenatePaths(elementPath, idShort); VABElementProxy proxy = rootProxy.getDeepProxy(subPath); if (Property.isProperty(mapContent)) { @@ -124,11 +143,11 @@ public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootP return new ConnectedFile(proxy); } else if (SubmodelElementCollection.isSubmodelElementCollection(mapContent)) { return new ConnectedSubmodelElementCollection(proxy); - } else if(MultiLanguageProperty.isMultiLanguageProperty(mapContent)) { + } else if (MultiLanguageProperty.isMultiLanguageProperty(mapContent)) { return new ConnectedMultiLanguageProperty(proxy); - } else if(Range.isRange(mapContent)) { + } else if (Range.isRange(mapContent)) { return new ConnectedRange(proxy); - } else if(ReferenceElement.isReferenceElement(mapContent)) { + } else if (ReferenceElement.isReferenceElement(mapContent)) { return new ConnectedReferenceElement(proxy); } else if (AnnotatedRelationshipElement.isAnnotatedRelationshipElement(mapContent)) { return new ConnectedAnnotatedRelationshipElement(proxy); @@ -136,7 +155,7 @@ public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootP return new ConnectedRelationshipElement(proxy); } else if (Operation.isOperation(mapContent)) { return new ConnectedOperation(proxy); - } else if(BasicEvent.isBasicEvent(mapContent)) { + } else if (BasicEvent.isBasicEvent(mapContent)) { return new ConnectedBasicEvent(proxy); } else if (Capability.isCapability(mapContent)) { return new ConnectedCapability(proxy); @@ -144,24 +163,26 @@ public static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootP return null; } } - + /** * Creates connected IOperations from a VABElementProxy * - * @param rootProxy proxy for the root element - * @param collectionPath path in the proxy for accessing all elements - * @param elementPath path in the proxy for accessing single elements by short ids + * @param rootProxy + * proxy for the root element + * @param collectionPath + * path in the proxy for accessing all elements + * @param elementPath + * path in the proxy for accessing single elements by short ids * @return A Map containing the created connected IOperations and their IDs */ @SuppressWarnings("unchecked") - public static Map getOperations(VABElementProxy rootProxy, String collectionPath, - String elementPath) { + public static Map getOperations(VABElementProxy rootProxy, String collectionPath, String elementPath) { // Query the whole list of elements - Collection> mapElemList = (Collection>) rootProxy - .getValue(collectionPath); + Collection> mapElemList = (Collection>) rootProxy.getValue(collectionPath); - // Get the type and idShort for each operation and create the corresponding connected variant - Map ret = new HashMap<>(); + // Get the type and idShort for each operation and create the corresponding + // connected variant + Map ret = new LinkedHashMap<>(); for (Map node : mapElemList) { String idShort = Referable.createAsFacade(node, KeyElements.OPERATION).getIdShort(); String subPath = VABPathTools.concatenatePaths(elementPath, idShort); @@ -172,24 +193,26 @@ public static Map getOperations(VABElementProxy rootProxy, S } return ret; } - + /** * Creates connected IDataElements from a VABElementProxy * - * @param rootProxy proxy for the root element - * @param collectionPath path in the proxy for accessing all elements - * @param elementPath path in the proxy for accessing single elements by short ids + * @param rootProxy + * proxy for the root element + * @param collectionPath + * path in the proxy for accessing all elements + * @param elementPath + * path in the proxy for accessing single elements by short ids * @return A Map containing the created connected IDataElement and their IDs */ @SuppressWarnings("unchecked") - public static Map getDataElements(VABElementProxy rootProxy, String collectionPath, - String elementPath) { + public static Map getDataElements(VABElementProxy rootProxy, String collectionPath, String elementPath) { // Query the whole list of elements - Collection> mapElemList = (Collection>) rootProxy - .getValue(collectionPath); + Collection> mapElemList = (Collection>) rootProxy.getValue(collectionPath); - // Get the type and idShort for each operation and create the corresponding connected variant - Map ret = new HashMap<>(); + // Get the type and idShort for each operation and create the corresponding + // connected variant + Map ret = new LinkedHashMap<>(); for (Map node : mapElemList) { String idShort = Referable.createAsFacade(node, KeyElements.DATAELEMENT).getIdShort(); String subPath = VABPathTools.concatenatePaths(elementPath, idShort); @@ -200,17 +223,17 @@ public static Map getDataElements(VABElementProxy rootProx ret.put(idShort, new ConnectedBlob(proxy)); } else if (File.isFile(node)) { ret.put(idShort, new ConnectedFile(proxy)); - } else if(MultiLanguageProperty.isMultiLanguageProperty(node)) { + } else if (MultiLanguageProperty.isMultiLanguageProperty(node)) { ret.put(idShort, new ConnectedMultiLanguageProperty(proxy)); - } else if(Range.isRange(node)) { + } else if (Range.isRange(node)) { ret.put(idShort, new ConnectedRange(proxy)); - } else if(ReferenceElement.isReferenceElement(node)) { + } else if (ReferenceElement.isReferenceElement(node)) { ret.put(idShort, new ConnectedReferenceElement(proxy)); } } return ret; } - + /** * Creates connected IProperty elements from VABElementProxy * @@ -220,14 +243,13 @@ public static Map getDataElements(VABElementProxy rootProx * @return */ @SuppressWarnings("unchecked") - public static Map getProperties(VABElementProxy rootProxy, String collectionPath, - String elementPath) { + public static Map getProperties(VABElementProxy rootProxy, String collectionPath, String elementPath) { // Query the whole list of elements Collection> mapElemList = (Collection>) rootProxy.getValue(collectionPath); // Get the type and idShort for each operation and create the corresponding // connected variant - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); for (Map node : mapElemList) { String idShort = Referable.createAsFacade(node, KeyElements.DATAELEMENT).getIdShort(); String subPath = VABPathTools.concatenatePaths(elementPath, idShort); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java index ed81ec41..7c86a703 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedBlob.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -20,13 +35,14 @@ /** * "Connected" implementation of IBlob + * * @author rajashek * */ public class ConnectedBlob extends ConnectedDataElement implements IBlob { - + public ConnectedBlob(VABElementProxy proxy) { - super(proxy); + super(proxy); } @Override @@ -41,9 +57,9 @@ public String getValue() { @Override public String getMimeType() { - return (String) getElem().get(Blob.MIMETYPE); + return (String) getElem().get(Blob.MIMETYPE); } - + @Override protected KeyElements getKeyElement() { return KeyElements.BLOB; @@ -64,7 +80,6 @@ public void setValue(String value) { } } - @Override public byte[] getByteArrayValue() { String value = getValue(); @@ -91,4 +106,3 @@ public void setUTF8String(String text) { setByteArrayValue(byteArray); } } - diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java index 779d9a98..dcc4fe5d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedDataElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -25,7 +40,7 @@ public class ConnectedDataElement extends ConnectedSubmodelElement implements ID public ConnectedDataElement(VABElementProxy proxy) { super(proxy); } - + @Override protected KeyElements getKeyElement() { return KeyElements.DATAELEMENT; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java index 9bb2afac..189fba3c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedFile.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -17,13 +32,14 @@ /** * "Connected" implementation of IFile + * * @author rajashek * */ public class ConnectedFile extends ConnectedDataElement implements IFile { - + public ConnectedFile(VABElementProxy proxy) { - super(proxy); + super(proxy); } @Override @@ -36,7 +52,7 @@ public String getValue() { public String getMimeType() { return (String) getElem().get(File.MIMETYPE); } - + @Override protected KeyElements getKeyElement() { return KeyElements.FILE; @@ -46,7 +62,7 @@ protected KeyElements getKeyElement() { public File getLocalCopy() { return File.createAsFacade(getElem()).getLocalCopy(); } - + @Override public void setValue(String value) { super.setValue(value); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java index 1f5d12c5..5750a2c7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedMultiLanguageProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -21,6 +36,7 @@ /** * "Connected" implementation of IMultiLanguageProperty + * * @author conradi * */ @@ -33,7 +49,7 @@ public ConnectedMultiLanguageProperty(VABElementProxy proxy) { @SuppressWarnings("unchecked") @Override public LangStrings getValue() { - return LangStrings.createAsFacade((Collection>) super.getValue()) ; + return LangStrings.createAsFacade((Collection>) super.getValue()); } @Override diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java index dade353d..4b92bc4c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -48,7 +63,7 @@ public IReference getValueId() { protected T retrieveObject() { return (T) getProxy().getValue(Property.VALUE); } - + @Override protected KeyElements getKeyElement() { return KeyElements.PROPERTY; @@ -56,10 +71,10 @@ protected KeyElements getKeyElement() { @Override public Object getValue() { - Object value = retrieveObject(); - if(value instanceof String) { + Object value = retrieveObject(); + if (value instanceof String) { return ValueTypeHelper.getJavaObject(value, getValueType()); - }else { + } else { return value; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java index fe36a4c1..3e85ec9b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedRange.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -22,6 +37,7 @@ /** * "Connected" implementation of IRange + * * @author conradi * */ @@ -57,11 +73,11 @@ protected KeyElements getKeyElement() { public RangeValue getValue() { return new RangeValue(getMin(), getMax()); } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(RangeValue.isRangeValue(value)) { + if (RangeValue.isRangeValue(value)) { RangeValue rangeValue = RangeValue.createAsFacade((Map) value); setValue(rangeValue); } else { @@ -79,11 +95,8 @@ public void setValue(RangeValue rangeValue) { Object minRaw = rangeValue.getMin(); Object maxRaw = rangeValue.getMax(); - RangeValue prepared = new RangeValue( - ValueTypeHelper.prepareForSerialization(minRaw), - ValueTypeHelper.prepareForSerialization(maxRaw) - ); - + RangeValue prepared = new RangeValue(ValueTypeHelper.prepareForSerialization(minRaw), ValueTypeHelper.prepareForSerialization(maxRaw)); + getProxy().setValue(MultiSubmodelElementProvider.VALUE, prepared); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java index 8b0e148b..f43ec9b2 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/dataelement/ConnectedReferenceElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement; @@ -20,12 +35,13 @@ /** * "Connected" implementation of IReferenceElement + * * @author rajashek * */ public class ConnectedReferenceElement extends ConnectedDataElement implements IReferenceElement { public ConnectedReferenceElement(VABElementProxy proxy) { - super(proxy); + super(proxy); } @SuppressWarnings("unchecked") @@ -33,7 +49,7 @@ public ConnectedReferenceElement(VABElementProxy proxy) { public IReference getValue() { return Reference.createAsFacade((Map) super.getValue()); } - + @Override protected KeyElements getKeyElement() { return KeyElements.REFERENCEELEMENT; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java index f38d274e..a3abeb45 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/event/ConnectedBasicEvent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event; @@ -21,6 +36,7 @@ /** * "Connected" implementation of IBasicEvent + * * @author conradi * */ @@ -35,7 +51,7 @@ public ConnectedBasicEvent(VABElementProxy proxy) { public IReference getObserved() { return Reference.createAsFacade((Map) getElem().getPath(BasicEvent.OBSERVED)); } - + @Override protected KeyElements getKeyElement() { return KeyElements.BASICEVENT; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java index 11365be4..79f0b248 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedAsyncInvocation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation; @@ -34,12 +49,12 @@ public class ConnectedAsyncInvocation implements IAsyncInvocation { private String operationId; private String requestId; - + private VABElementProxy proxy; - + private Object result = null; private boolean resultRetrieved = false; - + @SuppressWarnings("unchecked") public ConnectedAsyncInvocation(VABElementProxy proxy, String operationId, InvocationRequest request) { this.proxy = proxy; @@ -47,7 +62,7 @@ public ConnectedAsyncInvocation(VABElementProxy proxy, String operationId, Invoc CallbackResponse response = CallbackResponse.createAsFacade((Map) proxy.invokeOperation(Operation.INVOKE + OperationProvider.ASYNC, request)); requestId = response.getRequestId(); } - + @Override public Object getResult() { // Wait for Operation to finish @@ -57,26 +72,24 @@ public Object getResult() { } catch (InterruptedException e) { } } - + // Side-effect of isFinished is querying the result. // Thus, it can be assumed, the the result will be available here if (result instanceof Exception) { - throw new OperationExecutionErrorException("Exception while executing Invocation '" - + requestId + "' of Operation '" + operationId + "'"); + throw new OperationExecutionErrorException("Exception while executing Invocation '" + requestId + "' of Operation '" + operationId + "'"); } else if (ExecutionState.FAILED == result) { - throw new OperationExecutionErrorException("Exception while executing Invocation '" + requestId - + "' of Operation '" + operationId + "'; Operation failed"); + throw new OperationExecutionErrorException("Exception while executing Invocation '" + requestId + "' of Operation '" + operationId + "'; Operation failed"); } else if (ExecutionState.TIMEOUT == result) { - throw new OperationExecutionTimeoutException( - "Invocation '" + requestId + "' of Operation '" + operationId + "' timed out"); + throw new OperationExecutionTimeoutException("Invocation '" + requestId + "' of Operation '" + operationId + "' timed out"); } else { return result; } } - + /** - * Queries the operation with the connected proxy to see, if the result is already finished + * Queries the operation with the connected proxy to see, if the result is + * already finished */ @Override public boolean isFinished() { @@ -94,7 +107,7 @@ private void retrieveResultDirectly() { // 1. Retrieve InvocationResponse from proxy Object responseObj = null; try { - responseObj = proxy.getValue(getListPath()); + responseObj = proxy.getValue(getListPath()); } catch (ProviderException e) { // As the Submodel-API does not specify a request to ask whether // the operation is finished, it has to be done via the retrieval of the value. @@ -112,9 +125,9 @@ private void retrieveResultDirectly() { // 2. Cast response to InvocationResponse InvocationResponse response = null; - if ( responseObj instanceof InvocationResponse ) { + if (responseObj instanceof InvocationResponse) { response = (InvocationResponse) responseObj; - } else if ( result instanceof Map ) { + } else if (result instanceof Map) { response = InvocationResponse.createAsFacade((Map) result); } else { // got no valid InvocationResponse @@ -123,19 +136,19 @@ private void retrieveResultDirectly() { // 3. Transform to direct result switch (response.getExecutionState()) { - case COMPLETED: - // Finished => set internal state - resultRetrieved = true; - result = response.getFirstOutput(); - break; - case FAILED: - case TIMEOUT: - // Finished, but no result => set internal state - resultRetrieved = true; - result = response.getExecutionState(); - break; - default: - // Not finished, yet, result hasn't been retrieved + case COMPLETED: + // Finished => set internal state + resultRetrieved = true; + result = response.getFirstOutput(); + break; + case FAILED: + case TIMEOUT: + // Finished, but no result => set internal state + resultRetrieved = true; + result = response.getExecutionState(); + break; + default: + // Not finished, yet, result hasn't been retrieved } } @@ -146,7 +159,7 @@ public String getRequestId() { public String getOperationId() { return operationId; } - + private String getListPath() { return VABPathTools.concatenatePaths(OperationProvider.INVOCATION_LIST, requestId); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java index 4c2e6b3c..9a4cd9e3 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/operation/ConnectedOperation.java @@ -1,18 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; @@ -23,14 +37,13 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable; import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElement; -import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationCheckHelper; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationHelper; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest; import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse; -import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; /** @@ -67,16 +80,9 @@ public Collection getInOutputVariables() { */ @Override public Object invoke(Object... params) { - // Wrap simple params - SubmodelElement[] wrapper = createElementWrapper(params); - - // Invoke with submodel elements - SubmodelElement[] result = invoke(wrapper); - - // Unwrap result wrapper - return unwrapResult(result); + return invokeSimple(params); } - + @SuppressWarnings("unchecked") @Override public SubmodelElement[] invoke(SubmodelElement... elems) { @@ -89,8 +95,7 @@ public SubmodelElement[] invoke(SubmodelElement... elems) { // Extract the output elements Collection outputArguments = response.getOutputArguments(); - List elements = outputArguments.stream().map(IOperationVariable::getValue) - .collect(Collectors.toList()); + List elements = outputArguments.stream().map(IOperationVariable::getValue).collect(Collectors.toList()); // Cast them to an array SubmodelElement[] result = new SubmodelElement[elements.size()]; @@ -100,8 +105,7 @@ public SubmodelElement[] invoke(SubmodelElement... elems) { private InvocationRequest createInvocationRequest(int timeout, SubmodelElement... elems) { // Wrap parameters in operation variables - Collection inputArguments = Arrays.asList(elems).stream().map(OperationVariable::new) - .collect(Collectors.toList()); + Collection inputArguments = Arrays.asList(elems).stream().map(OperationVariable::new).collect(Collectors.toList()); // Generate random request id String requestId = UUID.randomUUID().toString(); @@ -109,38 +113,15 @@ private InvocationRequest createInvocationRequest(int timeout, SubmodelElement.. return new InvocationRequest(requestId, new ArrayList<>(), inputArguments, timeout); } - private SubmodelElement[] createElementWrapper(Object... params) { - Collection inputVariables = getInputVariables(); - if (inputVariables.size() != params.length) { - throw new WrongNumberOfParametersException(getIdShort(), inputVariables, params); - } - - // Copy parameter values into SubmodelElements according to InputVariables - SubmodelElement[] ret = new SubmodelElement[params.length]; - Iterator iterator = inputVariables.iterator(); - int i = 0; - while (iterator.hasNext()) { - IOperationVariable matchedInput = iterator.next(); - ISubmodelElement inputElement = matchedInput.getValue(); - SubmodelElement copy = inputElement.getLocalCopy(); - copy.setValue(params[i]); - ret[i] = copy; - i++; - } - - return ret; - } - @Override public ConnectedAsyncInvocation invokeAsync(Object... params) { - SubmodelElement[] smElements = createElementWrapper(params); - InvocationRequest request = createInvocationRequest(DEFAULT_ASYNC_TIMEOUT, smElements); - return new ConnectedAsyncInvocation(getProxy(), getIdShort(), request); + return invokeAsyncWithTimeout(DEFAULT_ASYNC_TIMEOUT, params); } - + @Override public ConnectedAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... params) { - SubmodelElement[] smElements = createElementWrapper(params); + OperationCheckHelper.checkValidParameterLength(params.length, getIdShort(), getInputVariables()); + SubmodelElement[] smElements = OperationHelper.wrapParameters(getInputVariables(), params); InvocationRequest request = createInvocationRequest(timeout, smElements); return new ConnectedAsyncInvocation(getProxy(), getIdShort(), request); } @@ -149,7 +130,7 @@ public ConnectedAsyncInvocation invokeAsyncWithTimeout(int timeout, Object... pa protected KeyElements getKeyElement() { return KeyElements.OPERATION; } - + @Override public Object getValue() { throw new UnsupportedOperationException("An Operation has no value"); @@ -159,32 +140,18 @@ public Object getValue() { public void setValue(Object value) { throw new UnsupportedOperationException("An Operation has no value"); } - - @SuppressWarnings("unchecked") - private Object unwrapResult(Object result) { - if (result instanceof Collection) { - Collection coll = (Collection) result; - if (coll.isEmpty()) { - return result; - } - Object resultWrapper = coll.iterator().next(); - if (resultWrapper instanceof Map) { - Map map = (Map) resultWrapper; - if (map.get(Referable.IDSHORT).equals("Response") && map.get(Property.VALUE) != null) { - return map.get(Property.VALUE); - } - } - } else if (result instanceof SubmodelElement[]) { - SubmodelElement[] arr = (SubmodelElement[]) result; - if (arr.length > 0 && arr[0] instanceof Map) { - return arr[0].getValue(); - } - } - return result; - } @Override public Operation getLocalCopy() { return Operation.createAsFacade(getElem()).getLocalCopy(); } + + @Override + public Object invokeSimple(Object... params) { + OperationCheckHelper.checkValidParameterLength(params.length, getIdShort(), getInputVariables()); + OperationCheckHelper.checkSubmodelElementExpectedTypes(params, getInputVariables()); + SubmodelElement[] wrapper = OperationHelper.wrapParameters(getInputVariables(), params); + SubmodelElement[] result = invoke(wrapper); + return OperationHelper.unwrapResult(result); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java index 6a8133ca..390e27ff 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedAnnotatedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java index 735ae6fb..71a5e55e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/connected/submodelelement/relationship/ConnectedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship; @@ -29,12 +44,12 @@ public class ConnectedRelationshipElement extends ConnectedSubmodelElement imple public ConnectedRelationshipElement(VABElementProxy proxy) { super(proxy); } - + @Override protected KeyElements getKeyElement() { return KeyElements.RELATIONSHIPELEMENT; } - + @SuppressWarnings("unchecked") @Override public RelationshipElementValue getValue() { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java index c3293b53..938d3b91 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnum.java @@ -1,17 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.enumhelper; /** - * Enums with this interface hold a custom string literal that is used during e.g. XML serialization. - * You may use the {@link StandardizedLiteralEnumHelper} to map a custom string literal to an enum. + * Enums with this interface hold a custom string literal that is used during + * e.g. XML serialization. You may use the {@link StandardizedLiteralEnumHelper} + * to map a custom string literal to an enum. * * @author alexandergordt */ diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java index 48dde838..80eddd24 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/enumhelper/StandardizedLiteralEnumHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.enumhelper; @@ -13,29 +28,34 @@ /** * Helper class to map custom string literals to StandardizedLiteralEnums. - * + * * @author alexandergordt */ public class StandardizedLiteralEnumHelper { /** * Maps string literals of {@link StandardizedLiteralEnum}s to enum constants. - * The string literals read via getStandardizedLiteral() from the enum constants. + * The string literals read via getStandardizedLiteral() from the enum + * constants. * - * @param Enum class implementing StandardizedLiteralEnum - * @param clazz Target enum with matching custom string literal - * @param literal The literal as contained in e.g. XML schema + * @param + * Enum class implementing StandardizedLiteralEnum + * @param clazz + * Target enum with matching custom string literal + * @param literal + * The literal as contained in e.g. XML schema * @return Enum constant - * @throws IllegalArgumentException when string literal is not found in enum. + * @throws IllegalArgumentException + * when string literal is not found in enum. */ public static T fromLiteral(Class clazz, String literal) { if (Strings.isNullOrEmpty(literal)) { return null; } - + T[] enumConstants = clazz.getEnumConstants(); - for(T constant : enumConstants) { - if(constant.getStandardizedLiteral().equals(literal)) { + for (T constant : enumConstants) { + if (constant.getStandardizedLiteral().equals(literal)) { return constant; } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/ElementContainerValuesHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/ElementContainerValuesHelper.java new file mode 100644 index 00000000..7d5f4025 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/ElementContainerValuesHelper.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.submodel.metamodel.facade; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.IElementContainer; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings; + +/** + * Helper class for getting the /values Map from a Element Container. + * + * @author conradi, haque + * + */ +public class ElementContainerValuesHelper { + + /** + * Gets the Values from a {@link IElementContainer} + * + * @param container + * the {@link IElementContainer} to get the values from. + * @return A Map mapping idShort to the value of the SubmodelElement + */ + @SuppressWarnings("unchecked") + public static Map getSubmodelValue(IElementContainer container) { + Map elements = container.getSubmodelElements(); + + return (Map) handleValue(elements.values()); + } + + @SuppressWarnings("unchecked") + private static Object handleValue(Object value) { + // Check if it is a collection but not a LangStrings (is internally also a + // Collection) + if (value instanceof Collection && !(value instanceof LangStrings)) { + return handleValueCollection((Collection) value); + } else { + // The value is not a collection -> return it as is + return value; + } + } + + private static Map handleValueCollection(Collection collection) { + Map ret = new LinkedHashMap<>(); + for (ISubmodelElement element : collection) { + try { + ret.put(element.getIdShort(), handleValue(element.getValue())); + } catch (UnsupportedOperationException e) { + // this Element has no value (e.g. an Operation) + // -> just ignore it + } + } + return ret; + } + +} diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java index d459599d..59a5287a 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelElementMapCollectionConverter.java @@ -1,197 +1,285 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.facade; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.basyx.aas.metamodel.exception.IdShortDuplicationException; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory; import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; - +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity; /** - * This class provides the functionality to convert the - * smElements of a Submodel/SubmodelElementCollection from a Collection to a Map and vice versa.
+ * This class provides the functionality to convert the smElements of a + * Submodel/SubmodelElementCollection from a Collection to a Map and vice + * versa.
* The given Submodel/Map is not changed.
- * This is necessary, because internally smElements are represented as Map and externally as Collection. + * This is necessary, because internally smElements are represented as Map and + * externally as Collection. * * @author conradi * */ public class SubmodelElementMapCollectionConverter { - - + /** * Builds a Submodel from a given Map.
- * Converts the Submodel.SUBMODELELEMENT entry of a Map to a {@literal Map}.
+ * Converts the Submodel.SUBMODELELEMENT entry of a Map to a + * {@literal Map}.
* Creates Facades for all smElements. * - * @param submodel a Map representing the Submodel to be converted. + * @param submodel + * a Map representing the Submodel to be converted. * @return a new Submodel made from the given Map with the smElements as Map */ public static Submodel mapToSM(Map submodel) { - - // Put the content of the Map into a SM and replace its smElements with the new Map of smElements + + // Put the content of the Map into a SM and replace its smElements with the new + // Map of smElements Submodel ret = new Submodel(); ret.setMap(submodel); - + Object smElements = submodel.get(Submodel.SUBMODELELEMENT); - + ret.put(Submodel.SUBMODELELEMENT, convertCollectionToIDMap(smElements)); - + return ret; } - + /** * Converts a given Submodel to a Map
- * Converts the Submodel.SUBMODELELEMENT entry of a Submodel to a Collection.
+ * Converts the Submodel.SUBMODELELEMENT entry of a Submodel to a + * Collection.
* - * @param submodel the Submodel to be converted. - * @return a Map made from the given Submodel containing the smElements as Collection. + * @param submodel + * the Submodel to be converted. + * @return a Map made from the given Submodel containing the smElements as + * Collection. */ @SuppressWarnings("unchecked") - public static Map smToMap(Submodel submodel) { - + public static Map smToMap(Submodel submodel) { + // Get the smElements Map from the given Submodel Map smElements = submodel.getSubmodelElements(); - + // Put the Entries of the SM in a new Map - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); ret.putAll(submodel); - - // Feed all contained smElements through smElementToMap to deal with smElemCollections - List> newElements = smElements.values().stream() - .map(e -> smElementToMap((Map) e)).collect(Collectors.toList()); - + + // Feed all contained smElements through smElementToMap to deal with + // smElemCollections + List> newElements = smElements.values().stream().map(e -> smElementToMap((Map) e)).collect(Collectors.toList()); + // Replace the smElements Map with the Collection of Elements ret.put(Submodel.SUBMODELELEMENT, newElements); - + return ret; } - /** * Builds a SubmodelElementCollection from a given Map.
- * Converts the Property.VALUE entry of a Map to a {@literal Map}.
+ * Converts the Property.VALUE entry of a Map to a + * {@literal Map}.
* Creates Facades for all smElements. * - * @param smECollection a Map representing the SubmodelElementCollection to be converted. - * @return a new SubmodelElementCollection made from the given Map with the smElements as Map + * @param smECollection + * a Map representing the SubmodelElementCollection to be converted. + * @return a new SubmodelElementCollection made from the given Map with the + * smElements as Map */ public static SubmodelElementCollection mapToSmECollection(Map smECollection) { - - // Put the content of the Map into a SM and replace its smElements with the new Map of smElements + + // Put the content of the Map into a SM and replace its smElements with the new + // Map of smElements SubmodelElementCollection ret = new SubmodelElementCollection(); ret.setMap(smECollection); - + Object smElements = smECollection.get(Property.VALUE); - + ret.put(Property.VALUE, convertCollectionToIDMap(smElements)); - + return ret; } - + /** - * Converts a given SubmodelElementCollection to a Map
- * Converts the Property.VALUE entry of a SubmodelElementCollection to a Collection.
- * If given Element is not a SubmodelElementCollection it will be returned unchanged. + * Converts a given SubmodelElement to a Map
+ * Converts the Property.VALUE entry of a SubmodelElementCollection to a + * Collection.
+ * Converts the statement entry of Entity, if it containes a + * SubmodelElementCollection as described above.
+ * If given Element is not a SubmodelElementCollection or an Entity with a + * SubmodelElementCollection as statement, it will be returned unchanged. * - * @param smElement the SubmodelElement to be converted. + * @param smElement + * the SubmodelElement to be converted. * @return a Map made from the given SubmodelElement. */ - public static Map smElementToMap(Map smElement) { - - if(!SubmodelElementCollection.isSubmodelElementCollection((Map) smElement)) { - return (Map) smElement; + public static Map smElementToMap(Map smElement) { + if (SubmodelElementCollection.isSubmodelElementCollection(smElement)) { + return convertSMC(smElement); + } else if (Entity.isEntity(smElement)) { + return convertEntity(smElement); + } else { + return smElement; } - - // Put the Entries of the SM in a new Map - Map ret = new HashMap<>(); + + } + + @SuppressWarnings("unchecked") + private static Map convertEntity(Map smElement) { + Map ret = new LinkedHashMap<>(); ret.putAll(smElement); - + + Collection> statements = (Collection>) smElement.get(Entity.STATEMENT); + Collection> convertedStatements = convertStatementList(statements); + + ret.put(Entity.STATEMENT, convertedStatements); + + return ret; + } + + private static Collection> convertStatementList(Collection> statements) { + return statements.stream().map(SubmodelElementMapCollectionConverter::smElementToMap).collect(Collectors.toList()); + } + + private static Map convertSMC(Map smElement) { + Map ret = new LinkedHashMap<>(); + ret.putAll(smElement); + ret.put(Property.VALUE, convertIDMapToCollection(smElement.get(Property.VALUE))); - + return ret; } - - + /** - * Converts a given smElement Collection/Map to a {@literal Map}. + * Converts a given smElement Collection/Map to a + * {@literal Map}. * - * @param smElements the smElements to be converted + * @param smElements + * the smElements to be converted * @return a {@literal Map} */ @SuppressWarnings("unchecked") public static Map convertCollectionToIDMap(Object smElements) { - Map smElementsMap = new HashMap<>(); - - if(smElements == null) { + Map smElementsMap = new LinkedHashMap<>(); + if (smElements == null) { // if null was given, return an empty Map return smElementsMap; } - + // SubmodelElemets can be given as Map, Set or List // If it is a Set or List, convert it to a Map first - if(smElements instanceof Collection) { + if (smElements instanceof Collection) { Collection smElementsSet = (Collection) smElements; - for (Object o: smElementsSet) { + for (Object o : smElementsSet) { Map smElement = (Map) o; String id = (String) smElement.get(Referable.IDSHORT); + + if (smElementsMap.containsKey(id)) { + throw new IdShortDuplicationException(smElementsMap); + } + smElementsMap.put(id, smElement); } - } else if(smElements instanceof Map){ + } else if (smElements instanceof Map) { + if (isDuplicateIdShortPresentInSubmodelElements((Map) smElements)) { + throw new IdShortDuplicationException(smElementsMap); + } + smElementsMap = (Map) smElements; } else { throw new RuntimeException("Elements must be given as Map or Collection"); } - + // Iterate through all SubmodelElements and create Facades for them - smElementsMap.replaceAll((id, smElement) -> - SubmodelElementFacadeFactory.createSubmodelElement((Map) smElement)); - + smElementsMap.replaceAll((id, smElement) -> SubmodelElementFacadeFactory.createSubmodelElement((Map) smElement)); + return smElementsMap; } - - + + /** + * Checks if there are two elements in the provided Submodel Elements with the + * same IdShort
+ * + * @param Submodel + * Elements + * @return True if there is duplicate IdShort present, otherwise False. + */ + @SuppressWarnings("unchecked") + private static boolean isDuplicateIdShortPresentInSubmodelElements(Map submodelElements) { + Map helperMap = new LinkedHashMap<>(); + + for (String key : submodelElements.keySet()) { + Map submodelElement = (Map) submodelElements.get(key); + + if (helperMap.containsKey(submodelElement.get(Referable.IDSHORT))) { + return true; + } + + helperMap.put(key, submodelElements.get(key)); + } + + return false; + } + /** - * Converts a given {@literal Map} to a smElement Collection. + * Converts a given {@literal Map} to a smElement + * Collection. * - * @param map the map to be converted + * @param map + * the map to be converted * @return {@literal Collection} */ @SuppressWarnings("unchecked") public static Collection> convertIDMapToCollection(Object map) { Collection smElements = null; - + // Check if the contained value is a Map or a Collection - if(map instanceof Collection) { - // It it is a Collection proceed, as there could be nested Collections that need conversion + if (map instanceof Collection) { + // It it is a Collection proceed, as there could be nested Collections that need + // conversion smElements = (Collection) map; - } else if(map instanceof Map) { + } else if (map instanceof Map) { smElements = ((Map) map).values(); } else { throw new RuntimeException("The SubmodelElementCollection contains neither a Collection nor a Map as value."); } - - // Feed all contained smElements recursively through smElementToMap again to deal with nested smElemCollections - List> newElements = smElements.stream() - .map(e -> smElementToMap((Map) e)).collect(Collectors.toList()); - + + // Feed all contained smElements recursively through smElementToMap again to + // deal with nested smElemCollections + List> newElements = smElements.stream().map(e -> smElementToMap((Map) e)).collect(Collectors.toList()); + return newElements; } - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java index 21410126..05f79b8d 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeCustomSemantics.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.facade; @@ -27,19 +42,17 @@ import org.eclipse.basyx.submodel.metamodel.map.reference.Key; import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; - - - - /** - * Facade class that supports the development and access of sub models using IRDI (International Registration Data Identifier) semantic definitions + * Facade class that supports the development and access of sub models using + * IRDI (International Registration Data Identifier) semantic definitions * * @author kuhn * */ public class SubmodelFacadeCustomSemantics extends Submodel { /** - * Constructor without arguments - create a sub model with all meta properties empty / set to default values + * Constructor without arguments - create a sub model with all meta properties + * empty / set to default values */ public SubmodelFacadeCustomSemantics() { // Create sub model @@ -81,14 +94,10 @@ public SubmodelFacadeCustomSemantics() { * Sub model revision */ public SubmodelFacadeCustomSemantics(String semantics, IdentifierType idType, String id, String idShort, String category, LangStrings description, Constraint constraint, HasDataSpecification dataSpecification, ModelingKind kind, - String version, - String revision) { + String version, String revision) { // Create sub model super(new HasSemantics(new Reference(Collections.singletonList(new Key(KeyElements.GLOBALREFERENCE, false, semantics, KeyType.CUSTOM)))), - new Identifiable(version, revision, idShort, category, description, IdentifierType.CUSTOM, id), - new Qualifiable(constraint), - dataSpecification, - new HasKind(kind)); + new Identifiable(version, revision, idShort, category, description, IdentifierType.CUSTOM, id), new Qualifiable(constraint), dataSpecification, new HasKind(kind)); } /** @@ -129,11 +138,7 @@ public SubmodelFacadeCustomSemantics(String semantics, IdentifierType idType, St public SubmodelFacadeCustomSemantics(String semantics, IdentifierType idType, String id, String idShort, String category, LangStrings description, Collection qualifier, Constraint constraint, HasDataSpecification dataSpecification, ModelingKind kind, String version, String revision) { // Create sub model - super(new HasSemantics(new Reference(Collections.singletonList(new Key(KeyElements.GLOBALREFERENCE, false, semantics, KeyType.CUSTOM)))), - new Identifiable(version, revision, idShort, category, description, idType, id), - new Qualifiable(qualifier), - dataSpecification, - new HasKind(kind)); + super(new HasSemantics(new Reference(Collections.singletonList(new Key(KeyElements.GLOBALREFERENCE, false, semantics, KeyType.CUSTOM)))), new Identifiable(version, revision, idShort, category, description, idType, id), + new Qualifiable(qualifier), dataSpecification, new HasKind(kind)); } } - diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java index 017eb70b..aa37b483 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelFacadeIRDISemantics.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.facade; @@ -81,13 +96,10 @@ public SubmodelFacadeIRDISemantics() { * Sub model revision */ public SubmodelFacadeIRDISemantics(String semantics, IdentifierType idType, String id, String idShort, String category, LangStrings description, Constraint constraint, HasDataSpecification dataSpecification, ModelingKind kind, - String version, - String revision) { + String version, String revision) { // Create sub model super(new HasSemantics(new Reference(Collections.singletonList(new Key(KeyElements.GLOBALREFERENCE, false, semantics, KeyType.IRDI)))), new Identifiable(version, revision, idShort, category, description, IdentifierType.CUSTOM, id), - new Qualifiable(constraint), - dataSpecification, - new HasKind(kind)); + new Qualifiable(constraint), dataSpecification, new HasKind(kind)); } /** @@ -127,10 +139,7 @@ public SubmodelFacadeIRDISemantics(String semantics, IdentifierType idType, Stri public SubmodelFacadeIRDISemantics(String semantics, IdentifierType idType, String id, String idShort, String category, LangStrings description, Collection qualifier, Constraint constraint, HasDataSpecification dataSpecification, ModelingKind kind, String version, String revision) { // Create sub model - super(new HasSemantics(new Reference(Collections.singletonList(new Key(KeyElements.GLOBALREFERENCE, false, semantics, KeyType.IRDI)))), - new Identifiable(version, revision, idShort, category, description, idType, id), - new Qualifiable(qualifier), - dataSpecification, - new HasKind(kind)); + super(new HasSemantics(new Reference(Collections.singletonList(new Key(KeyElements.GLOBALREFERENCE, false, semantics, KeyType.IRDI)))), new Identifiable(version, revision, idShort, category, description, idType, id), + new Qualifiable(qualifier), dataSpecification, new HasKind(kind)); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java index 8bf2b524..14f46030 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/SubmodelValuesHelper.java @@ -1,67 +1,41 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 - ******************************************************************************/ -package org.eclipse.basyx.submodel.metamodel.facade; + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +* +* SPDX-License-Identifier: MIT +******************************************************************************/ -import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; -import org.eclipse.basyx.submodel.metamodel.map.Submodel; -import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings; +package org.eclipse.basyx.submodel.metamodel.facade; /** * Helperclass for getting the /values Map from a Submodel. * + * This class is deprecated and replaces by {@link ElementContainerValuesHelper} + * Please use {@link ElementContainerValuesHelper} instead of this + * * @author conradi * */ -public class SubmodelValuesHelper { - - /** - * Gets the Values from a Submodel - * - * @param sm the Submodel to get the values from. - * @return A Map mapping idShort to the value of the SubmodelElement - */ - @SuppressWarnings("unchecked") - public static Map getSubmodelValue(Submodel sm) { - Map elements = sm.getSubmodelElements(); - - return (Map) handleValue(elements.values()); - } - - - @SuppressWarnings("unchecked") - private static Object handleValue(Object value) { - // Check if it is a collection but not a LangStrings (is internally also a Collection) - if (value instanceof Collection && !(value instanceof LangStrings)) { - return handleValueCollection((Collection) value); - } else { - // The value is not a collection -> return it as is - return value; - } - } - +@Deprecated +public class SubmodelValuesHelper extends ElementContainerValuesHelper { - private static Map handleValueCollection(Collection collection) { - Map ret = new HashMap<>(); - for(ISubmodelElement element: collection) { - try { - ret.put(element.getIdShort(), handleValue(element.getValue())); - } catch (UnsupportedOperationException e) { - // this Element has no value (e.g. an Operation) - // -> just ignore it - } - } - return ret; - } - } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java index 5abbf257..7ce46aaa 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/facade/submodelelement/SubmodelElementFacadeFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.facade.submodelelement; @@ -37,7 +52,8 @@ public class SubmodelElementFacadeFactory { /** * Takes a Map and creates the corresponding SubmodelElement as facade * - * @param submodelElement a Map containing the information of a SubmodelElement + * @param submodelElement + * a Map containing the information of a SubmodelElement * @return the actual of the given SubmodelElement map created as facade */ public static ISubmodelElement createSubmodelElement(Map submodelElement) { @@ -72,5 +88,4 @@ public static ISubmodelElement createSubmodelElement(Map submode } } - } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java index e51ca031..4d907996 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/Submodel.java @@ -1,17 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -32,7 +47,7 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; -import org.eclipse.basyx.submodel.metamodel.facade.SubmodelValuesHelper; +import org.eclipse.basyx.submodel.metamodel.facade.ElementContainerValuesHelper; import org.eclipse.basyx.submodel.metamodel.map.helper.ElementContainerHelper; import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType; import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation; @@ -79,12 +94,13 @@ public Submodel() { putAll(new ModelType(MODELTYPE)); setModelingKind(ModelingKind.INSTANCE); - put(SUBMODELELEMENT, new HashMap()); + put(SUBMODELELEMENT, new LinkedHashMap()); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort * @param identification */ @@ -94,12 +110,10 @@ public Submodel(String idShort, IIdentifier identification) { setIdShort(idShort); } - /** * Constructor */ - public Submodel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable, - HasDataSpecification specification, HasKind hasKind) { + public Submodel(HasSemantics semantics, Identifiable identifiable, Qualifiable qualifiable, HasDataSpecification specification, HasKind hasKind) { this(); // Add qualifiers putAll(semantics); @@ -109,7 +123,7 @@ public Submodel(HasSemantics semantics, Identifiable identifiable, Qualifiable q putAll(hasKind); // Attributes - put(SUBMODELELEMENT, new HashMap()); + put(SUBMODELELEMENT, new LinkedHashMap()); } /** @@ -133,21 +147,21 @@ public static Submodel createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Submodel.class, map); } - + if (!map.containsKey(SUBMODELELEMENT)) { map.put(SUBMODELELEMENT, new ArrayList<>()); } - return SubmodelElementMapCollectionConverter.mapToSM(map); + return SubmodelElementMapCollectionConverter.mapToSM(map); } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { @@ -203,13 +217,28 @@ public void setEmbeddedDataSpecifications(Collection HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications); } + /** + * @deprecated Please use {@link #getKind()} instead. + */ @Override public ModelingKind getModelingKind() { - return HasKind.createAsFacade(this).getModelingKind(); + return this.getKind(); } + /** + * @deprecated Please use {@link #setKind(ModelingKind)} instead. + */ public void setModelingKind(ModelingKind kind) { - HasKind.createAsFacade(this).setModelingKind(kind); + this.setKind(kind); + } + + @Override + public ModelingKind getKind() { + return HasKind.createAsFacade(this).getKind(); + } + + public void setKind(ModelingKind kind) { + HasKind.createAsFacade(this).setKind(kind); } @Override @@ -224,7 +253,7 @@ public void setIdShort(String id) { public void setProperties(Map properties) { // first, remove all properties Set> elementSet = getSubmodelElements().entrySet(); - for ( Iterator> iterator = elementSet.iterator(); iterator.hasNext(); ) { + for (Iterator> iterator = elementSet.iterator(); iterator.hasNext();) { Entry entry = iterator.next(); if (entry.getValue() instanceof IProperty) { iterator.remove(); @@ -288,7 +317,7 @@ public void addSubmodelElement(ISubmodelElement element) { @Override public Map getProperties() { - Map properties = new HashMap<>(); + Map properties = new LinkedHashMap<>(); getSubmodelElements().values().forEach(e -> { if (e instanceof IProperty) { properties.put(e.getIdShort(), (IProperty) e); @@ -299,7 +328,7 @@ public Map getProperties() { @Override public Map getOperations() { - Map operations = new HashMap<>(); + Map operations = new LinkedHashMap<>(); getSubmodelElements().values().forEach(e -> { if (e instanceof IOperation) { operations.put(e.getIdShort(), (IOperation) e); @@ -307,7 +336,7 @@ public Map getOperations() { }); return operations; } - + @SuppressWarnings("unchecked") @Override public Map getSubmodelElements() { @@ -316,9 +345,9 @@ public Map getSubmodelElements() { @Override public Map getValues() { - return SubmodelValuesHelper.getSubmodelValue(this); + return ElementContainerValuesHelper.getSubmodelValue(this); } - + @Override public Collection getQualifiers() { return Qualifiable.createAsFacade(this).getQualifiers(); @@ -335,6 +364,7 @@ public IReference getReference() { /** * Retrieves an element from element collection + * * @param id * @return retrieved element */ @@ -346,6 +376,7 @@ public ISubmodelElement getSubmodelElement(String id) { /** * Deletes an element from element collection + * * @param id */ @Override diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java index 9c8faac5..a224e4f8 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationContent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.dataspecification; @@ -20,7 +35,8 @@ public class DataSpecificationContent extends VABModelMap implements IDa * * @param map * a DataSpecificationContent object as raw map - * @return a DataSpecificationContent object, that behaves like a facade for the given map + * @return a DataSpecificationContent object, that behaves like a facade for the + * given map */ public static DataSpecificationContent createAsFacade(Map map) { if (map == null) { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java index 4faeb686..e2d8703c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.dataspecification; @@ -19,14 +34,14 @@ import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; /** - * An embedded DataSpecification that uses the DataSpecificationIEC61360 as a template + * An embedded DataSpecification that uses the DataSpecificationIEC61360 as a + * template * * @author espen */ public class DataSpecificationIEC61360 extends EmbeddedDataSpecification { public static final String TEMPLATE_IRI = "www.admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360"; - public static final Reference TEMPLATE_REFERENCE = new Reference( - new Key(KeyElements.GLOBALREFERENCE, false, TEMPLATE_IRI, KeyType.IRI)); + public static final Reference TEMPLATE_REFERENCE = new Reference(new Key(KeyElements.GLOBALREFERENCE, false, TEMPLATE_IRI, KeyType.IRI)); /** * Creates an empty DataSpecificationIEC61360 diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java index 154d3dc6..82b8a447 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/DataSpecificationIEC61360Content.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.dataspecification; @@ -46,15 +61,14 @@ public class DataSpecificationIEC61360Content extends VABModelMap implem /** * Constructor */ - public DataSpecificationIEC61360Content() {} + public DataSpecificationIEC61360Content() { + } /** * Constructor */ - public DataSpecificationIEC61360Content(LangStrings preferredName, LangStrings shortName, String unit, - IReference unitId, String sourceOfDefinition, String symbol, DataTypeIEC61360 dataType, - LangStrings definition, String valueFormat, Collection valueList, String value, - IReference valueId, LevelType levelType) { + public DataSpecificationIEC61360Content(LangStrings preferredName, LangStrings shortName, String unit, IReference unitId, String sourceOfDefinition, String symbol, DataTypeIEC61360 dataType, LangStrings definition, String valueFormat, + Collection valueList, String value, IReference valueId, LevelType levelType) { // Default values put(PREFERREDNAME, preferredName); put(SHORTNAME, shortName); @@ -173,7 +187,7 @@ public String getValueFormat() { public Collection getValueList() { ArrayList result = new ArrayList<>(); Object list = get(DataSpecificationIEC61360Content.VALUELIST); - if ( !(list instanceof Collection) ) { + if (!(list instanceof Collection)) { return result; } for (Map pair : (Collection>) list) { @@ -198,7 +212,7 @@ public String getValue() { public IReference getValueId() { return Reference.createAsFacade((Map) get(DataSpecificationIEC61360Content.VALUEID)); } - + /** * @return The level types */ diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java index aad99f5d..79520d67 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/EmbeddedDataSpecification.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.dataspecification; @@ -27,7 +42,8 @@ public class EmbeddedDataSpecification extends VABModelMap implements IE * * @param map * a EmbeddedDataSpecification object as raw map - * @return a EmbeddedDataSpecification object, that behaves like a facade for the given map + * @return a EmbeddedDataSpecification object, that behaves like a facade for + * the given map */ public static EmbeddedDataSpecification createAsFacade(Map map) { if (map == null) { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java index d3668441..79e3ae58 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/dataspecification/ValueReferencePair.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.dataspecification; @@ -22,8 +37,9 @@ import org.eclipse.basyx.vab.model.VABModelMap; /** - * The map implementation for a value reference pair within a value list of the DataSpecificationIEC61360. - * Each value has a global unique id defining its semantic. + * The map implementation for a value reference pair within a value list of the + * DataSpecificationIEC61360. Each value has a global unique id defining its + * semantic. * * @author espen * @@ -35,7 +51,8 @@ public class ValueReferencePair extends VABModelMap implements IValueRef /** * Constructor */ - public ValueReferencePair() {} + public ValueReferencePair() { + } /** * Constructs a reference based on an {@link IIdentifiable} and additional @@ -54,33 +71,31 @@ public ValueReferencePair(String value, IReference valueId) { * * @param map * a ValueReferencePair object as raw map - * @return a ValueReferencePair object, that behaves like a facade for the given map + * @return a ValueReferencePair object, that behaves like a facade for the given + * map */ public static ValueReferencePair createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(ValueReferencePair.class, map); } - + ValueReferencePair ret = new ValueReferencePair(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ @SuppressWarnings("unchecked") public static boolean isValid(Map map) { - return map != null && - map.containsKey(VALUE) && - map.containsKey(VALUEID) && - Reference.isValid((Map)map.get(VALUEID)); + return map != null && map.containsKey(VALUE) && map.containsKey(VALUEID) && Reference.isValid((Map) map.get(VALUEID)); } @Override diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java index 2ce6438b..8380ed4b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/helper/ElementContainerHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.helper; @@ -16,18 +31,19 @@ /** * Contains helper methods of element container + * * @author haque * */ public class ElementContainerHelper { - + public static ISubmodelElement getElementById(Map elements, String id) { if (elements != null && elements.containsKey(id)) { return elements.get(id); } throw new ResourceNotFoundException("Submodel Element with id: " + id + " does not exist"); } - + public static void removeElementById(Map elements, String id) { if (elements != null && elements.containsKey(id)) { elements.remove(id); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java index a1b77a36..45a9a6ec 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/identifier/Identifier.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.identifier; @@ -47,19 +62,19 @@ public static Identifier createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Identifier.class, map); } - + Identifier ret = new Identifier(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java index 40c22e60..046fe831 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/modeltype/ModelType.java @@ -1,15 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.modeltype; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.model.VABModelMap; @@ -27,7 +42,7 @@ public class ModelType extends VABModelMap { public static final String NAME = "name"; public ModelType(String type) { - Map map = new HashMap<>(); + Map map = new LinkedHashMap<>(); map.put(NAME, type); put(MODELTYPE, map); } @@ -55,7 +70,8 @@ public static ModelType createAsFacade(Map map) { @SuppressWarnings("unchecked") public String getName() { - if(get(ModelType.MODELTYPE) == null) return null; + if (get(ModelType.MODELTYPE) == null) + return null; return (String) ((Map) get(ModelType.MODELTYPE)).get(ModelType.NAME); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java index 9953142e..7e986ca1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/parts/ConceptDescription.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.parts; @@ -52,9 +67,10 @@ public ConceptDescription() { // Add attributes put(ISCASEOF, new HashSet()); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort * @param identification */ @@ -76,19 +92,19 @@ public static ConceptDescription createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(ConceptDescription.class, map); } - + ConceptDescription ret = new ConceptDescription(); ret.setMap(map); - return ret; + return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { @@ -154,6 +170,7 @@ public String getCategory() { public LangStrings getDescription() { return Referable.createAsFacade(this, getKeyElement()).getDescription(); } + @Override public IReference getParent() { return Referable.createAsFacade(this, getKeyElement()).getParent(); @@ -176,7 +193,7 @@ public void setDescription(LangStrings description) { public void setParent(IReference obj) { Referable.createAsFacade(this, getKeyElement()).setParent(obj); } - + private KeyElements getKeyElement() { return KeyElements.CONCEPTDESCRIPTION; } @@ -185,5 +202,5 @@ private KeyElements getKeyElement() { public IReference getReference() { return Identifiable.createAsFacade(this, getKeyElement()).getReference(); } - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java index bc571dfc..0280a11a 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/AdministrativeInformation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -84,13 +99,15 @@ public Collection getEmbeddedDataSpecifications() { public void setEmbeddedDataSpecifications(Collection embeddedDataSpecifications) { HasDataSpecification.createAsFacade(this).setEmbeddedDataSpecifications(embeddedDataSpecifications); } - + /** * Sets version and revision + * * @param version - * @param revision + * @param revision * - * @throws RuntimeException when revision is given without a valid version + * @throws RuntimeException + * when revision is given without a valid version */ public void setVersionInformation(String version, String revision) { setVersion(version); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java index 6a851789..91cf526b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasDataSpecification.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -31,6 +46,7 @@ public class HasDataSpecification extends VABModelMap implements IHasDataSpecification { public static final String DATASPECIFICATION = "dataSpecification"; public static final String EMBEDDEDDATASPECIFICATIONS = "embeddedDataSpecifications"; + /** * Constructor */ diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java index dfe20177..5da5ebfd 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/HasSemantics.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -28,7 +43,8 @@ public class HasSemantics extends VABModelMap implements IHasSemantics { /** * Constructor */ - public HasSemantics() {} + public HasSemantics() { + } /** * Constructor diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java index 902d2f28..2597f27c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Identifiable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -40,9 +55,10 @@ public Identifiable() { // The globally unique identification of an element. (Identificator) put(IDENTIFICATION, new Identifier()); } - + /** * Constructor with mandatory attribute + * * @param idShort * @param identification */ @@ -75,32 +91,31 @@ public static Identifiable createAsFacade(Map map, KeyElements t if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Identifiable.class, map); } - + Identifiable ret = new Identifiable(); ret.setMap(map); ret.setElementType(type); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ @SuppressWarnings("unchecked") public static boolean isValid(Map map) { - return Referable.isValid(map) && - map.containsKey(Identifiable.IDENTIFICATION) && - Identifier.isValid((Map)map.get(Identifiable.IDENTIFICATION)); + return Referable.isValid(map) && map.containsKey(Identifiable.IDENTIFICATION) && Identifier.isValid((Map) map.get(Identifiable.IDENTIFICATION)); } - + /** - * Creates an Identifiable object from a map - * Without checking mandatory attributes present + * Creates an Identifiable object from a map Without checking mandatory + * attributes present + * * @param map * @param type * @return @@ -109,7 +124,7 @@ public static Identifiable createAsFacadeNonStrict(Map map, KeyE if (map == null) { return null; } - + Identifiable ret = new Identifiable(); ret.setMap(map); ret.setElementType(type); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java index 2098549e..539e74bf 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangString.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -22,12 +37,13 @@ public class LangString extends VABModelMap { private static final String LANGUAGE = "language"; private static final String DESCRIPTION = "text"; - + private LangString() { } - + /** * Constructor that accepts a language and a description + * * @param language * @param description */ @@ -35,13 +51,13 @@ public LangString(String language, String description) { put(LANGUAGE, language); put(DESCRIPTION, description); } - + /** * Creates a LangString object from a map * - * @param map a LangString object as raw map - * @return a LangString object, that behaves like a facade for - * the given map + * @param map + * a LangString object as raw map + * @return a LangString object, that behaves like a facade for the given map */ public static LangString createAsFacade(Map map) { if (map == null) { @@ -52,31 +68,33 @@ public static LangString createAsFacade(Map map) { ret.setMap(map); return ret; } - + @SuppressWarnings("unchecked") public static boolean isLangString(Object value) { - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - + return map.get(LANGUAGE) instanceof String && map.get(DESCRIPTION) instanceof String; } - + /** * Get Language of the langString + * * @return Language */ public String getLanguage() { return (String) get(LANGUAGE); } - + /** * Get Description of the langString + * * @return Description */ public String getDescription() { return (String) get(DESCRIPTION); - } + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java index d632b3d1..d96ef5c0 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/LangStrings.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -23,29 +38,35 @@ */ public class LangStrings extends HashSet { private static final long serialVersionUID = 1L; - - public LangStrings() {} - + + public LangStrings() { + } + /** * Constructor taking a language and a description in that language - * @param language + * + * @param language * @param description */ public LangStrings(String language, String description) { add(new LangString(language, description)); } - + /** * Constructor taking a single LangString - * @param langString single LangString to add + * + * @param langString + * single LangString to add */ public LangStrings(LangString langString) { add(langString); } - + /** * Constructor taking a collection of LangString - * @param langStrings collection of LangString to add + * + * @param langStrings + * collection of LangString to add */ public LangStrings(Collection langStrings) { if (langStrings != null) { @@ -54,13 +75,13 @@ public LangStrings(Collection langStrings) { }); } } - + /** * Creates a LangStrings object from a collection of map * - * @param maps a LangStrings object as raw collection of map - * @return a LangStrings object, that behaves like a facade for - * the given map + * @param maps + * a LangStrings object as raw collection of map + * @return a LangStrings object, that behaves like a facade for the given map */ public static LangStrings createAsFacade(Collection> maps) { if (maps == null) { @@ -74,15 +95,55 @@ public static LangStrings createAsFacade(Collection> maps) { } return ret; } - + + /** + * QoL method which creates a LangStrings with the specified + * strings. The strings must be given in pairs, such that the first string is + * the language code and the second is the text. + * + *

+ * Examples: + * + *

+	 * {
+	 * 	@code
+	 * 	// Creates a LangStrings with two languages:
+	 * 	LangStrings ls1 = LangStrings.fromStringPairs("en", "Manual", "de", "Betriebsanleitung");
+	 * 
+	 * 	// Throws an exception:
+	 * 	LangStrings ls2 = LangStrings.fromStringPairs("en");
+	 * }
+	 * 
+ * + * @param strings + * A even-numbered set of strings where every pair of two strings + * describes one LangString. + * + * @return A new instance of LangStrings. + * + * @throws IllegalArgumentException + * if strings contains an odd number of elements. + */ + public static LangStrings fromStringPairs(String... strings) { + if ((strings.length % 2) == 1) { + throw new IllegalArgumentException("strings must have an even number of items."); + } + + LangStrings result = new LangStrings(); + for (int i = 0; i < strings.length; i = i + 2) { + result.add(new LangString(strings[i], strings[i + 1])); + } + return result; + } + @SuppressWarnings("unchecked") public static boolean isLangStrings(Object value) { - if(!(value instanceof Collection)) { + if (!(value instanceof Collection)) { return false; } - + Collection> collection = (Collection>) value; - + return collection.stream().allMatch(LangString::isLangString); } @@ -90,18 +151,18 @@ public static boolean isLangStrings(Object value) { * * @param language * @return The String for the specified language or
- * an empty String if no matching LangString is found + * an empty String if no matching LangString is found */ public String get(String language) { for (LangString langString : this) { String currLanguage = langString.getLanguage(); - if(currLanguage == null ? language == null : currLanguage.equalsIgnoreCase(language)) { + if (currLanguage == null ? language == null : currLanguage.equalsIgnoreCase(language)) { return langString.getDescription(); } } return ""; } - + /** * @return A Set of Strings containing all languages of this LangStrings Object */ diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java index 3f387c31..efc81c6a 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/Referable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier; @@ -36,13 +51,13 @@ public class Referable extends VABModelMap implements IReferable { private static Logger logger = LoggerFactory.getLogger(Referable.class); - public static final String IDSHORT="idShort"; - - public static final String CATEGORY="category"; - - public static final String DESCRIPTION="description"; - - public static final String PARENT="parent"; + public static final String IDSHORT = "idShort"; + + public static final String CATEGORY = "category"; + + public static final String DESCRIPTION = "description"; + + public static final String PARENT = "parent"; private KeyElements elem; @@ -53,9 +68,10 @@ public Referable() { // Identifies an element within its name space (String) put(IDSHORT, ""); } - + /** * Constructor with mandatory attribute + * * @param idShort */ public Referable(String idShort) { @@ -94,7 +110,7 @@ public static Referable createAsFacade(Map map, KeyElements type if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Referable.class, map); } @@ -102,21 +118,22 @@ public static Referable createAsFacade(Map map, KeyElements type ret.setMap(map); ret.setElementType(type); - return ret; + return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { return map != null && map.get(Referable.IDSHORT) != null; } - + /** - * Creates a Referable object from a map - * without checking the mandatory attributes present + * Creates a Referable object from a map without checking the mandatory + * attributes present + * * @param map * @param type * @return @@ -125,12 +142,12 @@ public static Referable createAsFacadeNonStrict(Map map, KeyElem if (map == null) { return null; } - + Referable ret = new Referable(); ret.setMap(map); ret.setElementType(type); - return ret; + return ret; } @Override @@ -156,12 +173,12 @@ public IReference getParent() { } public void setIdShort(String idShort) { - if(!IdShortValidator.isValid(idShort)) { + if (!IdShortValidator.isValid(idShort)) { /* * Currently, the AASX package explorer does support creating arbitrary * idShorts. Thus, if this is an exception, AASX files created with the AASX - * package explorer may not be loadable - * TODO: Replace this with a RuntimeException + * package explorer may not be loadable TODO: Replace this with a + * RuntimeException */ logger.warn("The passed idShort " + idShort + " is not valid! It has to satisfy the RegEx " + IdShortValidator.IDSHORT_REGEX); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java index 6377bc2f..455f0634 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/haskind/HasKind.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind; @@ -27,11 +42,12 @@ public class HasKind extends VABModelMap implements IHasKind { /** * Constructor */ - public HasKind() {} + public HasKind() { + } /** - * Constructor that takes - * {@link ModelingKind} (either Kind.Instance or Kind.Type) + * Constructor that takes {@link ModelingKind} (either Kind.Instance or + * Kind.Type) */ public HasKind(ModelingKind kind) { // Kind of the element: either type or instance. @@ -56,14 +72,33 @@ public static HasKind createAsFacade(Map map) { return ret; } + /** + * @deprecated Please use {@link #getKind()} instead. + */ @Override public ModelingKind getModelingKind() { + return this.getKind(); + } + + /** + * @deprecated Please use {@link #setKind(ModelingKind)} instead. + */ + public void setModelingKind(ModelingKind kind) { + this.setKind(kind); + } + + @Override + public ModelingKind getKind() { String str = (String) get(HasKind.KIND); return ModelingKind.fromString(str); } - public void setModelingKind(ModelingKind kind) { - put(HasKind.KIND, kind.toString()); + public void setKind(ModelingKind kind) { + if (kind != null) { + put(HasKind.KIND, kind.toString()); + } else { + put(HasKind.KIND, null); + } } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java index c7c78f64..ddeda715 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Constraint.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java index 5c794aa6..b16b92bf 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Formula.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable; @@ -77,5 +92,4 @@ public Collection getDependsOn() { return ReferenceHelper.transform(get(Formula.DEPENDSON)); } - } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java index 248ef622..37cbb4b7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifiable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable; @@ -30,7 +45,8 @@ public class Qualifiable extends VABModelMap implements IQualifiable { /** * Constructor */ - public Qualifiable() {} + public Qualifiable() { + } /** * Constructor diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java index 1aaf8ca4..e7fa5464 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/qualifier/qualifiable/Qualifier.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable; @@ -46,9 +61,10 @@ public Qualifier() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Constructor accepting mandatory attributes + * * @param type * @param valueType */ @@ -57,7 +73,7 @@ public Qualifier(String type, String valueType) { } public Qualifier(String type, String value, String valueType, Reference valueId) { - put(TYPE,type); + put(TYPE, type); put(VALUE, ValueTypeHelper.prepareForSerialization(value)); put(VALUEID, valueId); put(VALUETYPE, valueType); @@ -75,25 +91,23 @@ public static Qualifier createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Qualifier.class, map); } - + Qualifier ret = new Qualifier(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { - return map != null && - map.containsKey(TYPE) && - map.containsKey(VALUETYPE); + return map != null && map.containsKey(TYPE) && map.containsKey(VALUETYPE); } public void setType(String obj) { @@ -108,7 +122,7 @@ public String getType() { public void setValue(Object obj) { put(Qualifier.VALUE, ValueTypeHelper.prepareForSerialization(obj)); // Value type is only set if it is not set before - if(getValueType() == null) { + if (getValueType() == null) { put(Qualifier.VALUETYPE, ValueTypeHelper.getType(obj).toString()); } } @@ -116,9 +130,9 @@ public void setValue(Object obj) { @Override public Object getValue() { Object value = get(Qualifier.VALUE); - if(value instanceof String) { + if (value instanceof String) { return ValueTypeHelper.getJavaObject(value, getValueType()); - }else { + } else { return value; } } @@ -126,7 +140,7 @@ public Object getValue() { public void setValueId(IReference obj) { put(Qualifier.VALUEID, obj); } - + @SuppressWarnings("unchecked") @Override public IReference getValueId() { @@ -136,7 +150,7 @@ public IReference getValueId() { public void setValueType(ValueType obj) { put(Qualifier.VALUETYPE, obj.toString()); } - + @Override public ValueType getValueType() { return ValueTypeHelper.readTypeDef(get(Qualifier.VALUETYPE)); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java index 392d1de4..88e61d2f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Key.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.reference; @@ -51,7 +66,7 @@ public Key(KeyElements type, boolean local, String value, KeyType idType) { put(VALUE, value); put(IDTYPE, idType.toString()); } - + /** * Helper constructor to translate IdentifierType to KeyType.
* In the meta model KeyType inheritcs from IdentifiertType, however Java does @@ -83,42 +98,37 @@ public static Key createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Key.class, map); } - + Key ret = new Key(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map map) { - return map != null && - map.containsKey(TYPE) && - map.containsKey(LOCAL) && - map.containsKey(VALUE) && - map.containsKey(IDTYPE); + return map != null && map.containsKey(TYPE) && map.containsKey(LOCAL) && map.containsKey(VALUE) && map.containsKey(IDTYPE); } - + @SuppressWarnings("unchecked") public static boolean isKey(Object value) { - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - - if(!(map.get(LOCAL) instanceof Boolean && map.get(VALUE) instanceof String - && map.get(IDTYPE) instanceof String && map.get(TYPE) instanceof String)) { + + if (!(map.get(LOCAL) instanceof Boolean && map.get(VALUE) instanceof String && map.get(IDTYPE) instanceof String && map.get(TYPE) instanceof String)) { return false; } - + try { // Try to convert the Strings to Enum-Types // If that fails an Exception is thrown @@ -127,7 +137,7 @@ public static boolean isKey(Object value) { } catch (IllegalArgumentException e) { return false; } - + return true; } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java index 75785606..7c33847c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/Reference.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.reference; @@ -70,7 +85,8 @@ public Reference(IIdentifier identifier, KeyElements keyElement, boolean local) /** * - * @param keys Unique reference in its name space. + * @param keys + * Unique reference in its name space. */ public Reference(List keys) { setKeys(keys); @@ -96,25 +112,25 @@ public static Reference createAsFacade(Map map) { if (map == null) { return null; } - + if (!isValid(map)) { throw new MetamodelConstructionException(Reference.class, map); } - + Reference ret = new Reference(); ret.setMap(map); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ @SuppressWarnings("unchecked") public static boolean isValid(Map map) { if (map != null && map.containsKey(Reference.KEY)) { - Collection> keysCollection = (Collection>)map.get(Reference.KEY); + Collection> keysCollection = (Collection>) map.get(Reference.KEY); for (Map key : keysCollection) { if (!Key.isValid(key)) { return false; @@ -124,10 +140,10 @@ public static boolean isValid(Map map) { } return false; } - + /** - * Creates a Reference object from a map - * without checking mandatory attributes present + * Creates a Reference object from a map without checking mandatory attributes + * present * * @param map * a Reference object as raw map @@ -137,24 +153,24 @@ public static Reference createAsFacadeNonStrict(Map map) { if (map == null) { return null; } - + Reference ret = new Reference(); ret.setMap(map); return ret; } - + @SuppressWarnings("unchecked") public static boolean isReference(Object value) { - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - - if(!(map.get(KEY) instanceof Collection)) { + + if (!(map.get(KEY) instanceof Collection)) { return false; } - + return ((Collection) map.get(KEY)).stream().allMatch(Key::isKey); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java index 13614f9d..f9c0f6dd 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/reference/ReferenceHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.reference; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/Capability.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/Capability.java index 88e06d19..fc29767b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/Capability.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/Capability.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java index 6d151ae8..15893065 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement; @@ -29,7 +44,6 @@ import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable; import org.eclipse.basyx.vab.model.VABModelMap; - /** * SubmodelElement as defined in "Details of the Asset Administration Shell" * @@ -47,36 +61,39 @@ protected SubmodelElement() { /** * Constructor with only mandatory attribute + * * @param idShort */ protected SubmodelElement(String idShort) { this(); setIdShort(idShort); } - + /** * Creates a SubmodelElement object from a map * - * @param obj a SubmodelElement object as raw map - * @return a SubmodelElement object, that behaves like a facade for the given map + * @param obj + * a SubmodelElement object as raw map + * @return a SubmodelElement object, that behaves like a facade for the given + * map */ public static SubmodelElement createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { - throw new MetamodelConstructionException(SubmodelElement.class, obj); + throw new MetamodelConstructionException(SubmodelElement.class, obj); } SubmodelElement ret = new SubmodelElement(); ret.setMap(obj); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { @@ -163,13 +180,28 @@ public void setSemanticId(IReference ref) { HasSemantics.createAsFacade(this).setSemanticId(ref); } + /** + * @deprecated Please use {@link #getKind()} instead. + */ @Override public ModelingKind getModelingKind() { - return HasKind.createAsFacade(this).getModelingKind(); + return this.getKind(); } + /** + * @deprecated Please use {@link #setKind(ModelingKind)} instead. + */ public void setModelingKind(ModelingKind kind) { - HasKind.createAsFacade(this).setModelingKind(kind); + this.setKind(kind); + } + + @Override + public ModelingKind getKind() { + return HasKind.createAsFacade(this).getKind(); + } + + public void setKind(ModelingKind kind) { + HasKind.createAsFacade(this).setKind(kind); } @Override @@ -182,12 +214,12 @@ public String getModelType() { public IReference getReference() { return Referable.createAsFacade(this, getKeyElement()).getReference(); } - + @Override public Object getValue() { throw new UnsupportedOperationException("getValue is only possible in specific Element"); } - + @Override public void setValue(Object value) { throw new UnsupportedOperationException("setValue is only possible in specific Element"); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java index 0988ca69..e0b33d1b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/SubmodelElementCollection.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException; @@ -23,6 +38,7 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.facade.ElementContainerValuesHelper; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; import org.eclipse.basyx.submodel.metamodel.map.helper.ElementContainerHelper; import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType; @@ -44,7 +60,6 @@ public class SubmodelElementCollection extends SubmodelElement implements ISubmo public static final String ALLOWDUPLICATES = "allowDuplicates"; public static final String MODELTYPE = "SubmodelElementCollection"; - /** * Constructor */ @@ -53,13 +68,14 @@ public SubmodelElementCollection() { putAll(new ModelType(MODELTYPE)); // Put attributes - put(Property.VALUE, new HashMap<>()); + put(Property.VALUE, new LinkedHashMap<>()); put(ORDERED, true); put(ALLOWDUPLICATES, true); } - + /** * Constructor with only mandatory attribute + * * @param idShort */ public SubmodelElementCollection(String idShort) { @@ -88,48 +104,51 @@ public SubmodelElementCollection(String idShort) { public SubmodelElementCollection(Collection value, boolean ordered, boolean allowDuplicates) { // Add model type putAll(new ModelType(MODELTYPE)); - + // Put attributes put(Property.VALUE, SubmodelElementMapCollectionConverter.convertCollectionToIDMap(value)); put(ORDERED, ordered); put(ALLOWDUPLICATES, allowDuplicates); } - + /** * Creates a SubmodelElementCollection object from a map * - * @param obj a SubmodelElementCollection object as raw map - * @return a SubmodelElementCollection object, that behaves like a facade for the given map + * @param obj + * a SubmodelElementCollection object as raw map + * @return a SubmodelElementCollection object, that behaves like a facade for + * the given map */ public static SubmodelElementCollection createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(SubmodelElementCollection.class, obj); } - + return SubmodelElementMapCollectionConverter.mapToSmECollection(obj); } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { return SubmodelElement.isValid(obj); } - + /** - * Returns true if the given submodel element map is recognized as a submodel element collection + * Returns true if the given submodel element map is recognized as a submodel + * element collection */ public static boolean isSubmodelElementCollection(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) - return MODELTYPE.equals(modelType) || (modelType == null - && (map.containsKey(Property.VALUE) && map.containsKey(ORDERED) && map.containsKey(ALLOWDUPLICATES))); + // Either model type is set or the element type specific attributes are + // contained (fallback) + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(ORDERED) && map.containsKey(ALLOWDUPLICATES))); } /** @@ -217,10 +236,10 @@ public Map getSubmodelElements() { @SuppressWarnings("unchecked") @Override public Map getProperties() { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); Map smElems = (Map) get(Property.VALUE); - - for(ISubmodelElement smElement: smElems.values()) { + + for (ISubmodelElement smElement : smElems.values()) { if (Property.isProperty((Map) smElement)) { ret.put(smElement.getIdShort(), (IProperty) smElement); } @@ -232,10 +251,10 @@ public Map getProperties() { @SuppressWarnings("unchecked") @Override public Map getOperations() { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); Map smElems = (Map) get(Property.VALUE); - - for(ISubmodelElement smElement: smElems.values()) { + + for (ISubmodelElement smElement : smElems.values()) { if (Operation.isOperation(smElement)) { ret.put(smElement.getIdShort(), (IOperation) smElement); } @@ -246,6 +265,7 @@ public Map getOperations() { /** * Retrieves an element from element collection + * * @param id * @return retrieved element */ @@ -258,6 +278,7 @@ public ISubmodelElement getSubmodelElement(String id) { /** * Deletes an element from element collection + * * @param id */ @SuppressWarnings("unchecked") @@ -266,7 +287,7 @@ public void deleteSubmodelElement(String id) { Map submodelElems = (Map) get(Property.VALUE); ElementContainerHelper.removeElementById(submodelElems, id); } - + @Override protected KeyElements getKeyElement() { return KeyElements.SUBMODELELEMENTCOLLECTION; @@ -285,4 +306,9 @@ public SubmodelElementCollection getLocalCopy() { copy.setValue(clonedValue); return copy; } + + @Override + public Map getValues() { + return ElementContainerValuesHelper.getSubmodelValue(this); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java index c775a44d..c7323879 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/Blob.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement; @@ -28,7 +43,7 @@ public class Blob extends DataElement implements IBlob { public static final String MIMETYPE = "mimeType"; public static final String MODELTYPE = "Blob"; - + /** * Creates an empty Blob object */ @@ -36,9 +51,10 @@ public Blob() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort * @param mimeType */ @@ -64,46 +80,47 @@ public Blob(byte[] value, String mimeType) { setByteArrayValue(value); setMimeType(mimeType); } - + /** * Creates a Blob object from a map * - * @param obj a Blob object as raw map + * @param obj + * a Blob object as raw map * @return a Blob object, that behaves like a facade for the given map */ public static Blob createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Blob.class, obj); } - + Blob facade = new Blob(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { return DataElement.isValid(obj) && obj.containsKey(Blob.MIMETYPE); } - + /** * Returns true if the given submodel element map is recognized as a blob */ public static boolean isBlob(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) + // Either model type is set or the element type specific attributes are + // contained (fallback) // Note: Fallback is ambiguous - File has exactly the same attributes // => would need value parsing in order to be able to differentiate - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE))); + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE))); } @Override @@ -123,11 +140,11 @@ public String getValue() { } return (String) get(Property.VALUE); } - + @Override public byte[] getByteArrayValue() { String value = getValue(); - if ( value != null ) { + if (value != null) { return Base64.getDecoder().decode(value); } else { return null; @@ -153,7 +170,7 @@ public void setMimeType(String mimeType) { public String getMimeType() { return (String) get(Blob.MIMETYPE); } - + @Override protected KeyElements getKeyElement() { return KeyElements.BLOB; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java index e939a829..886fa49a 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/DataElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement; @@ -26,14 +41,15 @@ public DataElement() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Constructor with mandatory attribute + * * @param idShort */ public DataElement(String idShort) { super(idShort); - + // Add model type putAll(new ModelType(MODELTYPE)); } @@ -41,42 +57,42 @@ public DataElement(String idShort) { /** * Creates a DataElement object from a map * - * @param obj a DataElement object as raw map + * @param obj + * a DataElement object as raw map * @return a DataElement object, that behaves like a facade for the given map */ public static DataElement createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(DataElement.class, obj); } - + DataElement facade = new DataElement(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { return SubmodelElement.isValid(obj); } - + /** - * Returns true if the given submodel element map is recognized as a data element + * Returns true if the given submodel element map is recognized as a data + * element */ public static boolean isDataElement(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - return MODELTYPE.equals(modelType) || Property.isProperty(map) || Blob.isBlob(map) || File.isFile(map) - || Range.isRange(map) || MultiLanguageProperty.isMultiLanguageProperty(map) - || ReferenceElement.isReferenceElement(map); + return MODELTYPE.equals(modelType) || Property.isProperty(map) || Blob.isBlob(map) || File.isFile(map) || Range.isRange(map) || MultiLanguageProperty.isMultiLanguageProperty(map) || ReferenceElement.isReferenceElement(map); } - + @Override protected KeyElements getKeyElement() { return KeyElements.DATAELEMENT; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java index 7b0503bd..72ee5df1 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/File.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement; @@ -23,8 +38,8 @@ * @author pschorn, schnicke * */ -public class File extends DataElement implements IFile{ - public static final String MIMETYPE="mimeType"; +public class File extends DataElement implements IFile { + public static final String MIMETYPE = "mimeType"; public static final String MODELTYPE = "File"; /** @@ -34,16 +49,17 @@ public File() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Constructor accepting only mandatory attribute + * * @param mimeType */ public File(String mimeType) { this(); setMimeType(mimeType); } - + /** * Creates a file data element. It has to have a mimeType
* An absolute path is used in the case that the file exists independently of @@ -65,30 +81,31 @@ public File(String value, String mimeType) { put(Property.VALUE, value); put(MIMETYPE, mimeType); } - + /** * Creates a File object from a map * - * @param obj a File object as raw map + * @param obj + * a File object as raw map * @return a File object, that behaves like a facade for the given map */ public static File createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(File.class, obj); } - + File facade = new File(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { @@ -100,22 +117,21 @@ public static boolean isValid(Map obj) { */ public static boolean isFile(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) + // Either model type is set or the element type specific attributes are + // contained (fallback) // Note: Fallback is ambiguous - Blob has exactly the same attributes // => would need value parsing in order to be able to differentiate - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE))); + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(Property.VALUE) && map.containsKey(MIMETYPE))); } @Override public void setValue(Object value) { - if(value instanceof String) { + if (value instanceof String) { setValue((String) value); - } - else { + } else { throw new IllegalArgumentException("Given Object is not a String"); } - + } @Override @@ -131,7 +147,7 @@ public void setMimeType(String mimeType) { public String getMimeType() { return (String) get(File.MIMETYPE); } - + @Override protected KeyElements getKeyElement() { return KeyElements.FILE; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java index daa9ca27..ea89a53c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/MultiLanguageProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement; @@ -32,14 +47,15 @@ public class MultiLanguageProperty extends DataElement implements IMultiLanguage public static final String MODELTYPE = "MultiLanguageProperty"; public static final String VALUE = "value"; public static final String VALUEID = "valueId"; - + public MultiLanguageProperty() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort */ public MultiLanguageProperty(String idShort) { @@ -47,51 +63,53 @@ public MultiLanguageProperty(String idShort) { // Add model type putAll(new ModelType(MODELTYPE)); } - + public MultiLanguageProperty(Reference reference, LangStrings langStrings) { this(); put(VALUE, langStrings); put(VALUEID, reference); } - + /** * Creates a MultiLanguageProperty object from a map * - * @param obj a MultiLanguageProperty object as raw map - * @return a MultiLanguageProperty object, that behaves like a facade for the given map + * @param obj + * a MultiLanguageProperty object as raw map + * @return a MultiLanguageProperty object, that behaves like a facade for the + * given map */ public static MultiLanguageProperty createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(MultiLanguageProperty.class, obj); } - + MultiLanguageProperty facade = new MultiLanguageProperty(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { return DataElement.isValid(obj); } - + /** - * Returns true if the given submodel element map is recognized as a MultiLanguageProperty + * Returns true if the given submodel element map is recognized as a + * MultiLanguageProperty */ public static boolean isMultiLanguageProperty(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUE) && map.containsKey(VALUEID) - && !map.containsKey(Property.VALUETYPE))); + // Either model type is set or the element type specific attributes are + // contained (fallback) + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUE) && map.containsKey(VALUEID) && !map.containsKey(Property.VALUETYPE))); } @Override @@ -105,20 +123,19 @@ public IReference getValueId() { public LangStrings getValue() { return LangStrings.createAsFacade((Collection>) get(VALUE)); } - + @Override protected KeyElements getKeyElement() { return KeyElements.MULTILANGUAGEPROPERTY; } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(LangStrings.isLangStrings(value)) { + if (LangStrings.isLangStrings(value)) { LangStrings strings = LangStrings.createAsFacade((Collection>) value); setValue(strings); - } - else { + } else { throw new IllegalArgumentException("Given Object is not a LangStrings"); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java index 65e342b4..abb05085 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/ReferenceElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement; @@ -71,35 +86,37 @@ public ReferenceElement(Reference ref) { putAll(new ModelType(MODELTYPE)); put(Property.VALUE, ref); } - + /** * Creates a ReferenceElement object from a map * - * @param obj a ReferenceElement object as raw map - * @return a ReferenceElement object, that behaves like a facade for the given map + * @param obj + * a ReferenceElement object as raw map + * @return a ReferenceElement object, that behaves like a facade for the given + * map */ public static ReferenceElement createAsFacade(Map obj) { if (obj == null) { return null; } - + ReferenceElement ret = new ReferenceElement(); ret.setMap(obj); return ret; } /** - * Returns true if the given submodel element map is recognized as a ReferenceElement + * Returns true if the given submodel element map is recognized as a + * ReferenceElement */ public static boolean isReferenceElement(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) - // Ambiguous - fallback could be further improved by parsing the value and recognizing references - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(Property.VALUE) && !map.containsKey(Property.VALUETYPE) - && !map.containsKey(Property.VALUEID) && !map.containsKey(File.MIMETYPE) - && !map.containsKey(SubmodelElementCollection.ORDERED) - && !map.containsKey(SubmodelElementCollection.ALLOWDUPLICATES))); + // Either model type is set or the element type specific attributes are + // contained (fallback) + // Ambiguous - fallback could be further improved by parsing the value and + // recognizing references + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(Property.VALUE) && !map.containsKey(Property.VALUETYPE) && !map.containsKey(Property.VALUEID) && !map.containsKey(File.MIMETYPE) + && !map.containsKey(SubmodelElementCollection.ORDERED) && !map.containsKey(SubmodelElementCollection.ALLOWDUPLICATES))); } @Override @@ -107,18 +124,17 @@ public static boolean isReferenceElement(Map map) { public IReference getValue() { return Reference.createAsFacade((Map) get(Property.VALUE)); } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(Reference.isReference(value)) { + if (Reference.isReference(value)) { setValue(Reference.createAsFacade((Map) value)); - } - else { + } else { throw new IllegalArgumentException("Given Object is not a Reference"); } } - + @Override protected KeyElements getKeyElement() { return KeyElements.REFERENCEELEMENT; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java index a52d7695..92432e7c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/AASLambdaPropertyHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java index bb9ccc5c..4d0a2b09 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/Property.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property; @@ -49,7 +64,7 @@ public Property() { put(Property.VALUE, null); put(Property.VALUEID, null); } - + /** * Constructor accepting only mandatory attribute * @@ -60,23 +75,26 @@ public Property(String idShort, ValueType valueType) { super(idShort); setValueType(valueType); setIdShort(idShort); - + // Add model type putAll(new ModelType(MODELTYPE)); } - + /** - * Constructor accepting an idShort and a value - * The valueType is set automatically - * @param idShort the idShort for the Property - * @param value the value for the Property + * Constructor accepting an idShort and a value The valueType is set + * automatically + * + * @param idShort + * the idShort for the Property + * @param value + * the value for the Property */ public Property(String idShort, Object value) { setIdShort(idShort); - + // Add model type putAll(new ModelType(MODELTYPE)); - + // Set the value for the Property // set() also automatically sets the value type setValue(value); @@ -85,26 +103,27 @@ public Property(String idShort, Object value) { /** * Creates a Property object from a map * - * @param obj a Property object as raw map + * @param obj + * a Property object as raw map * @return a Property object, that behaves like a facade for the given map */ public static Property createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Property.class, obj); } - + Property facade = new Property(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { @@ -116,9 +135,9 @@ public static boolean isValid(Map obj) { */ public static boolean isProperty(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUETYPE))); + // Either model type is set or the element type specific attributes are + // contained (fallback) + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(VALUE) && map.containsKey(VALUETYPE))); } /** @@ -143,23 +162,28 @@ public Property(Object value, Referable referable, Reference semanticId, Qualifi } /** - * Overrides the orignal value type that has been determined by inspecting the given value. - * Only use this method, if there is no actual value for this property (e.g. when creating templates) + * Overrides the orignal value type that has been determined by inspecting the + * given value. Only use this method, if there is no actual value for this + * property (e.g. when creating templates) * * @param type - * manually determined type of the value + * manually determined type of the value */ public void setValueType(ValueType type) { - if(type == null) { + if (type == null) { throw new RuntimeException("Can not set null as valueType"); } put(Property.VALUETYPE, type.toString()); } public void setValueId(IReference ref) { - Reference refMap = new Reference(); - refMap.setKeys(ref.getKeys()); - put(Property.VALUEID, refMap); + if (ref != null) { + Reference refMap = new Reference(); + refMap.setKeys(ref.getKeys()); + put(Property.VALUEID, refMap); + } else { + put(Property.VALUEID, null); + } } @SuppressWarnings("unchecked") @@ -178,7 +202,6 @@ public void set(Object newValue, ValueType newType) throws ProviderException { setValueType(newType); } - @Override public ValueType getValueType() { String valueType = (String) get(Property.VALUETYPE); @@ -215,7 +238,7 @@ public Object getValue() { return value; } } - + @Override public void setValue(Object value) { put(Property.VALUE, ValueTypeHelper.prepareForSerialization(value)); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java index b5dea922..669ec2e7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype; @@ -21,16 +36,11 @@ * */ public enum ValueType implements StandardizedLiteralEnum { - Int8("byte"), Int16("short"), Int32("int"), Int64("long"), - UInt8("unsignedByte"), UInt16("unsignedShort"), UInt32("unsignedInt"), UInt64("unsignedLong"), - String("string"), LangString("langString"), - AnyURI("anyuri"), Base64Binary("base64Binary"), HexBinary("hexBinary"), NOTATION("notation"), ENTITY("entity"), ID("id"), IDREF("idref"), - Integer("integer"), NonPositiveInteger("nonPositiveInteger"), NonNegativeInteger("nonNegativeInteger"), PositiveInteger("positiveInteger"), NegativeInteger("negativeInteger"), - Double("double"), Float("float"), Boolean("boolean"), - Duration("duration"), DayTimeDuration("dayTimeDuration"), YearMonthDuration("yearMonthDuration"), - DateTime("dateTime"), DateTimeStamp("dateTimeStamp"), GDay("gDay"), GMonth("gMonth"), GMonthDay("gMonthDay"), GYear("gYear"), GYearMonth("gYearMonth"), - QName("qName"), - None("none"), AnyType("anyType"), AnySimpleType("anySimpleType"); + Int8("byte"), Int16("short"), Int32("int"), Int64("long"), UInt8("unsignedByte"), UInt16("unsignedShort"), UInt32("unsignedInt"), UInt64("unsignedLong"), String("string"), LangString("langString"), AnyURI("anyuri"), Base64Binary( + "base64Binary"), HexBinary("hexBinary"), NOTATION("notation"), ENTITY("entity"), ID("id"), IDREF("idref"), Integer("integer"), NonPositiveInteger("nonPositiveInteger"), NonNegativeInteger("nonNegativeInteger"), PositiveInteger( + "positiveInteger"), NegativeInteger("negativeInteger"), Double("double"), Float("float"), Boolean("boolean"), Duration("duration"), DayTimeDuration("dayTimeDuration"), YearMonthDuration("yearMonthDuration"), DateTime( + "dateTime"), DateTimeStamp( + "dateTimeStamp"), GDay("gDay"), GMonth("gMonth"), GMonthDay("gMonthDay"), GYear("gYear"), GYearMonth("gYearMonth"), QName("qName"), None("none"), AnyType("anyType"), AnySimpleType("anySimpleType"); private String standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java index b1f073ef..3a913961 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/property/valuetype/ValueTypeHelper.java @@ -1,18 +1,33 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2022 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype; import java.math.BigInteger; import java.time.Duration; import java.time.Period; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; @@ -20,7 +35,6 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; - /** * Provides utility functions for * {@link org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType @@ -32,7 +46,7 @@ * */ public class ValueTypeHelper { - private static Map typeMap = new HashMap<>(); + private static Map typeMap = new LinkedHashMap<>(); // insert all types into a Map to allow getting a PropertyValueType based on a // String @@ -41,7 +55,7 @@ public class ValueTypeHelper { typeMap.put(t.toString(), t); } } - + // Strings required for meta-model conformant valueType format private static final String TYPE_NAME = "name"; private static final String TYPE_OBJECT = "dataObjectType"; @@ -68,16 +82,16 @@ public static ValueType fromName(String name) { */ public static ValueType getType(Object obj) { ValueType objectType; - + if (obj == null) { objectType = ValueType.None; } else { Class c = obj.getClass(); - if(c == byte.class || c == Byte.class) { + if (c == byte.class || c == Byte.class) { objectType = ValueType.Int8; - }else if(c == short.class || c == Short.class) { + } else if (c == short.class || c == Short.class) { objectType = ValueType.Int16; - }else if (c == int.class || c == Integer.class) { + } else if (c == int.class || c == Integer.class) { objectType = ValueType.Integer; } else if (c == long.class || c == Long.class) { objectType = ValueType.Int64; @@ -123,107 +137,127 @@ public static ValueType getType(Object obj) { */ public static Object getJavaObject(Object value, ValueType objType) { Object target = null; - if(objType != null) { - switch(objType) { + if (objType != null) { + switch (objType) { case Int8: - if(((String)value).isEmpty()){ + if (((String) value).isEmpty()) { target = new Byte("NaN"); - }else { - target = new Byte((String)value); + } else { + target = new Byte((String) value); } break; - case Int16: case UInt8: - if(((String)value).isEmpty()){ + case Int16: + case UInt8: + if (((String) value).isEmpty()) { target = new Short("NaN"); - }else { - target = new Short((String)value); + } else { + target = new Short((String) value); } break; - case Int32: case UInt16: - if(((String)value).isEmpty()){ + case Int32: + case UInt16: + if (((String) value).isEmpty()) { target = new Integer("NaN"); - }else { - target = new Integer((String)value); + } else { + target = new Integer((String) value); } break; - case Int64: case UInt32: - if(((String)value).isEmpty()){ + case Int64: + case UInt32: + if (((String) value).isEmpty()) { target = new Long("NaN"); - }else { - target = new Long((String)value); + } else { + target = new Long((String) value); } break; case UInt64: - if(((String)value).isEmpty()){ + if (((String) value).isEmpty()) { target = new BigInteger("NaN"); - }else { - target = new BigInteger((String)value); + } else { + target = new BigInteger((String) value); } break; case Double: - if(((String)value).isEmpty()){ + if (((String) value).isEmpty()) { target = new Double("NaN"); - }else { - target = new Double((String)value); + } else { + target = new Double((String) value); } break; case Float: - if(((String)value).isEmpty()){ + if (((String) value).isEmpty()) { target = new Float("NaN"); - }else { - target = new Float((String)value); + } else { + target = new Float((String) value); } break; case Boolean: - target = new Boolean((String)value); + target = new Boolean((String) value); break; - case AnySimpleType: case String: case LangString: case AnyURI: case Base64Binary: case HexBinary: case NOTATION: case ENTITY: case ID: case IDREF: + case AnySimpleType: + case String: + case LangString: + case AnyURI: + case Base64Binary: + case HexBinary: + case NOTATION: + case ENTITY: + case ID: + case IDREF: target = (String) value; break; - case Duration: case DayTimeDuration: - target = Duration.parse((String)value); + case Duration: + case DayTimeDuration: + target = Duration.parse((String) value); break; case YearMonthDuration: - target = Period.parse((String)value); + target = Period.parse((String) value); break; - case DateTime: case DateTimeStamp: case GDay: case GMonth: case GMonthDay: case GYear: case GYearMonth: + case DateTime: + case DateTimeStamp: + case GDay: + case GMonth: + case GMonthDay: + case GYear: + case GYearMonth: try { - target = DatatypeFactory.newInstance().newXMLGregorianCalendar((String)value); + target = DatatypeFactory.newInstance().newXMLGregorianCalendar((String) value); break; } catch (DatatypeConfigurationException e) { e.printStackTrace(); throw new RuntimeException("Could not create DatatypeFactory for XMLGregorianCaldner handling"); - } + } case QName: - target = QName.valueOf((String)value); + target = QName.valueOf((String) value); break; default: target = value; break; } return target; - }else { + } else { return null; } - - + } /** * Convert an object which has special types (Duration, period, Qname, Date) to - * String object Used by Property.set() or ConnectedProperty.set(), prepare for the serialization + * String object Used by Property.set() or ConnectedProperty.set(), prepare for + * the serialization * - * @param value - the target object + * @param value + * - the target object * @return */ public static Object prepareForSerialization(Object value) { - if(value != null) { + if (value != null) { Class c = value.getClass(); if (c == Duration.class || c == Period.class || c == QName.class || value instanceof XMLGregorianCalendar) { return value.toString(); } } - return value; + return value; } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java index fbdf1d64..842daf40 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/Range.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range; @@ -31,13 +46,12 @@ public class Range extends DataElement implements IRange { public static final String VALUETYPE = "valueType"; public static final String MIN = "min"; public static final String MAX = "max"; - public Range() { // Add model type putAll(new ModelType(MODELTYPE)); } - + public Range(ValueType valueType) { this(); setValueType(valueType); @@ -45,6 +59,7 @@ public Range(ValueType valueType) { /** * Constructor accepting only mandatory attribute + * * @param idShort * @param valueType */ @@ -54,50 +69,52 @@ public Range(String idShort, ValueType valueType) { putAll(new ModelType(MODELTYPE)); setValueType(valueType); } - + public Range(ValueType valueType, Object min, Object max) { this(valueType); put(MIN, min); put(MAX, max); } - + /** * Creates a Range object from a map * - * @param obj a Range object as raw map + * @param obj + * a Range object as raw map * @return a Range object, that behaves like a facade for the given map */ public static Range createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Range.class, obj); } - + Range facade = new Range(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { return DataElement.isValid(obj) && obj.containsKey(VALUETYPE); } - + /** - * Returns true if the given submodel element map is recognized as a Range element + * Returns true if the given submodel element map is recognized as a Range + * element */ public static boolean isRange(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE))); + // Either model type is set or the element type specific attributes are + // contained (fallback) + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(MIN) && map.containsKey(MAX) && map.containsKey(VALUETYPE))); } private void setValueType(ValueType valueType) { @@ -112,9 +129,9 @@ public ValueType getValueType() { @Override public Object getMin() { Object value = get(MIN); - if(value instanceof String) { + if (value instanceof String) { return ValueTypeHelper.getJavaObject(value, getValueType()); - }else { + } else { return value; } } @@ -122,13 +139,13 @@ public Object getMin() { @Override public Object getMax() { Object value = get(MAX); - if(value instanceof String) { + if (value instanceof String) { return ValueTypeHelper.getJavaObject(value, getValueType()); - }else { + } else { return value; } } - + @Override protected KeyElements getKeyElement() { return KeyElements.RANGE; @@ -138,11 +155,11 @@ protected KeyElements getKeyElement() { public RangeValue getValue() { return new RangeValue(getMin(), getMax()); } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(RangeValue.isRangeValue(value)) { + if (RangeValue.isRangeValue(value)) { RangeValue rv = RangeValue.createAsFacade((Map) value); setValue(rv); } else { diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java index 322bcacc..2b460a98 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/dataelement/range/RangeValue.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.range; @@ -13,7 +28,6 @@ import org.eclipse.basyx.vab.model.VABModelMap; - /** * Container class for holding the value of Range * @@ -22,47 +36,49 @@ */ public class RangeValue extends VABModelMap { - private RangeValue() {} - + private RangeValue() { + } + public RangeValue(Object min, Object max) { put(Range.MIN, min); put(Range.MAX, max); } - + @SuppressWarnings("unchecked") public static boolean isRangeValue(Object value) { - + // Given Object must be a Map - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - + // Given Map must contain all necessary Entries return map.containsKey(Range.MIN) && map.containsKey(Range.MAX); } - + /** * Creates a RangeValue object from a map * - * @param obj a RangeValue object as raw map + * @param obj + * a RangeValue object as raw map * @return a RangeValue object, that behaves like a facade for the given map */ public static RangeValue createAsFacade(Map obj) { if (obj == null) { return null; } - + RangeValue facade = new RangeValue(); facade.setMap(obj); return facade; } - + public Object getMin() { return get(Range.MIN); } - + public Object getMax() { return get(Range.MAX); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java index 333b87f1..348a8025 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/Entity.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity; @@ -31,37 +46,38 @@ * */ public class Entity extends SubmodelElement implements IEntity { - + public static final String MODELTYPE = "Entity"; public static final String STATEMENT = "statement"; public static final String ENTITY_TYPE = "entityType"; public static final String ASSET = "asset"; - + public Entity() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort * @param entityType */ public Entity(String idShort, EntityType entityType) { super(idShort); setEntityType(entityType); - + // Add model type putAll(new ModelType(MODELTYPE)); } - + public Entity(EntityType entityType, Collection statements, IReference asset) { this(); setEntityType(entityType); setStatements(statements); setAsset(asset); } - + public void setStatements(Collection statements) { put(STATEMENT, statements); } @@ -76,33 +92,35 @@ public void setEntityType(EntityType entityType) { public static boolean isEntity(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) + // Either model type is set or the element type specific attributes are + // contained (fallback) return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(Entity.STATEMENT)); } /** * Creates an Entity object from a map * - * @param obj an Entity object as raw map + * @param obj + * an Entity object as raw map * @return an Entity object, that behaves like a facade for the given map */ public static Entity createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Entity.class, obj); } - + Entity facade = new Entity(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { @@ -131,7 +149,7 @@ public EntityType getEntityType() { public IReference getAsset() { return Reference.createAsFacade((Map) get(ASSET)); } - + @Override protected KeyElements getKeyElement() { return KeyElements.ENTITY; @@ -141,16 +159,15 @@ protected KeyElements getKeyElement() { public EntityValue getValue() { return new EntityValue(getStatements(), getAsset()); } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(EntityValue.isEntityValue(value)) { + if (EntityValue.isEntityValue(value)) { EntityValue ev = EntityValue.createAsFacade((Map) value); put(Entity.STATEMENT, ev.getStatement()); put(Entity.ASSET, ev.getAsset()); - } - else { + } else { throw new IllegalArgumentException("Given Object is not an EntityValue"); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java index cdce0a70..f49ba740 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/entity/EntityValue.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity; @@ -19,7 +34,6 @@ import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; import org.eclipse.basyx.vab.model.VABModelMap; - /** * Container class for holding the value of Entity * @@ -28,64 +42,64 @@ */ public class EntityValue extends VABModelMap { - private EntityValue() {} - + private EntityValue() { + } + public EntityValue(Collection statements, IReference asset) { put(Entity.STATEMENT, statements); put(Entity.ASSET, asset); } - + /** * Creates a EntityValue object from a map * - * @param obj a EntityValue object as raw map + * @param obj + * a EntityValue object as raw map * @return a EntityValue object, that behaves like a facade for the given map */ public static EntityValue createAsFacade(Map obj) { if (obj == null) { return null; } - + EntityValue facade = new EntityValue(); facade.setMap(obj); return facade; } - + @SuppressWarnings("unchecked") public static boolean isEntityValue(Object value) { - + // Given Object must be a Map - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - + // Given Map must contain all necessary Entries - if(!(map.get(Entity.STATEMENT) instanceof Collection - && Reference.isReference(map.get(Entity.ASSET)))) { + if (!(map.get(Entity.STATEMENT) instanceof Collection && Reference.isReference(map.get(Entity.ASSET)))) { return false; } - + try { // Try to create a Facade for each Element // If one of the Objects in STATEMENT is not a smElement, // SubmodelElementFacadeFactory throws an Exception - ((Collection>) map.get(Entity.STATEMENT)).stream() - .forEach(SubmodelElementFacadeFactory::createSubmodelElement); + ((Collection>) map.get(Entity.STATEMENT)).stream().forEach(SubmodelElementFacadeFactory::createSubmodelElement); } catch (RuntimeException e) { return false; } - + return true; } - + @SuppressWarnings("unchecked") public Collection getStatement() { Collection> elements = (Collection>) get(Entity.STATEMENT); return elements.stream().map(e -> SubmodelElementFacadeFactory.createSubmodelElement(e)).collect(Collectors.toList()); } - + @SuppressWarnings("unchecked") public IReference getAsset() { return Reference.createAsFacade((Map) get(Entity.ASSET)); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java index f04bd0b7..d1871d8e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/event/BasicEvent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.event; @@ -29,70 +44,74 @@ public class BasicEvent extends SubmodelElement implements IBasicEvent { public static final String MODELTYPE = "BasicEvent"; public static final String OBSERVED = "observed"; - + public BasicEvent() { // Add model type putAll(new ModelType(MODELTYPE)); } - + public BasicEvent(IReference observed) { this(); put(OBSERVED, observed); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort * @param observed */ public BasicEvent(String idShort, IReference observed) { super(idShort); - + // Add model type putAll(new ModelType(MODELTYPE)); put(OBSERVED, observed); } - + @Override protected KeyElements getKeyElement() { return KeyElements.BASICEVENT; } - + /** * Creates a BasicEvent object from a map * - * @param obj a BasicEvent object as raw map + * @param obj + * a BasicEvent object as raw map * @return a BasicEvent object, that behaves like a facade for the given map */ public static BasicEvent createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { - throw new MetamodelConstructionException(BasicEvent.class, obj); + throw new MetamodelConstructionException(BasicEvent.class, obj); } - + BasicEvent facade = new BasicEvent(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { return SubmodelElement.isValid(obj) && obj.containsKey(OBSERVED); } - + /** - * Returns true if the given submodel element map is recognized as an BasicEvent element + * Returns true if the given submodel element map is recognized as an BasicEvent + * element */ public static boolean isBasicEvent(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained (fallback) + // Either model type is set or the element type specific attributes are + // contained (fallback) return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(OBSERVED)); } @@ -106,14 +125,13 @@ public IReference getObserved() { public IReference getValue() { return getObserved(); } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(Reference.isReference(value)) { + if (Reference.isReference(value)) { put(OBSERVED, Reference.createAsFacade((Map) value)); - } - else { + } else { throw new IllegalArgumentException("Given Object is not a Reference"); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java index 193818c5..b8fd224f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/AsyncInvocation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; @@ -14,7 +29,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; -import org.apache.poi.ss.formula.functions.T; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation; /** @@ -29,63 +43,68 @@ public class AsyncInvocation implements IAsyncInvocation { private String operationId; private CompletableFuture future; + + // This variable is used to write the result of the function into private Object result; + private RuntimeException exception; - + @SuppressWarnings("unchecked") public AsyncInvocation(Operation operation, int timeout, Object... parameters) { operationId = operation.getIdShort(); - + Function invokable = (Function) operation.get(Operation.INVOKABLE); + + // This future executes the given function and a timeout future. + // It finishes when either the timeout is over or the function finishes. + + // The result of the function is written into the "result" variable + // as it can not be returned through the Future due to the timeout check future = CompletableFuture.supplyAsync( // Run Operation asynchronously () -> invokable.apply(parameters)) // Accept either result or throw exception on timeout .acceptEither(setTimeout(timeout), - // result accepted => write result (or timeout exception) - futureResult -> this.result = futureResult - ).exceptionally(throwable -> { + // result accepted => write result (or timeout exception) + futureResult -> this.result = futureResult) + .exceptionally(throwable -> { // result not accepted? set operation state if (throwable.getCause() instanceof OperationExecutionTimeoutException) { exception = (RuntimeException) throwable.getCause(); } else { // result not accepted? set operation state - exception = new OperationExecutionErrorException( - "Exception while executing Operation Operation '" + operationId + "'", throwable); + exception = new OperationExecutionErrorException("Exception while executing Operation Operation '" + operationId + "'", throwable); } return null; }); } - + /** * Function for scheduling a timeout function with completable futures */ - private CompletableFuture setTimeout(int timeout) { - CompletableFuture timeoutFuture = new CompletableFuture<>(); - delayer.schedule( - () -> timeoutFuture.completeExceptionally( - new OperationExecutionTimeoutException("Operation " + operationId + " timed out")), - timeout, TimeUnit.MILLISECONDS); + private CompletableFuture setTimeout(int timeout) { + CompletableFuture timeoutFuture = new CompletableFuture<>(); + delayer.schedule(() -> timeoutFuture.completeExceptionally(new OperationExecutionTimeoutException("Operation " + operationId + " timed out")), timeout, TimeUnit.MILLISECONDS); return timeoutFuture; } @Override public Object getResult() { try { + // The future itself always returns null () + // Actual return value is written into result variable inside future future.get(); } catch (Exception e) { // Some RuntimeException occured when finishing the future - throw new OperationExecutionErrorException( - "Exception while executing Operation Operation '" + operationId + "'", e.getCause()); + throw new OperationExecutionErrorException("Exception while executing Operation '" + operationId + "'", e.getCause()); } - if (exception instanceof OperationExecutionTimeoutException - || exception instanceof OperationExecutionErrorException) { + if (exception instanceof OperationExecutionTimeoutException || exception instanceof OperationExecutionErrorException) { // Future finished with an exception throw exception; } return result; } - + @Override public boolean isFinished() { return future.isDone(); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java index 0f2c0621..c765ec99 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/Operation.java @@ -1,18 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; import java.util.ArrayList; import java.util.Collection; import java.util.Map; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; @@ -25,7 +42,7 @@ import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings; import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; -import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException; +import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider; /** * Operation as defined in DAAS document
@@ -44,43 +61,40 @@ public class Operation extends SubmodelElement implements IOperation { public static final String INVOKABLE = "invokable"; public static final String MODELTYPE = "Operation"; - + + // Extension of DAAS specification for function storage public static final String INVOKE = "invoke"; + public static final String IS_WRAPPED_INVOKABLE = "isWrappedInvokable"; - /** - * Constructor - */ public Operation() { - // Add model type - putAll(new ModelType(MODELTYPE)); - - // Input variables - put(IN, new ArrayList()); - - // Output variables - put(OUT, new ArrayList()); - - // Variables, that are input and output - put(INOUT, new ArrayList()); + this(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } - + /** * Constructor accepting only mandatory attribute + * * @param idShort */ public Operation(String idShort) { - super(idShort); - // Add model type - putAll(new ModelType(MODELTYPE)); - - // Input variables - setInputVariables(new ArrayList()); - - // Output variables - setOutputVariables(new ArrayList()); + this(); + setIdShort(idShort); + } - // Variables, that are input and output - setInOutputVariables(new ArrayList()); + /** + * @param in + * Input parameter of the operation. + * @param out + * Output parameter of the operation. + * @param inout + * Inoutput parameter of the operation. + * + */ + public Operation(Collection in, Collection out, Collection inout) { + super(); + putAll(new ModelType(MODELTYPE)); + setInputVariables(in); + setOutputVariables(out); + setInOutputVariables(inout); } /** @@ -92,25 +106,12 @@ public Operation(String idShort) { * @param inout * Inoutput parameter of the operation. * @param function - * the concrete function + * the concrete function that can directly handle unwrapped values * */ - public Operation(Collection in, Collection out, - Collection inout, Function function) { - // Add model type - putAll(new ModelType(MODELTYPE)); - - // Input variables - put(IN, in); - - // Output variables - put(OUT, out); - - // Output variables - put(INOUT, inout); - - // Extension of DAAS specification for function storage - put(INVOKABLE, function); + public Operation(Collection in, Collection out, Collection inout, Function function) { + this(in, out, inout); + setInvokable(function); } /** @@ -134,19 +135,19 @@ public static Operation createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Operation.class, obj); } - + Operation ret = new Operation(); ret.setMap(obj); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Checks whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ public static boolean isValid(Map obj) { @@ -158,16 +159,16 @@ public static boolean isValid(Map obj) { */ @SuppressWarnings("unchecked") public static boolean isOperation(Object value) { - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - + String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained - return MODELTYPE.equals(modelType) - || (modelType == null && (map.containsKey(IN) && map.containsKey(OUT) && map.containsKey(INOUT))); + // Either model type is set or the element type specific attributes are + // contained + return MODELTYPE.equals(modelType) || (modelType == null && (map.containsKey(IN) && map.containsKey(OUT) && map.containsKey(INOUT))); } @Override @@ -185,33 +186,35 @@ public Collection getInOutputVariables() { return transformToOperationVariables(get(Operation.INOUT)); } - @SuppressWarnings("unchecked") - private Collection transformToOperationVariables(Object obj) { - if (obj instanceof Collection) { - Collection> map = (Collection>) obj; - Collection ret = new ArrayList<>(); - for (Map m : map) { - ret.add(OperationVariable.createAsFacade(m)); - } - return ret; - } else { - return new ArrayList<>(); - } + @Override + public Object invoke(Object... params) { + return invokeSimple(params); } - @SuppressWarnings("unchecked") @Override - public Object invoke(Object... params) { - if (params.length != getInputVariables().size()) { - throw new WrongNumberOfParametersException(getIdShort(), getInputVariables(), params); + public Object invokeSimple(Object... simpleParams) { + OperationCheckHelper.checkValidParameterLength(simpleParams.length, getIdShort(), getInputVariables()); + OperationCheckHelper.checkSubmodelElementExpectedTypes(simpleParams, getInputVariables()); + if (isWrappedInvokable()) { + return invokeWrappedInvokableWithSimpleParameters(simpleParams); + } else { + return directlyInvokeSimpleInvokable(simpleParams); } - return ((Function) get(INVOKABLE)).apply(params); + } + + private Object invokeWrappedInvokableWithSimpleParameters(Object... simpleParams) { + Map wrappedParamMap = OperationHelper.wrapSimpleInputParametersInMap(simpleParams, getInputVariables()); + OperationCheckHelper.checkSubmodelElementAsParameter(wrappedParamMap, getInputVariables()); + SubmodelElement[] wrappedResult = directlyInvokeWrappedInvokable(wrappedParamMap); + return OperationHelper.unwrapResult(wrappedResult); } @Override public SubmodelElement[] invoke(SubmodelElement... elems) { - throw new UnsupportedOperationException( - "SubmodelElement matching logic is only supported for connected Operations"); + OperationCheckHelper.checkValidParameterLength(elems.length, getIdShort(), getInputVariables()); + OperationCheckHelper.checkSubmodelElementAsParameter(elems, getInputVariables()); + Map seMap = OperationHelper.convertSubmodelElementArrayToMap(elems); + return invokeWrappedUnchecked(seMap); } @Override @@ -236,8 +239,58 @@ public void setInOutputVariables(Collection inOut) { put(Operation.INOUT, inOut); } + /** + * Sets an invokable that handles submodel elements. + * + * @param endpoint + */ + public void setWrappedInvokable(Function, SubmodelElement[]> endpoint) { + Function wrappedInvokable = prepareWrappedFunctionForVAB(endpoint); + setInvokable(wrappedInvokable); + put(Operation.IS_WRAPPED_INVOKABLE, true); + } + + /** + * Sets an invokable that handles a consumer. + * + * @param consumer + */ + public void setWrappedInvokable(Consumer> consumer) { + Consumer wrappedInvokable = prepareWrappedFunctionForVAB(consumer); + setInvokable(wrappedInvokable); + put(Operation.IS_WRAPPED_INVOKABLE, true); + } + + /** + * Sets an invokable that handles a supplier. + * + * @param supplier + */ + public void setWrappedInvokable(Supplier supplier) { + Supplier wrappedInvokable = prepareWrappedFunctionForVAB(supplier); + setInvokable(wrappedInvokable); + put(Operation.IS_WRAPPED_INVOKABLE, true); + } + + /** + * Sets an invokable that handles direct values. + * + * @param endpoint + */ public void setInvokable(Function endpoint) { - put(Operation.INVOKABLE, endpoint); + setSimpleInvokable(endpoint); + } + + public void setInvokable(Runnable runnable) { + setSimpleInvokable(runnable); + } + + public void setInvokable(Supplier supplier) { + setSimpleInvokable(supplier); + } + + public void setInvokable(Consumer consumer) { + setSimpleInvokable(consumer); } @Override @@ -264,7 +317,7 @@ public String getCategory() { public LangStrings getDescription() { return Referable.createAsFacade(this, getKeyElement()).getDescription(); } - + @Override protected KeyElements getKeyElement() { return KeyElements.OPERATION; @@ -302,4 +355,65 @@ public Operation getLocalCopy() { copy.setInOutputVariables(inoutVarCopy); return copy; } + + private void setSimpleInvokable(Object invokable) { + put(Operation.INVOKABLE, invokable); + put(Operation.IS_WRAPPED_INVOKABLE, false); + } + + @SuppressWarnings("unchecked") + private Collection transformToOperationVariables(Object obj) { + if (obj instanceof Collection) { + Collection> mapCollection = (Collection>) obj; + return transformToOperationVariable(mapCollection); + } else { + return new ArrayList<>(); + } + } + + private Collection transformToOperationVariable(Collection> mapCollection) { + Collection ret = new ArrayList<>(); + for (Map m : mapCollection) { + OperationVariable opVariable = OperationVariable.createAsFacade(m); + ret.add(opVariable); + } + return ret; + } + + private Object directlyInvokeSimpleInvokable(Object[] simpleParams) { + return new VABLambdaProvider(this).invokeOperation(INVOKABLE, simpleParams); + } + + private SubmodelElement[] invokeWrappedUnchecked(Map wrappedParamMap) { + if (isWrappedInvokable()) { + return directlyInvokeWrappedInvokable(wrappedParamMap); + } else { + Object[] unwrappedParams = OperationHelper.unwrapInputParameters(wrappedParamMap, getInputVariables()); + Object unwrappedResult = directlyInvokeSimpleInvokable(unwrappedParams); + return OperationHelper.wrapResult(unwrappedResult, getOutputVariables()); + } + } + + private SubmodelElement[] directlyInvokeWrappedInvokable(Map wrappedParamMap) { + return (SubmodelElement[]) new VABLambdaProvider(this).invokeOperation(INVOKABLE, wrappedParamMap); + } + + private boolean isWrappedInvokable() { + Object isWrappedInvokable = get(IS_WRAPPED_INVOKABLE); + return isWrappedInvokable != null && ((boolean) isWrappedInvokable); + } + + @SuppressWarnings("unchecked") + private Function prepareWrappedFunctionForVAB(Function, SubmodelElement[]> wrappedFunction) { + return elemArray -> wrappedFunction.apply((Map) elemArray[0]); + } + + @SuppressWarnings("unchecked") + private Consumer prepareWrappedFunctionForVAB(Consumer> consumer) { + return elemArray -> consumer.accept((Map) elemArray[0]); + } + + private Supplier prepareWrappedFunctionForVAB(Supplier supplier) { + return () -> supplier.get(); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationCheckHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationCheckHelper.java new file mode 100644 index 00000000..42f324c8 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationCheckHelper.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; +import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; +import org.eclipse.basyx.vab.exception.provider.WrongNumberOfParametersException; + +/** + * Checks submodel inputs of {@link Operation} to be the expected submodels. + * + * @author fischer, espen + */ +public class OperationCheckHelper { + + private OperationCheckHelper() { + } + + /** + * Checks parameter signature for given complex parameters for an operation. + * + * @param givenParameters + * @param expectedVariables + */ + public static void checkSubmodelElementAsParameter(SubmodelElement[] givenParameters, Collection expectedVariables) { + Map paramsByIdShortMap = createParameterMap(givenParameters); + + compareGivenWithExpectedVariables(paramsByIdShortMap, expectedVariables); + } + + /** + * Checks parameter signature for given complex parameters for an operation. + * + * @param givenParameterMap + * @param expectedVariables + */ + public static void checkSubmodelElementAsParameter(Map givenParameterMap, Collection expectedVariables) { + compareGivenWithExpectedVariables(givenParameterMap, expectedVariables); + } + + /** + * Checks if given parameters correspond with the actual length. + * + * @param actualParameterLength + * of the given parameters + * @param idShort + * of the operation + * @param inputVariables + */ + public static void checkValidParameterLength(int actualParameterLength, String idShort, Collection inputVariables) { + if (actualParameterLength != inputVariables.size()) { + throw new WrongNumberOfParametersException(idShort, inputVariables, actualParameterLength); + } + } + + /** + * Checks if the expected variables allow setValue to the given parameters. + * + * @param givenParameters + * @param expectedVariables + */ + public static void checkSubmodelElementExpectedTypes(Object[] givenParameters, Collection expectedVariables) { + IOperationVariable[] expectedVarArray = expectedVariables.toArray(new IOperationVariable[expectedVariables.size()]); + + for (int i = 0; i < expectedVarArray.length; i++) { + checkSubmodelElementExpectedType(expectedVarArray[i], givenParameters[i]); + } + + } + + private static void checkSubmodelElementExpectedType(IOperationVariable iOperationVariable, Object value) { + SubmodelElement submodelElement = iOperationVariable.getValue().getLocalCopy(); + + try { + submodelElement.setValue(value); + } catch (Exception e) { + throw new MalformedRequestException(e); + } + } + + private static void compareGivenWithExpectedVariables(Map paramsByIdShortMap, Collection expectedVariables) { + for (IOperationVariable expectedVariable : expectedVariables) { + compareExpectedVariableToGivenVariableMap(expectedVariable, paramsByIdShortMap); + } + } + + private static void compareExpectedVariableToGivenVariableMap(IOperationVariable expectedVariable, Map paramsByIdShortMap) { + SubmodelElement expectedParam = (SubmodelElement) expectedVariable.getValue(); + SubmodelElement givenParam = paramsByIdShortMap.get(expectedParam.getIdShort()); + + compareSubmodelElements(expectedParam, givenParam); + } + + private static void compareSubmodelElements(SubmodelElement expectedParam, SubmodelElement givenParam) { + checkIfSubmodelElementExists(expectedParam, givenParam); + checkModelType(expectedParam, givenParam); + } + + private static Map createParameterMap(SubmodelElement[] params) { + Map parameterMap = new LinkedHashMap<>(); + for (SubmodelElement param : params) { + String parameterKey = getKeyForParameter(param); + parameterMap.put(parameterKey, param); + } + return parameterMap; + } + + private static String getKeyForParameter(SubmodelElement param) { + IOperationVariable paramOperationVariable = new OperationVariable(param); + return paramOperationVariable.getValue().getIdShort(); + } + + private static void checkIfSubmodelElementExists(SubmodelElement expectedParam, SubmodelElement givenParam) { + if (givenParam == null) { + throw new MalformedRequestException("Expected parameter " + expectedParam.getIdShort() + " missing in request"); + } + } + + private static void checkModelType(SubmodelElement expectedParam, SubmodelElement givenParam) { + if (!expectedParam.getModelType().equals(givenParam.getModelType())) { + throw new MalformedRequestException("Given modelType " + givenParam.getModelType() + " differs from expected modelType " + expectedParam.getModelType()); + } + } +} diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java index a3bf9510..c88bf1e2 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionErrorException.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; @@ -17,19 +32,16 @@ */ public class OperationExecutionErrorException extends RuntimeException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Store message */ protected String message = null; - - + /** * Constructor */ @@ -37,19 +49,16 @@ public OperationExecutionErrorException(String msg) { // Store message message = msg; } - - + public OperationExecutionErrorException(Exception e) { super(e); } - public OperationExecutionErrorException(String message, Throwable cause) { super(cause); this.message = message; } - /** * Return detailed message */ diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java index 4ad50212..4a79f928 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationExecutionTimeoutException.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; @@ -17,19 +32,16 @@ */ public class OperationExecutionTimeoutException extends RuntimeException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Store message */ protected String message = null; - - + /** * Constructor */ @@ -37,19 +49,16 @@ public OperationExecutionTimeoutException(String msg) { // Store message message = msg; } - - + public OperationExecutionTimeoutException(Exception e) { super(e); } - public OperationExecutionTimeoutException(String message, Throwable cause) { super(cause); this.message = message; } - /** * Return detailed message */ diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java index cee7219f..27cd000f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationHelper.java @@ -1,15 +1,38 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.StreamSupport; + import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; @@ -17,7 +40,64 @@ public class OperationHelper { public static Property createPropertyTemplate(ValueType type) { Property prop = new Property(); prop.setValueType(type); - prop.setModelingKind(ModelingKind.TEMPLATE); + prop.setKind(ModelingKind.TEMPLATE); return prop; } + + public static SubmodelElement[] wrapParameters(Collection inputVariables, Object... unwrappedParameters) { + IOperationVariable[] inputVarArray = inputVariables.toArray(new IOperationVariable[inputVariables.size()]); + SubmodelElement[] wrappedParameters = new SubmodelElement[inputVariables.size()]; + for (int i = 0; i < wrappedParameters.length; i++) { + wrappedParameters[i] = wrapSingleParameter(inputVarArray[i], unwrappedParameters[i]); + } + return wrappedParameters; + } + + public static Map wrapSimpleInputParametersInMap(Object[] simpleParams, Collection inputVariables) { + SubmodelElement[] wrappedParameterArray = OperationHelper.wrapParameters(inputVariables, simpleParams); + return convertSubmodelElementArrayToMap(wrappedParameterArray); + } + + public static SubmodelElement[] wrapResult(Object unwrappedResult, Collection outputVariables) { + if (outputVariables.isEmpty()) { + return new SubmodelElement[] {}; + } + IOperationVariable resultTemplate = outputVariables.iterator().next(); + SubmodelElement wrappedResult = OperationHelper.wrapSingleParameter(resultTemplate, unwrappedResult); + return new SubmodelElement[] { wrappedResult }; + } + + public static SubmodelElement wrapSingleParameter(IOperationVariable template, Object simpleValue) { + ISubmodelElement submodelElementTemplate = template.getValue(); + SubmodelElement submodelElementCopy = submodelElementTemplate.getLocalCopy(); + submodelElementCopy.setValue(simpleValue); + return submodelElementCopy; + } + + public static Object[] unwrapInputParameters(Map wrappedParamMap, Collection inputVariables) { + return StreamSupport.stream(inputVariables.spliterator(), false).map(inputVar -> unwrapInputParameter(wrappedParamMap, inputVar)).toArray(); + } + + public static Object unwrapInputParameter(Map wrappedParamMap, IOperationVariable parameter) { + ISubmodelElement parameterElement = parameter.getValue(); + String parameterName = parameterElement.getIdShort(); + SubmodelElement passedParameterElement = wrappedParamMap.get(parameterName); + return passedParameterElement.getValue(); + } + + public static Object unwrapResult(SubmodelElement[] result) { + if (result != null && result.length > 0) { + return result[0].getValue(); + } else { + return null; + } + } + + public static Map convertSubmodelElementArrayToMap(SubmodelElement[] elems) { + Map seMap = new LinkedHashMap<>(); + for (SubmodelElement se : elems) { + seMap.put(se.getIdShort(), se); + } + return seMap; + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java index 0376c83f..b5fd2f8e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/operation/OperationVariable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation; @@ -33,7 +48,7 @@ */ public class OperationVariable extends VABModelMap implements IOperationVariable { public static final Logger logger = LoggerFactory.getLogger(OperationVariable.class); - + public static final String MODELTYPE = "OperationVariable"; /** @@ -45,7 +60,7 @@ public class OperationVariable extends VABModelMap implements IOperation public OperationVariable(SubmodelElement value) { // Add model type putAll(new ModelType(MODELTYPE)); - + setValue(value); } @@ -53,51 +68,51 @@ public OperationVariable() { // Add model type putAll(new ModelType(MODELTYPE)); } - + /** * Creates an OperationVariable object from a map * - * @param obj an OperationVariable object as raw map - * @return an OperationVariable object, that behaves like a facade for the given map + * @param obj + * an OperationVariable object as raw map + * @return an OperationVariable object, that behaves like a facade for the given + * map */ public static OperationVariable createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { - throw new MetamodelConstructionException(OperationVariable.class, obj); + throw new MetamodelConstructionException(OperationVariable.class, obj); } - + OperationVariable facade = new OperationVariable(); facade.setMap(obj); return facade; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { - return obj != null && - obj.containsKey(Property.VALUE) && - SubmodelElement.isValid((Map) obj.get(Property.VALUE)); + return obj != null && obj.containsKey(Property.VALUE) && SubmodelElement.isValid((Map) obj.get(Property.VALUE)); } /** * Sets value of operation variable * * @param value - * @throws RuntimeException if modelingkind of the value is not of modelingkind.template + * @throws RuntimeException + * if modelingkind of the value is not of modelingkind.template */ @SuppressWarnings("unchecked") public void setValue(ISubmodelElement value) { - if (value.getModelingKind() != ModelingKind.TEMPLATE) { - // TODO: Change with 1.0 Release + if (value.getKind() != ModelingKind.TEMPLATE) { logger.warn("Modeling kind of Operation variable was wrong and automatically changed to ModelingKind.TEMPLATE"); - HasKind.createAsFacade((Map) value).setModelingKind(ModelingKind.TEMPLATE); + HasKind.createAsFacade((Map) value).setKind(ModelingKind.TEMPLATE); } put(Property.VALUE, value); } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java index c0edffc9..9028a3c5 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship; @@ -22,7 +37,8 @@ /** * AnnotatedRelationshipElement as defined in DAAS document
- * An annotated relationship element is a relationship element that can be annotated with additional data elements. + * An annotated relationship element is a relationship element that can be + * annotated with additional data elements. * * @author schnicke, conradi * @@ -47,25 +63,21 @@ public void setAnnotation(Collection annotations) { put(ANNOTATIONS, annotations); } - @SuppressWarnings("unchecked") - private Collection getAnnotations() { + private Collection getAnnotations() { Collection list = new ArrayList<>(); Collection> annotations = (Collection>) get(ANNOTATIONS); - + // If non mandatory element annotations does not exist, return empty list - if(annotations == null) { + if (annotations == null) { return list; } - - annotations.stream() - .map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m)) - .filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement)e)); - + + annotations.stream().map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m)).filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement) e)); + return list; } - @SuppressWarnings("unchecked") @Override public void setValue(Object obj) { @@ -126,4 +138,10 @@ public void setValue(AnnotatedRelationshipElementValue value) { setAnnotation(value.getAnnotations()); } + @Override + public AnnotatedRelationshipElement getLocalCopy() { + AnnotatedRelationshipElement copy = new AnnotatedRelationshipElement(); + copy.putAll(this); + return copy; + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java index b65f2ba6..5dbba8a2 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/AnnotatedRelationshipElementValue.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship; @@ -52,27 +67,26 @@ public static AnnotatedRelationshipElementValue createAsFacade(Map map = (Map) value; return Reference.isReference(map.get(AnnotatedRelationshipElement.ANNOTATIONS)); } } - + @SuppressWarnings("unchecked") public Collection getAnnotations() { Collection list = new ArrayList<>(); - + // Feed all Elements in ANNOTATIONS through the SubmodelElementFacadeFactory // then collect them in a List - ((Collection>) get(AnnotatedRelationshipElement.ANNOTATIONS)).stream() - .map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m)) - .filter(e -> e instanceof IDataElement).forEach(e -> list.add((IDataElement)e)); - + ((Collection>) get(AnnotatedRelationshipElement.ANNOTATIONS)).stream().map(m -> SubmodelElementFacadeFactory.createSubmodelElement(m)).filter(e -> e instanceof IDataElement) + .forEach(e -> list.add((IDataElement) e)); + return list; } diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java index af0b31d6..e805bf9e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship; @@ -32,7 +47,7 @@ public class RelationshipElement extends SubmodelElement implements IRelationshi public static final String FIRST = "first"; public static final String SECOND = "second"; public static final String MODELTYPE = "RelationshipElement"; - + /** * Constructor */ @@ -51,13 +66,14 @@ public RelationshipElement() { public RelationshipElement(IReference first, IReference second) { // Add model type putAll(new ModelType(MODELTYPE)); - + put(FIRST, first); put(SECOND, second); } - + /** * Constructor with only mandatory attributes + * * @param idShort * @param first * @param second @@ -66,54 +82,53 @@ public RelationshipElement(String idShort, IReference first, IReference second) this(first, second); setIdShort(idShort); } - + /** * Creates a RelationshipElement object from a map * - * @param obj a RelationshipElement object as raw map - * @return a RelationshipElement object, that behaves like a facade for the given map + * @param obj + * a RelationshipElement object as raw map + * @return a RelationshipElement object, that behaves like a facade for the + * given map */ public static RelationshipElement createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(RelationshipElement.class, obj); } - - + RelationshipElement ret = new RelationshipElement(); ret.setMap(obj); return ret; } - + /** - * Check whether all mandatory elements for the metamodel - * exist in a map + * Check whether all mandatory elements for the metamodel exist in a map + * * @return true/false */ @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { - return SubmodelElement.isValid(obj) && - obj.containsKey(FIRST) && - obj.containsKey(SECOND) && - Reference.isValid((Map)obj.get(FIRST)) && - Reference.isValid((Map)obj.get(SECOND)); + return SubmodelElement.isValid(obj) && obj.containsKey(FIRST) && obj.containsKey(SECOND) && Reference.isValid((Map) obj.get(FIRST)) && Reference.isValid((Map) obj.get(SECOND)); } /** - * Returns true if the given submodel element map is recognized as a RelationshipElement + * Returns true if the given submodel element map is recognized as a + * RelationshipElement */ public static boolean isRelationshipElement(Map map) { String modelType = ModelType.createAsFacade(map).getName(); - // Either model type is set or the element type specific attributes are contained + // Either model type is set or the element type specific attributes are + // contained return MODELTYPE.equals(modelType) || (modelType == null && map.containsKey(FIRST) && map.containsKey(SECOND)); } public void setFirst(IReference first) { put(RelationshipElement.FIRST, first); - + } @SuppressWarnings("unchecked") @@ -123,14 +138,14 @@ public IReference getFirst() { public void setSecond(IReference second) { put(RelationshipElement.SECOND, second); - + } @SuppressWarnings("unchecked") public IReference getSecond() { return Reference.createAsFacade((Map) get(RelationshipElement.SECOND)); } - + @Override protected KeyElements getKeyElement() { return KeyElements.RELATIONSHIPELEMENT; @@ -140,13 +155,12 @@ protected KeyElements getKeyElement() { public RelationshipElementValue getValue() { return new RelationshipElementValue(getFirst(), getSecond()); } - + @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - if(RelationshipElementValue.isRelationshipElementValue(value)) { - RelationshipElementValue rev = - RelationshipElementValue.createAsFacade((Map) value); + if (RelationshipElementValue.isRelationshipElementValue(value)) { + RelationshipElementValue rev = RelationshipElementValue.createAsFacade((Map) value); setValue(rev); } else { throw new IllegalArgumentException("Given Object is not an RelationshipElementValue"); diff --git a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java index 952540b9..22a8a8b7 100644 --- a/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java +++ b/src/main/java/org/eclipse/basyx/submodel/metamodel/map/submodelelement/relationship/RelationshipElementValue.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship; @@ -15,7 +30,6 @@ import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; import org.eclipse.basyx.vab.model.VABModelMap; - /** * Container class for holding the value of RelationshipElement * @@ -26,50 +40,51 @@ public class RelationshipElementValue extends VABModelMap { protected RelationshipElementValue() { } - + public RelationshipElementValue(IReference first, IReference second) { put(RelationshipElement.FIRST, first); put(RelationshipElement.SECOND, second); } - + /** * Creates a RelationshipElementValue object from a map * - * @param obj a RelationshipElementValue object as raw map - * @return a RelationshipElementValue object, that behaves like a facade for the given map + * @param obj + * a RelationshipElementValue object as raw map + * @return a RelationshipElementValue object, that behaves like a facade for the + * given map */ public static RelationshipElementValue createAsFacade(Map obj) { if (obj == null) { return null; } - + RelationshipElementValue facade = new RelationshipElementValue(); facade.setMap(obj); return facade; } - + @SuppressWarnings("unchecked") public static boolean isRelationshipElementValue(Object value) { - + // Given Object must be a Map - if(!(value instanceof Map)) { + if (!(value instanceof Map)) { return false; } - + Map map = (Map) value; - - return Reference.isReference(map.get(RelationshipElement.FIRST)) - && Reference.isReference(map.get(RelationshipElement.SECOND)); + + return Reference.isReference(map.get(RelationshipElement.FIRST)) && Reference.isReference(map.get(RelationshipElement.SECOND)); } - + @SuppressWarnings("unchecked") public IReference getFirst() { return Reference.createAsFacade((Map) get(RelationshipElement.FIRST)); } - + @SuppressWarnings("unchecked") public IReference getSecond() { return Reference.createAsFacade((Map) get(RelationshipElement.SECOND)); } - + } diff --git a/src/main/java/org/eclipse/basyx/submodel/observer/IObserver.java b/src/main/java/org/eclipse/basyx/submodel/observer/IObserver.java new file mode 100644 index 00000000..44b8e623 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/observer/IObserver.java @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.submodel.observer; + +/** + * Generic interface for any observer + * + * @author haque + * + */ +public interface IObserver { + +} diff --git a/src/main/java/org/eclipse/basyx/submodel/observer/Observable.java b/src/main/java/org/eclipse/basyx/submodel/observer/Observable.java new file mode 100644 index 00000000..32ab8884 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/observer/Observable.java @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.submodel.observer; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Generic implementation of an Observable. This class contains all common + * operations an Observable is supposed to do. Java generics is used to specify + * which type of Observable is required + * + * @author haque + * + * @param + * can be Observers which extends IObserver + */ +public class Observable { + + public Collection observers = new ArrayList(); + + /** + * Adds an observer to the subscriber list + * + * @param observer + * the observer to be added + */ + public void addObserver(T observer) { + observers.add(observer); + } + + /** + * Removes an observer from the subscriber list + * + * @param observer + * the observer to be removed + * @return true if the observer was found and removed; false otherwise + */ + public boolean removeObserver(T observer) { + return observers.remove(observer); + } +} diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java index f39cf0ee..1c23830e 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/MultiSubmodelElementProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi; @@ -23,7 +38,8 @@ import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; /** - * Provider that handles container properties. Container properties can contain other submodel elements. + * Provider that handles container properties. Container properties can contain + * other submodel elements. * * @author espen, conradi * @@ -33,7 +49,8 @@ public class MultiSubmodelElementProvider implements IModelProvider { public static final String ELEMENTS = "submodelElements"; public static final String VALUE = "value"; - // The VAB model provider containing the submodelElements this SubmodelElementProvider is based on + // The VAB model provider containing the submodelElements this + // SubmodelElementProvider is based on // Assumed to be a map that maps idShorts to the submodel elements private IModelProvider modelProvider; @@ -52,7 +69,8 @@ protected Collection> getElementsList() { Object elements = modelProvider.getValue(""); Map> all = (Map>) elements; - // Feed all ELements through their Providers, in case someting needs to be done to them (e.g. smElemCollections) + // Feed all ELements through their Providers, in case someting needs to be done + // to them (e.g. smElemCollections) return all.entrySet().stream().map(e -> (Map) getSingleElement(ELEMENTS + "/" + e.getKey())).collect(Collectors.toList()); } @@ -83,12 +101,12 @@ private Object getSingleElement(String path) { public Object getValue(String path) throws ProviderException { String[] pathElements = VABPathTools.splitPath(path); String qualifier = pathElements[0]; - - if(!qualifier.equals(ELEMENTS)) { + + if (!qualifier.equals(ELEMENTS)) { // No other qualifier in a submodel element container can be directly accessed throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements"); } - + if (pathElements.length == 1) { // returns all elements return getElementsList(); @@ -109,7 +127,7 @@ public void setValue(String path, Object newValue) throws ProviderException { IModelProvider elementProxy = getElementProxy(pathElements); String subPath = VABPathTools.buildPath(pathElements, 2); - + new SubmodelElementProvider(elementProxy).setValue(subPath, newValue); } @@ -119,12 +137,11 @@ public void createValue(String path, Object newEntity) throws ProviderException String[] pathElements = VABPathTools.splitPath(path); String qualifier = pathElements[0]; String subPath = VABPathTools.buildPath(pathElements, 2); - if (!qualifier.equals(ELEMENTS)) { throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements"); } - + // Check if the passed element is a SubmodelElementCollection. If yes, the value // of the "value" key needs to be handled if (SubmodelElementCollection.isSubmodelElementCollection((Map) newEntity)) { @@ -151,15 +168,15 @@ public void deleteValue(String path) throws ProviderException { String qualifier = pathElements[0]; String subPath; IModelProvider elementProvider; - + if (!qualifier.equals(ELEMENTS)) { throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements"); } // If the first Element is a Collection, use its Provider - if(pathElements.length > 2) { + if (pathElements.length > 2) { IModelProvider elementProxy = getElementProxy(pathElements); - elementProvider = new SubmodelElementProvider(elementProxy); + elementProvider = new SubmodelElementProvider(elementProxy); subPath = VABPathTools.buildPath(pathElements, 2); } else { elementProvider = modelProvider; @@ -184,7 +201,7 @@ public Object invokeOperation(String path, Object... parameters) throws Provider if (!qualifier.equals(ELEMENTS)) { throw new MalformedRequestException("Given path '" + path + "' does not start with /submodelElements"); } - + IModelProvider elementProxy = getElementProxy(pathElements); return new SubmodelElementProvider(elementProxy).invokeOperation(subPath, parameters); } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java index 70ddcd26..8b827377 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/OperationProvider.java @@ -1,18 +1,37 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; @@ -20,19 +39,20 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; import org.eclipse.basyx.submodel.restapi.operation.AsyncOperationHandler; import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse; +import org.eclipse.basyx.submodel.restapi.operation.DelegatedInvocationManager; import org.eclipse.basyx.submodel.restapi.operation.ExecutionState; import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest; import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; import org.eclipse.basyx.vab.exception.provider.ProviderException; -import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory; /** * Handles operations according to AAS meta model. * - * @author schnicke + * @author schnicke, espen, fischer * */ public class OperationProvider implements IModelProvider { @@ -41,9 +61,15 @@ public class OperationProvider implements IModelProvider { public String operationId; private IModelProvider modelProvider; + private DelegatedInvocationManager invocationHelper; public OperationProvider(IModelProvider modelProvider) { + this(modelProvider, new DelegatedInvocationManager(new HTTPConnectorFactory())); + } + + public OperationProvider(IModelProvider modelProvider, DelegatedInvocationManager invocationHelper) { this.modelProvider = modelProvider; + this.invocationHelper = invocationHelper; operationId = getIdShort(modelProvider.getValue("")); } @@ -52,15 +78,19 @@ public Object getValue(String path) throws ProviderException { String[] splitted = VABPathTools.splitPath(path); if (path.isEmpty()) { return modelProvider.getValue(""); - } else if (splitted[0].equals(INVOCATION_LIST) && splitted.length == 2) { + } else if (isInvocationListQuery(splitted)) { String requestId = splitted[1]; return AsyncOperationHandler.retrieveResult(requestId, operationId); - + } else { throw new MalformedRequestException("Get of an Operation supports only empty or /invocationList/{requestId} paths"); } } + private boolean isInvocationListQuery(String[] splitted) { + return splitted[0].equals(INVOCATION_LIST) && splitted.length == 2; + } + @Override public void setValue(String path, Object newValue) throws ProviderException { throw new MalformedRequestException("Set not allowed at path '" + path + "'"); @@ -82,103 +112,156 @@ public void deleteValue(String path, Object obj) throws ProviderException { throw new MalformedRequestException("Delete not allowed at path '" + path + "'"); } + @SuppressWarnings("unchecked") @Override public Object invokeOperation(String path, Object... parameters) throws ProviderException { - // Fix path - boolean async = path.endsWith(ASYNC); - // remove the "invoke" from the end of the path + boolean isAsync = isAsyncInvokePath(path); path = VABPathTools.stripInvokeFromPath(path); - // TODO: Only allow wrapped parameters with InvokationRequests - Object[] unwrappedParameters; - InvocationRequest request = getInvocationRequest(parameters); - String requestId; - if (request != null) { - unwrappedParameters = request.unwrapInputParameters(); - requestId = request.getRequestId(); - } else { - // => not necessary, if it is only allowed to use InvocationRequests - unwrappedParameters = unwrapDirectParameters(parameters); - // Generate random request id - requestId = UUID.randomUUID().toString(); - } - // Invoke /invokable instead of an Operation property if existent Object childElement = modelProvider.getValue(path); - if (Operation.isOperation(childElement)) { - path = VABPathTools.concatenatePaths(path, Operation.INVOKABLE); + if (!Operation.isOperation(childElement)) { + throw new MalformedRequestException("Only operations can be invoked."); } - - // Handle async operations - if (async) { - // Async call? No return value, yet - Collection outputVars = copyOutputVariables(); - IModelProvider provider = new VABElementProxy(path, modelProvider); - - // Only necessary as long as invocations without InvokationRequest is allowed - if (request != null) { - AsyncOperationHandler.invokeAsync(provider, operationId, request, outputVars); + Operation op = Operation.createAsFacade((Map) childElement); + + if (DelegatedInvocationManager.isDelegatingOperation(op)) { + return invocationHelper.invokeDelegatedOperation(op, parameters); + } else { + InvocationRequest request = getInvocationRequest(parameters, op); + + if (request != null && isAsync) { + return handleAsyncRequestInvokation(op, request); + } else if (request != null) { + return handleSyncRequestInvokation(op, request); + } else if (isAsync) {// => not necessary, if it is only allowed to use InvocationRequests + return handleAsyncParameterInvokation(op, parameters); } else { - AsyncOperationHandler.invokeAsync(provider, operationId, requestId, unwrappedParameters, outputVars, - 10000); + return handleSyncParameterInvokation(op, parameters); } - - // Request id has to be returned for caller to be able to retrieve result - // => Use callback response and leave url empty - return new CallbackResponse(requestId, ""); } + } - // Handle synchronous operations - // Forward direct operation call to modelprovider - Object directResult = modelProvider.invokeOperation(path, unwrappedParameters); - if (request == null) { - // Parameters have been passed directly? Directly return the result - return directResult; - } - return createInvocationResponseFromDirectResult(request, directResult); + private CallbackResponse handleAsyncRequestInvokation(Operation operation, InvocationRequest request) { + Collection outputVars = copyOutputVariables(operation); + + AsyncOperationHandler.invokeAsync(operation, operationId, request, outputVars); + + // Request id has to be returned for caller to be able to retrieve result + // => Use callback response and leave url empty + return new CallbackResponse(request.getRequestId(), ""); } - /** - * Directly creates an InvocationResponse from an operation result - */ - private Object createInvocationResponseFromDirectResult(InvocationRequest request, Object directResult) { - // Get SubmodelElement output template - Collection outputs = copyOutputVariables(); - if(outputs.size() > 0) - { - SubmodelElement outputElem = (SubmodelElement) outputs.iterator().next().getValue(); - // Set result object - outputElem.setValue(directResult); - }; - - // Create and return InvokationResponse + private InvocationResponse handleSyncRequestInvokation(Operation operation, InvocationRequest request) { + SubmodelElement[] inputVariables = getSumbodelElementsFromInvocationRequest(request); + SubmodelElement[] submodelElementsResult = operation.invoke(inputVariables); + + return createInvocationResponseFromSubmodelElementsResult(request, submodelElementsResult); + } + + private SubmodelElement[] getSumbodelElementsFromInvocationRequest(InvocationRequest request) { + Collection inputVariables = request.getInputArguments(); + + Stream inputVariablesStream = StreamSupport.stream(inputVariables.spliterator(), false); + Stream submodelElementStream = inputVariablesStream.map(inputVar -> (SubmodelElement) inputVar.getValue()); + + return submodelElementStream.toArray(SubmodelElement[]::new); + } + + private CallbackResponse handleAsyncParameterInvokation(Operation operation, Object[] parameters) { + Object[] unwrappedParameters = unwrapDirectParameters(parameters); + Collection outputVars = copyOutputVariables(operation); + + String requestId = UUID.randomUUID().toString(); + + AsyncOperationHandler.invokeAsync(operation, operationId, requestId, unwrappedParameters, outputVars, 10000); + // Request id has to be returned for caller to be able to retrieve result + // => Use callback response and leave url empty + return new CallbackResponse(requestId, ""); + } + + private Object handleSyncParameterInvokation(Operation operation, Object[] parameters) { + Object[] unwrappedParameters = unwrapDirectParameters(parameters); + + Object directResult = operation.invokeSimple(unwrappedParameters); + + return directResult; + } + + private boolean isAsyncInvokePath(String path) { + return path.endsWith(ASYNC); + } + + private InvocationResponse createInvocationResponseFromSubmodelElementsResult(InvocationRequest request, SubmodelElement[] submodelElementsResult) { + Collection outputs; + if (submodelElementsResult == null) { + outputs = new ArrayList<>(); + } else { + Stream submodelElementsStream = Arrays.stream(submodelElementsResult); + Stream operationVariableStream = submodelElementsStream.map(submodelElement -> new OperationVariable(submodelElement)); + + outputs = operationVariableStream.collect(Collectors.toList()); + } return new InvocationResponse(request.getRequestId(), new ArrayList<>(), outputs, ExecutionState.COMPLETED); } /** - * Extracts an invokation request from a generic parameter array + * Extracts an invocation request from a generic parameter array Matches + * parameters to order of Operation inputs by id Throws + * MalformedArgumentException if a required parameter is missing * * @param parameters - * @return + * the input parameters + * @param op + * the Operation providing the inputVariables to be matched to the + * actual input + * @return the build InvocationRequest */ @SuppressWarnings("unchecked") - private InvocationRequest getInvocationRequest(Object[] parameters) { - if (parameters.length == 1 && parameters[0] instanceof Map) { - Map requestMap = (Map) parameters[0]; - return InvocationRequest.createAsFacade(requestMap); + private InvocationRequest getInvocationRequest(Object[] parameters, Operation op) { + if (!isInvokationRequest(parameters)) { + return null; } - return null; + + Map requestMap = (Map) parameters[0]; + InvocationRequest request = InvocationRequest.createAsFacade(requestMap); + + // Sort parameters in request by InputVariables of operation + Collection vars = op.getInputVariables(); + Collection ordered = createOrderedInputVariablesList(request, vars); + + return new InvocationRequest(request.getRequestId(), request.getInOutArguments(), ordered, request.getTimeout()); } - - /** - * Gets the (first) output parameter from the underlying object - * - * @return - */ - @SuppressWarnings("unchecked") - private Collection copyOutputVariables() { - Map operationMap = (Map) getValue(""); - Operation op = Operation.createAsFacade(operationMap); + + private Collection createOrderedInputVariablesList(InvocationRequest request, Collection vars) { + Collection ordered = new ArrayList<>(); + + for (IOperationVariable var : vars) { + String id = var.getValue().getIdShort(); + ordered.add(findOperationVariableById(id, request.getInputArguments())); + } + + return ordered; + } + + private IOperationVariable findOperationVariableById(String id, Collection vars) { + for (IOperationVariable input : vars) { + if (input.getValue().getIdShort().equals(id)) { + return input; + } + } + + throw new MalformedRequestException("Expected parameter " + id + " missing in request"); + } + + private boolean isInvokationRequest(Object[] parameters) { + if (parameters.length != 1) { + return false; + } + return InvocationRequest.isInvocationRequest(parameters[0]); + } + + private Collection copyOutputVariables(Operation op) { Collection outputs = op.getOutputVariables(); Collection outCopy = new ArrayList<>(); outputs.stream().forEach(o -> outCopy.add(new OperationVariable(o.getValue().getLocalCopy()))); @@ -187,7 +270,7 @@ private Collection copyOutputVariables() { @SuppressWarnings("unchecked") private String getIdShort(Object operation) { - if(Operation.isOperation(operation)) { + if (Operation.isOperation(operation)) { return Operation.createAsFacade((Map) operation).getIdShort(); } else { // Should never happen as SubmodelElementProvider.getElementProvider diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java index 846fe85c..995b73d4 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/PropertyProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi; diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelAPIHelper.java b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelAPIHelper.java new file mode 100644 index 00000000..65f2b7ae --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelAPIHelper.java @@ -0,0 +1,109 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.submodel.restapi; + +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; + +/** + * Helper class for Submodel API + * + * @author haque + */ +public class SubmodelAPIHelper { + + /** + * Retrieves base access path for Submodel API + * + * @return + */ + public static String getSubmodelPath() { + return ""; + } + + /** + * Retrieves base access path for submodel element + * + * @return + */ + public static String getSubmodelElementsPath() { + return Submodel.SUBMODELELEMENT; + } + + /** + * Retrieves access path for given element + * + * @param idShortPath + * @return + */ + public static String getSubmodelElementPath(String idShortPath) { + return VABPathTools.concatenatePaths(MultiSubmodelElementProvider.ELEMENTS, idShortPath); + } + + /** + * Retrieves access path for async invocation of element's operation + * + * @param idShortPath + * @return + */ + public static String getSubmodelElementAsyncInvokePath(String idShortPath) { + return VABPathTools.concatenatePaths(getSubmodelElementPath(idShortPath), Operation.INVOKE + OperationProvider.ASYNC); + } + + /** + * Retrieves access path for synchroenous invocation of element's operation + * + * @param idShortPath + * @return + */ + public static String getSubmodelElementSyncInvokePath(String idShortPath) { + return VABPathTools.concatenatePaths(getSubmodelElementPath(idShortPath), Operation.INVOKE); + } + + /** + * Retrieves access path for element value + * + * @param idShortPath + * @return + */ + public static String getSubmodelElementValuePath(String idShortPath) { + return VABPathTools.concatenatePaths(getSubmodelElementPath(idShortPath), Property.VALUE); + } + + /** + * Retrieves access path for Element operation's result by request id + * + * @param idShortPath + * @param requestId + * @return + */ + public static String getSubmodelElementResultValuePath(String idShortPath, String requestId) { + return VABPathTools.concatenatePaths(getSubmodelElementPath(idShortPath), OperationProvider.INVOCATION_LIST, requestId); + } +} diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java index 19f66b71..6af252ce 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementCollectionProvider.java @@ -1,14 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi; +import java.util.Collection; import java.util.Map; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; @@ -38,35 +54,30 @@ public SubmodelElementCollectionProvider(IModelProvider proxy) { */ protected IModelProvider getElementProvider(String idShort) { - // The "value" before the id is needed by the providers lower down in order to handle collections correctly - // The paths then look like e.g. "submodelElements/collectionID/value/propertyID" - IModelProvider defaultProvider = new VABElementProxy( - VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, idShort), proxy); + // The "value" before the id is needed by the providers lower down in order to + // handle collections correctly + // The paths then look like e.g. + // "submodelElements/collectionID/value/propertyID" + IModelProvider defaultProvider = new VABElementProxy(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, idShort), proxy); - // Wrap the property with idShort into a SubmodelElementProvider and return that provider + // Wrap the property with idShort into a SubmodelElementProvider and return that + // provider return new SubmodelElementProvider(defaultProvider); } - @SuppressWarnings("unchecked") @Override public Object getValue(String path) throws ProviderException { path = VABPathTools.stripSlashes(path); String[] pathElements = VABPathTools.splitPath(path); if (path.isEmpty()) { - // Convert the internally used Map to a Collection before returning the smECollection - Map map = (Map) proxy.getValue(path); - SubmodelElementCollection smElemColl = SubmodelElementCollection.createAsFacade(map); - return SubmodelElementMapCollectionConverter.smElementToMap(smElemColl); - } else if(path.equals(MultiSubmodelElementProvider.VALUE)) { - // Return only a Collection of Elements. Not the internally used Map. - return SubmodelElementMapCollectionConverter.convertIDMapToCollection(proxy.getValue(path)); + return getSubmodelElementCollection(); + } else if (isValueAccess(path)) { + return getElements(); + } else if (isValuesAccess(path)) { + return getElementsValues(); } else { - // Directly access an element inside of the collection - String idShort = pathElements[0]; - String subPath = VABPathTools.buildPath(pathElements, 1); - - return getElementProvider(idShort).getValue(subPath); + return getElementByIdShort(pathElements); } } @@ -78,10 +89,9 @@ public void setValue(String path, Object newValue) throws ProviderException { if (path.isEmpty()) { // Convert the Collection of Elements to the internally used Map - Map value = - SubmodelElementMapCollectionConverter.mapToSmECollection((Map) newValue); + Map value = SubmodelElementMapCollectionConverter.mapToSmECollection((Map) newValue); proxy.setValue(path, value); - } else if(path.equals(MultiSubmodelElementProvider.VALUE)) { + } else if (isValueAccess(path)) { // Convert the Collection of Elements to the internally used Map Map value = SubmodelElementMapCollectionConverter.convertCollectionToIDMap(newValue); proxy.setValue(path, value); @@ -118,16 +128,17 @@ public void createValue(String path, Object newEntity) throws ProviderException public void deleteValue(String path) throws ProviderException { path = VABPathTools.stripSlashes(path); String[] pathElements = VABPathTools.splitPath(path); - + // "value" is a keyword and can not be used as the ID of an Element - if (path.isEmpty() || path.equals(MultiSubmodelElementProvider.VALUE)) { + if (path.isEmpty() || isValueAccess(path)) { throw new MalformedRequestException("Path must not be empty or /value"); } else { // If Path contains only one Element, use the proxy directly - if(pathElements.length == 1) { + if (pathElements.length == 1) { proxy.deleteValue(VABPathTools.concatenatePaths(MultiSubmodelElementProvider.VALUE, path)); } else { - // If Path contains more Elements, get the Provider for the first Element in Path + // If Path contains more Elements, get the Provider for the first Element in + // Path String idShort = pathElements[0]; String subPath = VABPathTools.buildPath(pathElements, 1); getElementProvider(idShort).deleteValue(subPath); @@ -145,7 +156,7 @@ public Object invokeOperation(String path, Object... parameter) throws ProviderE path = VABPathTools.stripSlashes(path); String[] pathElements = VABPathTools.splitPath(path); - if (path.isEmpty() || path.equals(MultiSubmodelElementProvider.VALUE)) { + if (path.isEmpty() || isValueAccess(path)) { throw new MalformedRequestException("Path must not be empty or /value"); } else { // Directly access an element inside of the collection @@ -154,4 +165,61 @@ public Object invokeOperation(String path, Object... parameter) throws ProviderE return getElementProvider(idShort).invokeOperation(subPath, parameter); } } + + private boolean isValueAccess(String path) { + return path.equals(MultiSubmodelElementProvider.VALUE); + } + + private boolean isValuesAccess(String path) { + return path.equals(SubmodelProvider.VALUES); + } + + /** + * Gets single element by idShort + * + * @param pathElements + * containing idShort as the first item + * @return + */ + private Object getElementByIdShort(String[] pathElements) { + String idShort = pathElements[0]; + String subPath = VABPathTools.buildPath(pathElements, 1); + + return getElementProvider(idShort).getValue(subPath); + } + + /** + * Gets elements values from the proxy Converts the internally used Map to a + * Collection before returning the smECollection + * + * @return + */ + @SuppressWarnings("unchecked") + private Map getElementsValues() { + Map map = (Map) proxy.getValue(""); + SubmodelElementCollection smElemColl = SubmodelElementCollection.createAsFacade(map); + return smElemColl.getValues(); + } + + /** + * Gets element collection from the proxy + * + * @return Only a Collection of Elements. Not the internally used Map. + */ + private Collection> getElements() { + return SubmodelElementMapCollectionConverter.convertIDMapToCollection(proxy.getValue(MultiSubmodelElementProvider.VALUE)); + } + + /** + * Gets Submodel Element Collection from the proxy Converts the internally used + * Map to a Collection before returning the smECollection + * + * @return map of the SMElementCollection + */ + @SuppressWarnings("unchecked") + private Map getSubmodelElementCollection() { + Map map = (Map) proxy.getValue(""); + SubmodelElementCollection smElemColl = SubmodelElementCollection.createAsFacade(map); + return SubmodelElementMapCollectionConverter.smElementToMap(smElemColl); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java index d441a41a..a5acc514 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelElementProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi; @@ -30,7 +45,7 @@ public class SubmodelElementProvider implements IModelProvider { private IModelProvider proxy; - + // Flag used to indicate whether a specialized ElementProvider is used private boolean specializedProvider = false; @@ -42,19 +57,22 @@ public SubmodelElementProvider(IModelProvider proxy) { } /** - * Used to find out if an Element needs a specialized Provider (Collection, Operation) + * Used to find out if an Element needs a specialized Provider (Collection, + * Operation) * - * @param proxy the Provider given from above - * @return either the unchanged Provider or the Provider nested into a specialized ElementProvider + * @param proxy + * the Provider given from above + * @return either the unchanged Provider or the Provider nested into a + * specialized ElementProvider */ @SuppressWarnings("unchecked") public static IModelProvider getElementProvider(IModelProvider proxy) { Map elementMap = (Map) proxy.getValue(""); - if(Operation.isOperation(elementMap)) { + if (Operation.isOperation(elementMap)) { return new OperationProvider(proxy); } else if (SubmodelElementCollection.isSubmodelElementCollection(elementMap)) { return new SubmodelElementCollectionProvider(proxy); - } else if(Property.isProperty(elementMap)) { + } else if (Property.isProperty(elementMap)) { return new PropertyProvider(proxy); } else { return proxy; @@ -69,15 +87,15 @@ public Object getValue(String path) throws ProviderException { if (path.equals(MultiSubmodelElementProvider.VALUE)) { // Handle "/value" path // return value - - if(specializedProvider) { + + if (specializedProvider) { return proxy.getValue(path); } - + Map elementMap = (Map) proxy.getValue(""); - + ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap); - + try { return element.getValue(); } catch (UnsupportedOperationException e) { @@ -94,25 +112,26 @@ public Object getValue(String path) throws ProviderException { @Override public void setValue(String path, Object newValue) throws ProviderException { path = VABPathTools.stripSlashes(path); - - if(!path.endsWith(MultiSubmodelElementProvider.VALUE)) { + + if (!path.endsWith(MultiSubmodelElementProvider.VALUE)) { throw new MalformedRequestException("The given path '" + path + "' does not end in /value."); } - + if (!specializedProvider && path.equals(MultiSubmodelElementProvider.VALUE)) { - // Path is only "value" and no specialized Provider has to be used -> update the Element of this Provider + // Path is only "value" and no specialized Provider has to be used -> update the + // Element of this Provider Map elementMap = (Map) proxy.getValue(""); - + ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap); - + try { - element.setValue(newValue); + element.setValue(newValue); } catch (IllegalArgumentException e) { throw new MalformedRequestException("The given Value was not valid for Element '" + path + "'"); } - + proxy.setValue("", element); - + } else { // Path has more Elements -> pass it to Provider below proxy.setValue(path, newValue); @@ -121,7 +140,7 @@ public void setValue(String path, Object newValue) throws ProviderException { @Override public void createValue(String path, Object newEntity) throws ProviderException { - if(!specializedProvider) { + if (!specializedProvider) { // In a regular SubmodelElement nothing can be created throw new MalformedRequestException("Creating a new Element is not allowed at '" + path + "'"); } else { @@ -132,7 +151,7 @@ public void createValue(String path, Object newEntity) throws ProviderException @Override public void deleteValue(String path) throws ProviderException { - if(!specializedProvider) { + if (!specializedProvider) { // From a regular SubmodelElement nothing can be deleted throw new MalformedRequestException("Deleting the Element '" + path + "' is not allowed"); } else { @@ -148,7 +167,7 @@ public void deleteValue(String path, Object obj) throws ProviderException { @Override public Object invokeOperation(String path, Object... parameter) throws ProviderException { - return proxy.invokeOperation(path, parameter); + return proxy.invokeOperation(path, parameter); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java index 1097c1fb..0a9855fe 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/SubmodelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi; @@ -16,9 +31,10 @@ import java.util.regex.Pattern; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; +import org.eclipse.basyx.submodel.metamodel.facade.submodelelement.SubmodelElementFacadeFactory; import org.eclipse.basyx.submodel.metamodel.map.Submodel; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; @@ -30,8 +46,8 @@ import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider; /** - * Additional VAB provider specific for providing submodels together - * with other SDKs by implementing the submodel API. + * Additional VAB provider specific for providing submodels together with other + * SDKs by implementing the submodel API. * * The VAB provides generic models without considering high-level information. * For example, Operation submodel elements are realized as a Map. The function @@ -49,7 +65,7 @@ public class SubmodelProvider implements IModelProvider { public static final String VALUES = "values"; public static final String SUBMODEL = "submodel"; - + ISubmodelAPI submodelAPI; /** @@ -128,22 +144,22 @@ public Object getValue(String path) throws ProviderException { // Remove initial "/submodelElements" path = removeSMElementPrefix(path); - if (endsWithValue(splitted)) { // Request for the value of an property - String idShortPath = removeValueSuffix(path); - return submodelAPI.getSubmodelElementValue(idShortPath); - } else if (isInvocationListPath(splitted)) { - List idShorts = getIdShorts(splitted); - - // Remove invocationList/{requestId} from the idShorts - idShorts.remove(idShorts.size() - 1); - idShorts.remove(idShorts.size() - 1); - return submodelAPI.getOperationResult(idShorts.get(0), splitted[splitted.length - 1]); - } else { - return submodelAPI.getSubmodelElement(path); - } - } - } - throw new MalformedRequestException("Unknown path " + path + " was requested"); + if (endsWithValue(splitted)) { // Request for the value of an property + String idShortPath = removeValueSuffix(path); + return submodelAPI.getSubmodelElementValue(idShortPath); + } else if (isInvocationListPath(splitted)) { + List idShorts = getIdShorts(splitted); + + // Remove invocationList/{requestId} from the idShorts + idShorts.remove(idShorts.size() - 1); + idShorts.remove(idShorts.size() - 1); + return submodelAPI.getOperationResult(idShorts.get(0), splitted[splitted.length - 1]); + } else { + return submodelAPI.getSubmodelElement(path); + } + } + } + throw new MalformedRequestException("Unknown path " + path + " was requested"); } private List getIdShorts(String[] splitted) { @@ -160,25 +176,26 @@ private List getIdShorts(String[] splitted) { return idShorts; } - private boolean endsWithValue(String[] splitted) { return splitted[splitted.length - 1].equals(Property.VALUE); } /** - * Removes a trailing /value from the path if it exists. - * - * @param path The original path, which might or might not end on {@value Property.VALUE}. - * @return The new path - */ - private String removeValueSuffix(String path) { - String suffix = "/" + Property.VALUE; - if (path.endsWith(suffix)) { - path = path.substring(0, path.length() - suffix.length()); - } - - return path; - } + * Removes a trailing /value from the path if it exists. + * + * @param path + * The original path, which might or might not end on + * {@value Property.VALUE}. + * @return The new path + */ + private String removeValueSuffix(String path) { + String suffix = "/" + Property.VALUE; + if (path.endsWith(suffix)) { + path = path.substring(0, path.length() - suffix.length()); + } + + return path; + } private boolean isInvocationListPath(String[] splitted) { return splitted.length > 2 && splitted[splitted.length - 2].equals(OperationProvider.INVOCATION_LIST); @@ -197,14 +214,13 @@ public void setValue(String path, Object newValue) throws ProviderException { if (endsWithValue(splitted)) { submodelAPI.updateSubmodelElement(idshortPath, newValue); } else { - - SubmodelElement element = SubmodelElement.createAsFacade((Map) newValue); - - if(!path.endsWith(element.getIdShort())) { - throw new MalformedRequestException("The idShort of given Element '" - + element.getIdShort() + "' does not match the ending of the given path '" + path + "'"); + + ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement((Map) newValue); + + if (!path.endsWith(element.getIdShort())) { + throw new MalformedRequestException("The idShort of given Element '" + element.getIdShort() + "' does not match the ending of the given path '" + path + "'"); } - + submodelAPI.addSubmodelElement(idshortPath, element); } } @@ -246,30 +262,50 @@ public void deleteValue(String path, Object obj) throws ProviderException { @Override public Object invokeOperation(String path, Object... parameters) throws ProviderException { - path = removeSubmodelPrefix(path); - if (path.isEmpty()) { + String pathWithoutSubmodelPrefix = removeSubmodelPrefix(path); + if (pathWithoutSubmodelPrefix.isEmpty()) { throw new MalformedRequestException("Given path must not be empty"); + } + + if (!VABPathTools.isOperationInvokationPath(pathWithoutSubmodelPrefix)) { + throw new MalformedRequestException("Given path '" + path + "' does not end in /" + Operation.INVOKE); + } + + String pathWithoutSMElementPrefix = removeSMElementPrefix(pathWithoutSubmodelPrefix); + + if (isAsyncInvokePath(pathWithoutSMElementPrefix)) { + return invokeAsync(pathWithoutSMElementPrefix, parameters); } else { - if (VABPathTools.isOperationInvokationPath(path)) { - if(path.endsWith(OperationProvider.ASYNC)) { - path = removeSMElementPrefix(path); - path = path.replaceFirst(Pattern.quote(Operation.INVOKE + OperationProvider.ASYNC), ""); - return submodelAPI.invokeAsync(path, parameters); - } else { - path = removeSMElementPrefix(path); - return submodelAPI.invokeOperation(path, parameters); - } - } else { - throw new MalformedRequestException("Given path '" + path + "' does not end in /" + Operation.INVOKE); - } + return invokeSync(pathWithoutSMElementPrefix, parameters); } + + } + + private Object invokeSync(String path, Object... parameters) { + String pathWithoutInvoke = path.replaceFirst(Pattern.quote(Operation.INVOKE), ""); + String strippedPathWithoutInvoke = VABPathTools.stripSlashes(pathWithoutInvoke); + return submodelAPI.invokeOperation(strippedPathWithoutInvoke, parameters); + } + + private Object invokeAsync(String path, Object... parameters) { + String pathWithoutAsyncInvoke = path.replaceFirst(Pattern.quote(Operation.INVOKE + OperationProvider.ASYNC), ""); + String strippedPathWithoutAsyncInvoke = VABPathTools.stripSlashes(pathWithoutAsyncInvoke); + return submodelAPI.invokeAsync(strippedPathWithoutAsyncInvoke, parameters); + } + + private boolean isAsyncInvokePath(String path) { + return path.endsWith(OperationProvider.ASYNC); + } + + public ISubmodelAPI getAPI() { + return this.submodelAPI; } protected void setAPI(ISubmodelAPI api) { this.submodelAPI = api; } - + private String removeSMElementPrefix(String path) { - return path.replaceFirst(MultiSubmodelElementProvider.ELEMENTS, ""); + return path.replaceFirst(MultiSubmodelElementProvider.ELEMENTS, ""); } } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java b/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java index 0ba527be..053ec69c 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPI.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.api; @@ -43,7 +58,7 @@ public interface ISubmodelAPI { * * @param idShortPath * the idShort path to the submodelElement - * @param elem + * @param elem * the submodelElement to be added */ public void addSubmodelElement(String idShortPath, ISubmodelElement elem); @@ -65,7 +80,6 @@ public interface ISubmodelAPI { */ public void deleteSubmodelElement(String idShortPath); - /** * Helper function for quick access of operations * @@ -99,7 +113,6 @@ public interface ISubmodelAPI { */ public Object getSubmodelElementValue(String idShortPath); - /** * Invokes an operation * @@ -111,22 +124,21 @@ public interface ISubmodelAPI { */ public Object invokeOperation(String idShortPath, Object... params); - /** * Invoke an operation asynchronously * * @param idShortPath - * the idShort path to the operation + * the idShort path to the operation * @param params - * to be passed to the operation + * to be passed to the operation * @return the requestId of the invocation */ public Object invokeAsync(String idShortPath, Object... params); - + /** * Gets the result of an asynchronously invoked operation * - * @param idShort + * @param idShort * of the operation * @param requestId * the requestId of the invocation diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java b/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java index a5ef08cb..705d9409 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/api/ISubmodelAPIFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.api; @@ -21,7 +36,14 @@ public interface ISubmodelAPIFactory { /** * Return a constructed Submodel API * + * @deprecated This method is deprecated please use {@link #create(Submodel)} + * * @return */ + @Deprecated public ISubmodelAPI getSubmodelAPI(Submodel submodel); + + public default ISubmodelAPI create(Submodel submodel) { + return getSubmodelAPI(submodel); + } } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/observing/ISubmodelAPIObserver.java b/src/main/java/org/eclipse/basyx/submodel/restapi/observing/ISubmodelAPIObserver.java new file mode 100644 index 00000000..ced8d605 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/observing/ISubmodelAPIObserver.java @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.submodel.restapi.observing; + +import org.eclipse.basyx.submodel.observer.IObserver; + +/** + * Interface for an observer of {@link ObservableSubmodelAPI} + * + * @author conradi + * + */ +public interface ISubmodelAPIObserver extends IObserver { + + /** + * Is called when a SubmodelElement is added + * + * @param idShortPath + * the idShortPath of the added element + * @param newValue + * the value of the new element + */ + public void elementAdded(String idShortPath, Object newValue); + + /** + * Is called when a SubmodelElement is deleted + * + * @param idShortPath + * the idShortPath of the deleted element + */ + public void elementDeleted(String idShortPath); + + /** + * Is called when a SubmodelElement is updated + * + * @param idShortPath + * the idShortPath of the updated element + * @param newValue + * the new value of the updated element + */ + public void elementUpdated(String idShortPath, Object newValue); + +} diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/observing/ObservableSubmodelAPI.java b/src/main/java/org/eclipse/basyx/submodel/restapi/observing/ObservableSubmodelAPI.java new file mode 100644 index 00000000..4774de23 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/observing/ObservableSubmodelAPI.java @@ -0,0 +1,114 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.submodel.restapi.observing; + +import java.util.Collection; + +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.observer.Observable; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; + +/** + * Implementation of {@link ISubmodelAPI} that calls back registered + * {@link ISubmodelAPIObserver} when changes on SubmodelElements occur + * + * @author conradi + * + */ +public class ObservableSubmodelAPI extends Observable implements ISubmodelAPI { + + ISubmodelAPI submodelAPI; + + public ObservableSubmodelAPI(ISubmodelAPI observerdAPI) { + submodelAPI = observerdAPI; + } + + @Override + public ISubmodel getSubmodel() { + return submodelAPI.getSubmodel(); + } + + @Override + public void addSubmodelElement(ISubmodelElement elem) { + submodelAPI.addSubmodelElement(elem); + observers.stream().forEach(o -> o.elementAdded(elem.getIdShort(), elem.getValue())); + } + + @Override + public void addSubmodelElement(String idShortPath, ISubmodelElement elem) { + submodelAPI.addSubmodelElement(idShortPath, elem); + observers.stream().forEach(o -> o.elementAdded(idShortPath, elem.getValue())); + } + + @Override + public ISubmodelElement getSubmodelElement(String idShortPath) { + return submodelAPI.getSubmodelElement(idShortPath); + } + + @Override + public void deleteSubmodelElement(String idShortPath) { + submodelAPI.deleteSubmodelElement(idShortPath); + observers.stream().forEach(o -> o.elementDeleted(idShortPath)); + } + + @Override + public Collection getOperations() { + return submodelAPI.getOperations(); + } + + @Override + public Collection getSubmodelElements() { + return submodelAPI.getSubmodelElements(); + } + + @Override + public void updateSubmodelElement(String idShortPath, Object newValue) { + submodelAPI.updateSubmodelElement(idShortPath, newValue); + observers.stream().forEach(o -> o.elementUpdated(idShortPath, newValue)); + } + + @Override + public Object getSubmodelElementValue(String idShortPath) { + return submodelAPI.getSubmodelElementValue(idShortPath); + } + + @Override + public Object invokeOperation(String idShortPath, Object... params) { + return submodelAPI.invokeOperation(idShortPath, params); + } + + @Override + public Object invokeAsync(String idShortPath, Object... params) { + return submodelAPI.invokeAsync(idShortPath, params); + } + + @Override + public Object getOperationResult(String idShort, String requestId) { + return submodelAPI.getOperationResult(idShort, requestId); + } + +} diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java index bdf6b413..9c7b7afb 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/AsyncOperationHandler.java @@ -1,28 +1,42 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.operation; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import org.apache.poi.ss.formula.functions.T; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationExecutionTimeoutException; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; -import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; /** * Helperclass used to keep and invoke operations asynchronously. @@ -31,46 +45,40 @@ * */ public class AsyncOperationHandler { - private static Map responses = new HashMap<>(); - private static Map responseOperationMap = new HashMap<>(); + private static Map responses = new LinkedHashMap<>(); + private static Map responseOperationMap = new LinkedHashMap<>(); private static ScheduledThreadPoolExecutor delayer = new ScheduledThreadPoolExecutor(0); /** * Invokes an Operation with an invocation request */ - public static void invokeAsync(IModelProvider provider, String operationId, InvocationRequest request, - Collection outputArguments) { + public static void invokeAsync(Operation operation, String operationId, InvocationRequest request, Collection outputArguments) { String requestId = request.getRequestId(); Collection inOutArguments = request.getInOutArguments(); Object[] parameters = request.unwrapInputParameters(); - invokeAsync(provider, operationId, requestId, parameters, inOutArguments, outputArguments, - request.getTimeout()); + invokeAsync(operation, operationId, requestId, parameters, inOutArguments, outputArguments, request.getTimeout()); } /** * Invokes an Operation without an invocation request */ - public static void invokeAsync(IModelProvider provider, String operationId, String requestId, Object[] inputs, - Collection outputArguments, int timeout) { - invokeAsync(provider, operationId, requestId, inputs, new ArrayList<>(), outputArguments, timeout); + public static void invokeAsync(Operation operation, String operationId, String requestId, Object[] inputs, Collection outputArguments, int timeout) { + invokeAsync(operation, operationId, requestId, inputs, new ArrayList<>(), outputArguments, timeout); } /** * Invokes an Operation and returns its requestId */ - private static void invokeAsync(IModelProvider provider, String operationId, String requestId, Object[] inputs, - Collection inOutArguments, - Collection outputArguments, int timeout) { + private static void invokeAsync(Operation operation, String operationId, String requestId, Object[] inputs, Collection inOutArguments, Collection outputArguments, int timeout) { synchronized (responses) { - InvocationResponse response = new InvocationResponse(requestId, inOutArguments, outputArguments, - ExecutionState.INITIATED); + InvocationResponse response = new InvocationResponse(requestId, inOutArguments, outputArguments, ExecutionState.INITIATED); responses.put(requestId, response); responseOperationMap.put(requestId, operationId); CompletableFuture.supplyAsync( // Run Operation asynchronously - () -> provider.invokeOperation("", inputs)) + () -> operation.invokeSimple(inputs)) // Accept either result or throw exception on timeout .acceptEither(setTimeout(timeout, requestId), result -> { // result accepted? => Write execution state if there is an output @@ -98,55 +106,51 @@ private static void invokeAsync(IModelProvider provider, String operationId, Str }); } } - + /** * Function for scheduling a timeout function with completable futures */ - private static CompletableFuture setTimeout(int timeout, String requestId) { - CompletableFuture result = new CompletableFuture<>(); - delayer.schedule( - () -> result.completeExceptionally( - new OperationExecutionTimeoutException("Request " + requestId + " timed out")), - timeout, TimeUnit.MILLISECONDS); + private static CompletableFuture setTimeout(int timeout, String requestId) { + CompletableFuture result = new CompletableFuture<>(); + delayer.schedule(() -> result.completeExceptionally(new OperationExecutionTimeoutException("Request " + requestId + " timed out")), timeout, TimeUnit.MILLISECONDS); return result; } /** * Gets the result of an invocation * - * @param operationId the id of the requested Operation - * @param requestId the id of the request + * @param operationId + * the id of the requested Operation + * @param requestId + * the id of the request * @return the result of the Operation or a Message that it is not yet finished */ public static Object retrieveResult(String requestId, String operationId) { // Remove the Invocation if it is finished and its result was retrieved synchronized (responses) { if (!responses.containsKey(requestId)) { - throw new ResourceNotFoundException( - "RequestId '" + requestId + "' not found for operation '" + operationId + "'."); + throw new ResourceNotFoundException("RequestId '" + requestId + "' not found for operation '" + operationId + "'."); } - + String validOperationId = responseOperationMap.get(requestId); if (!operationId.equals(validOperationId)) { - throw new ResourceNotFoundException( - "RequestId '" + requestId + "' does not belong to Operation '" + operationId + "'"); + throw new ResourceNotFoundException("RequestId '" + requestId + "' does not belong to Operation '" + operationId + "'"); } InvocationResponse response = responses.get(requestId); - if (ExecutionState.COMPLETED == response.getExecutionState() - || ExecutionState.TIMEOUT == response.getExecutionState() - || ExecutionState.FAILED == response.getExecutionState()) { + if (ExecutionState.COMPLETED == response.getExecutionState() || ExecutionState.TIMEOUT == response.getExecutionState() || ExecutionState.FAILED == response.getExecutionState()) { responses.remove(requestId); responseOperationMap.remove(requestId); } return response; } } - + /** * Checks if a given requestId exists * - * @param requestId the id to be checked + * @param requestId + * the id to be checked * @return if the id exists */ public static boolean hasRequestId(String requestId) { diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java index fb101254..bd7d40de 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/CallbackResponse.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.operation; @@ -22,10 +37,10 @@ public class CallbackResponse extends VABModelMap { public static final String REQUESTID = "requestId"; public static final String CALLBACKURL = "callbackUrl"; - + public CallbackResponse() { } - + public static CallbackResponse createAsFacade(Map map) { if (map == null) { return null; diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/DelegatedInvocationManager.java b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/DelegatedInvocationManager.java new file mode 100644 index 00000000..d52b80d3 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/DelegatedInvocationManager.java @@ -0,0 +1,130 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.submodel.restapi.operation; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint; +import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; + +/** + * A helper class for operation invocation delegation + * + * @author haque + * + */ +public class DelegatedInvocationManager { + public static final String DELEGATION_TYPE = "invocationDelegation"; + + private IConnectorFactory connectorFactory; + + /** + * Constructs the DelegatedInvocationHelper using the passed connectorFactory + * for call delegation + * + * @param connectorFactory + * IConnectorFactory to be used for delegation + */ + public DelegatedInvocationManager(IConnectorFactory connectorFactory) { + this.connectorFactory = connectorFactory; + } + + /** + * Checks whether the given operation is delegated invocation + * + * @param operation + * @return + */ + public static boolean isDelegatingOperation(Operation operation) { + return getDelegatedQualifier(operation) != null; + } + + /** + * Invokes delegated operation using delegated URL + * + * @param operation + * @param parameters + * @return + */ + public Object invokeDelegatedOperation(Operation operation, Object... parameters) { + String delegatedUrl = getDelegatedURL(operation); + return connectorFactory.create(delegatedUrl).invokeOperation("", parameters); + } + + /** + * Creates the Qualifier used to tag an Operation as delegating operation + * + * @param delegationURL + * the URL the Operation delegates to + * @return the delegation Qualifier + */ + public static Qualifier createDelegationQualifier(String delegationURL) { + return new Qualifier(DelegatedInvocationManager.DELEGATION_TYPE, delegationURL, "string", null); + } + + /** + * Retrieves the delegated URL of the operation invoke + * + * @param operation + * @return + * @throws RuntimeException + * if delegated qualifier does not exist + */ + private static String getDelegatedURL(Operation operation) throws RuntimeException { + Qualifier qualifier = getDelegatedQualifier(operation); + if (qualifier != null) { + return qualifier.getValue().toString(); + } else { + throw new RuntimeException("Qualifier with Delegated type does not exist"); + } + } + + /** + * Gets the delegated qualifier if exists. Otherwise null is returned + * + * @param operation + * @return + */ + @SuppressWarnings("unchecked") + private static Qualifier getDelegatedQualifier(Operation operation) { + Collection constraints = operation.getQualifiers(); + for (IConstraint constraint : constraints) { + Qualifier qualifier = Qualifier.createAsFacade((Map) constraint); + if (isDelegationQualifier(qualifier)) { + return qualifier; + } + } + return null; + } + + private static boolean isDelegationQualifier(Qualifier qualifier) { + return qualifier.getType() != null && qualifier.getType().equalsIgnoreCase(DELEGATION_TYPE); + } +} diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java index 4e085cb8..61bf7672 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/ExecutionState.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.operation; @@ -55,7 +70,7 @@ private ExecutionState(String standardizedLiteral) { public String getStandardizedLiteral() { return standardizedLiteral; } - + @Override public String toString() { return standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java index 4b0178e0..b760a39a 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationRequest.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.operation; @@ -45,7 +60,7 @@ public static InvocationRequest createAsFacade(Map map) { if (map == null) { return null; } - + InvocationRequest ret = new InvocationRequest(); ret.setRequestId((String) map.get(REQUESTID)); Collection inoutArguments = createInoutArguments(map); @@ -60,7 +75,31 @@ public static InvocationRequest createAsFacade(Map map) { } /** - * Unwraps the values of the inputVars in the order of occurance in the collection of input arguments + * Returns true if the given map is recognized as an InvocationRequest + */ + @SuppressWarnings("unchecked") + public static boolean isInvocationRequest(Object value) { + if (!(value instanceof Map)) { + return false; + } + + Map map = (Map) value; + + return isValid(map); + } + + /** + * Check whether all mandatory elements for the metamodel exist in a map + * + * @return true/false + */ + public static boolean isValid(Map map) { + return map.containsKey(REQUESTID) && map.containsKey(TIMEOUT); + } + + /** + * Unwraps the values of the inputVars in the order of occurance in the + * collection of input arguments * * @return */ diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java index 78e41703..6ed36205 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/operation/InvocationResponse.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.operation; @@ -34,8 +49,7 @@ public class InvocationResponse extends VABModelMap { private InvocationResponse() { } - public InvocationResponse(String requestId, Collection inoutArguments, - Collection outputArguments, ExecutionState executionState) { + public InvocationResponse(String requestId, Collection inoutArguments, Collection outputArguments, ExecutionState executionState) { put(REQUESTID, requestId); put(INOUTARGUMENTS, inoutArguments); put(OUTPUTARGUMENTS, outputArguments); @@ -78,8 +92,7 @@ private static Collection createInoutArguments(Map createOperationVariables( - Collection> variableMap) { + private static Collection createOperationVariables(Collection> variableMap) { if (variableMap != null) { return variableMap.stream().map(OperationVariable::createAsFacade).collect(Collectors.toList()); } else { diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java index 3934a04c..7ec2524f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPI.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.vab; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; @@ -19,10 +34,8 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider; -import org.eclipse.basyx.submodel.restapi.OperationProvider; +import org.eclipse.basyx.submodel.restapi.SubmodelAPIHelper; import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; @@ -58,7 +71,7 @@ public VABSubmodelAPI(IModelProvider modelProvider) { * submodelelements */ private MultiSubmodelElementProvider getElementProvider() { - IModelProvider elementProxy = new VABElementProxy(Submodel.SUBMODELELEMENT, modelProvider); + IModelProvider elementProxy = new VABElementProxy(SubmodelAPIHelper.getSubmodelElementsPath(), modelProvider); return new MultiSubmodelElementProvider(elementProxy); } @@ -66,30 +79,29 @@ private MultiSubmodelElementProvider getElementProvider() { @Override public ISubmodel getSubmodel() { // For access on the container property root, return the whole model - Map map = (Map) modelProvider.getValue(""); + Map map = (Map) modelProvider.getValue(SubmodelAPIHelper.getSubmodelPath()); // Only return a copy of the Submodel - Map smCopy = new HashMap<>(); + Map smCopy = new LinkedHashMap<>(); smCopy.putAll(map); return Submodel.createAsFacade(smCopy); } @Override public void addSubmodelElement(ISubmodelElement elem) { - getElementProvider().createValue(MultiSubmodelElementProvider.ELEMENTS + "/" + elem.getIdShort(), elem); + getElementProvider().createValue(SubmodelAPIHelper.getSubmodelElementPath(elem.getIdShort()), elem); } @Override public void addSubmodelElement(String idShortPath, ISubmodelElement elem) { - getElementProvider().createValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath, elem); + getElementProvider().createValue(SubmodelAPIHelper.getSubmodelElementPath(idShortPath), elem); } @Override public void deleteSubmodelElement(String idShortPath) { - getElementProvider().deleteValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath); + getElementProvider().deleteValue(SubmodelAPIHelper.getSubmodelElementPath(idShortPath)); } - @Override public Collection getOperations() { return getSubmodelElements().stream().filter(e -> e instanceof IOperation).map(e -> (IOperation) e).collect(Collectors.toList()); @@ -98,47 +110,39 @@ public Collection getOperations() { @SuppressWarnings("unchecked") @Override public Collection getSubmodelElements() { - Collection> elements = (Collection>) getElementProvider() - .getValue(MultiSubmodelElementProvider.ELEMENTS); + Collection> elements = (Collection>) getElementProvider().getValue(SubmodelAPIHelper.getSubmodelElementsPath()); return elements.stream().map(SubmodelElement::createAsFacade).collect(Collectors.toList()); } @Override public void updateSubmodelElement(String idShortPath, Object newValue) { - getElementProvider().setValue(buildValuePathForProperty(idShortPath), newValue); + getElementProvider().setValue(SubmodelAPIHelper.getSubmodelElementValuePath(idShortPath), newValue); } @Override public Object getSubmodelElementValue(String idShortPath) { - return getElementProvider().getValue(buildValuePathForProperty(idShortPath)); + return getElementProvider().getValue(SubmodelAPIHelper.getSubmodelElementValuePath(idShortPath)); } @SuppressWarnings("unchecked") @Override public ISubmodelElement getSubmodelElement(String idShortPath) { - return SubmodelElement.createAsFacade((Map) getElementProvider().getValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath)); + return SubmodelElement.createAsFacade((Map) getElementProvider().getValue(SubmodelAPIHelper.getSubmodelElementPath(idShortPath))); } @Override public Object invokeOperation(String idShortPath, Object... params) { - return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath, params); + return getElementProvider().invokeOperation(SubmodelAPIHelper.getSubmodelElementSyncInvokePath(idShortPath), params); } - - + @Override public Object invokeAsync(String idShortPath, Object... params) { - return getElementProvider().invokeOperation(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath +"/" + Operation.INVOKE + OperationProvider.ASYNC, params); + return getElementProvider().invokeOperation(SubmodelAPIHelper.getSubmodelElementAsyncInvokePath(idShortPath), params); } - private String buildValuePathForProperty(String idShortPath) { - return MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath + "/" + Property.VALUE; - } - - @Override public Object getOperationResult(String idShortPath, String requestId) { - return getElementProvider().getValue(MultiSubmodelElementProvider.ELEMENTS + "/" + idShortPath + "/" + OperationProvider.INVOCATION_LIST + "/" + requestId); + return getElementProvider().getValue(SubmodelAPIHelper.getSubmodelElementResultValuePath(idShortPath, requestId)); } - } diff --git a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java index a547c9c9..1ff0f200 100644 --- a/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java +++ b/src/main/java/org/eclipse/basyx/submodel/restapi/vab/VABSubmodelAPIFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.restapi.vab; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java index f03ad345..283b07b4 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/DigitalNameplateSubmodel.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate; @@ -34,7 +49,8 @@ import org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings.Markings; /** - * DigitalNameplateSubmodel as defined in the AAS Digital Nameplate Template document
+ * DigitalNameplateSubmodel as defined in the AAS Digital Nameplate Template + * document
* this contains the nameplate information attached to the product * * @author haque @@ -51,11 +67,13 @@ public class DigitalNameplateSubmodel extends Submodel { public static final String ASSETSPECIFICPROPERTIESID = "AssetSpecificProperties"; public static final Reference SEMANTICID = new Reference(Collections.singletonList(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate", KeyType.IRI))); public static final String SUBMODELID = "Nameplate"; - - private DigitalNameplateSubmodel() {} - + + private DigitalNameplateSubmodel() { + } + /** * Constructor with default idShort + * * @param identifier * @param manufacturerName * @param manufacturerProductDesignation @@ -63,19 +81,14 @@ private DigitalNameplateSubmodel() {} * @param manufacturerProductFamily * @param yearsOfConstruction */ - public DigitalNameplateSubmodel( - Identifier identifier, - MultiLanguageProperty manufacturerName, - MultiLanguageProperty manufacturerProductDesignation, - Address address, - MultiLanguageProperty manufacturerProductFamily, - Property yearsOfConstruction - ) { + public DigitalNameplateSubmodel(Identifier identifier, MultiLanguageProperty manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Address address, MultiLanguageProperty manufacturerProductFamily, + Property yearsOfConstruction) { this(SUBMODELID, identifier, manufacturerName, manufacturerProductDesignation, address, manufacturerProductFamily, yearsOfConstruction); } - + /** * Constructor with default idShort + * * @param identifier * @param manufacturerName * @param manufacturerProductDesignation @@ -83,19 +96,13 @@ public DigitalNameplateSubmodel( * @param manufacturerProductFamily * @param yearsOfConstruction */ - public DigitalNameplateSubmodel( - Identifier identifier, - LangString manufacturerName, - LangString manufacturerProductDesignation, - Address address, - LangString manufacturerProductFamily, - String yearsOfConstruction - ) { + public DigitalNameplateSubmodel(Identifier identifier, LangString manufacturerName, LangString manufacturerProductDesignation, Address address, LangString manufacturerProductFamily, String yearsOfConstruction) { this(SUBMODELID, identifier, manufacturerName, manufacturerProductDesignation, address, manufacturerProductFamily, yearsOfConstruction); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param identifier * @param manufacturerName @@ -104,15 +111,8 @@ public DigitalNameplateSubmodel( * @param manufacturerProductFamily * @param yearsOfConstruction */ - public DigitalNameplateSubmodel( - String idShort, - Identifier identifier, - MultiLanguageProperty manufacturerName, - MultiLanguageProperty manufacturerProductDesignation, - Address address, - MultiLanguageProperty manufacturerProductFamily, - Property yearsOfConstruction - ) { + public DigitalNameplateSubmodel(String idShort, Identifier identifier, MultiLanguageProperty manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Address address, MultiLanguageProperty manufacturerProductFamily, + Property yearsOfConstruction) { super(idShort, identifier); setSemanticId(SEMANTICID); setManufacturerName(manufacturerName); @@ -121,9 +121,10 @@ public DigitalNameplateSubmodel( setManufacturerProductFamily(manufacturerProductFamily); setYearOfConstruction(yearsOfConstruction); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param identifier * @param manufacturerName @@ -132,15 +133,7 @@ public DigitalNameplateSubmodel( * @param manufacturerProductFamily * @param yearsOfConstruction */ - public DigitalNameplateSubmodel( - String idShort, - Identifier identifier, - LangString manufacturerName, - LangString manufacturerProductDesignation, - Address address, - LangString manufacturerProductFamily, - String yearsOfConstruction - ) { + public DigitalNameplateSubmodel(String idShort, Identifier identifier, LangString manufacturerName, LangString manufacturerProductDesignation, Address address, LangString manufacturerProductFamily, String yearsOfConstruction) { super(idShort, identifier); setSemanticId(SEMANTICID); setManufacturerName(manufacturerName); @@ -149,46 +142,50 @@ public DigitalNameplateSubmodel( setManufacturerProductFamily(manufacturerProductFamily); setYearOfConstruction(yearsOfConstruction); } - + /** * Creates a DigitalNameplateSubmodel object from a map * - * @param obj a DigitalNameplateSubmodel SMC object as raw map - * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for the given map + * @param obj + * a DigitalNameplateSubmodel SMC object as raw map + * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for + * the given map */ public static DigitalNameplateSubmodel createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(DigitalNameplateSubmodel.class, obj); } - + DigitalNameplateSubmodel ret = new DigitalNameplateSubmodel(); ret.setMap(SubmodelElementMapCollectionConverter.mapToSM(obj)); return ret; } - + /** * Creates a DigitalNameplateSubmodel object from a map without validation * - * @param obj a DigitalNameplateSubmodel SMC object as raw map - * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for the given map + * @param obj + * a DigitalNameplateSubmodel SMC object as raw map + * @return a DigitalNameplateSubmodel SMC object, that behaves like a facade for + * the given map */ private static DigitalNameplateSubmodel createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + DigitalNameplateSubmodel ret = new DigitalNameplateSubmodel(); ret.setMap(SubmodelElementMapCollectionConverter.mapToSM(obj)); return ret; } - + /** - * Check whether all mandatory elements for DigitalNameplateSubmodel - * exist in the map + * Check whether all mandatory elements for DigitalNameplateSubmodel exist in + * the map * * @param obj * @@ -197,36 +194,32 @@ private static DigitalNameplateSubmodel createAsFacadeNonStrict(Map obj) { DigitalNameplateSubmodel submodel = createAsFacadeNonStrict(obj); - - return Submodel.isValid(obj) - && MultiLanguageProperty.isValid((Map) submodel.getManufacturerName()) - && MultiLanguageProperty.isValid((Map) submodel.getManufacturerProductDesignation()) - && Address.isValid(submodel.getAddress()) - && MultiLanguageProperty.isValid((Map) submodel.getManufacturerProductFamily()) - && Property.isValid((Map) submodel.getYearOfConstruction()); + + return Submodel.isValid(obj) && MultiLanguageProperty.isValid((Map) submodel.getManufacturerName()) && MultiLanguageProperty.isValid((Map) submodel.getManufacturerProductDesignation()) + && Address.isValid(submodel.getAddress()) && MultiLanguageProperty.isValid((Map) submodel.getManufacturerProductFamily()) && Property.isValid((Map) submodel.getYearOfConstruction()); } - + /** - * Sets manufacturerName - * legally valid designation of the natural or judicial person which is directly - * responsible for the design, production, packaging and labeling of a product - * in respect to its being brought into circulation - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. - * @param manufacturerName {@link MultiLanguageProperty} + * Sets manufacturerName legally valid designation of the natural or judicial + * person which is directly responsible for the design, production, packaging + * and labeling of a product in respect to its being brought into circulation + * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * + * @param manufacturerName + * {@link MultiLanguageProperty} */ public void setManufacturerName(MultiLanguageProperty manufacturerName) { addSubmodelElement(manufacturerName); } - + /** - * Sets manufacturerName - * legally valid designation of the natural or judicial person which is directly - * responsible for the design, production, packaging and labeling of a product - * in respect to its being brought into circulation - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. - * @param manufacturerName {@link LangString} + * Sets manufacturerName legally valid designation of the natural or judicial + * person which is directly responsible for the design, production, packaging + * and labeling of a product in respect to its being brought into circulation + * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * + * @param manufacturerName + * {@link LangString} */ public void setManufacturerName(LangString manufacturerName) { MultiLanguageProperty manufacturerNameProp = new MultiLanguageProperty(MANUFACTURERNAMEID); @@ -234,37 +227,38 @@ public void setManufacturerName(LangString manufacturerName) { manufacturerNameProp.setValue(new LangStrings(manufacturerName)); setManufacturerName(manufacturerNameProp); } - + /** * - * Gets manufacturerName - * legally valid designation of the natural or judicial person which is directly - * responsible for the design, production, packaging and labeling of a product - * in respect to its being brought into circulation - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. + * Gets manufacturerName legally valid designation of the natural or judicial + * person which is directly responsible for the design, production, packaging + * and labeling of a product in respect to its being brought into circulation + * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IMultiLanguageProperty getManufacturerName() { return MultiLanguageProperty.createAsFacade((Map) getSubmodelElement(MANUFACTURERNAMEID)); } - + /** - * Sets Short description of the product (short text) - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. - * @param manufacturerProductDesignation {@link MultiLanguageProperty} + * Sets Short description of the product (short text) Note: mandatory property + * according to EU Machine Directive 2006/42/EC. + * + * @param manufacturerProductDesignation + * {@link MultiLanguageProperty} */ public void setManufacturerProductDesignation(MultiLanguageProperty manufacturerProductDesignation) { addSubmodelElement(manufacturerProductDesignation); } - + /** - * Sets Short description of the product (short text) - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. - * @param manufacturerProductDesignation {@link LangString} + * Sets Short description of the product (short text) Note: mandatory property + * according to EU Machine Directive 2006/42/EC. + * + * @param manufacturerProductDesignation + * {@link LangString} */ public void setManufacturerProductDesignation(LangString manufacturerProductDesignation) { MultiLanguageProperty manufacturerProductDesignationProp = new MultiLanguageProperty(MANUFACTURERPRODUCTDESIGNATIONID); @@ -272,34 +266,34 @@ public void setManufacturerProductDesignation(LangString manufacturerProductDesi manufacturerProductDesignationProp.setValue(new LangStrings(manufacturerProductDesignation)); setManufacturerProductDesignation(manufacturerProductDesignationProp); } - + /** - * Gets Short description of the product (short text) - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. + * Gets Short description of the product (short text) Note: mandatory property + * according to EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IMultiLanguageProperty getManufacturerProductDesignation() { return MultiLanguageProperty.createAsFacade((Map) getSubmodelElement(MANUFACTURERPRODUCTDESIGNATIONID)); } - + /** * Sets address information of a business partner * - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. + * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * * @param address */ public void setAddress(Address address) { addSubmodelElement(address); } - + /** * Gets address information of a business partner * - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. + * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") @@ -307,22 +301,24 @@ public Address getAddress() { ISubmodelElement element = getSubmodelElement(ADDRESSID); return element == null ? null : Address.createAsFacade((Map) element); } - + /** - * Sets 2nd level of a 3 level manufacturer specific product hierarchy - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. - * @param manufacturerProductFamily {@link MultiLanguageProperty} + * Sets 2nd level of a 3 level manufacturer specific product hierarchy Note: + * mandatory property according to EU Machine Directive 2006/42/EC. + * + * @param manufacturerProductFamily + * {@link MultiLanguageProperty} */ public void setManufacturerProductFamily(MultiLanguageProperty manufacturerProductFamily) { addSubmodelElement(manufacturerProductFamily); } - + /** - * Sets 2nd level of a 3 level manufacturer specific product hierarchy - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. - * @param manufacturerProductFamily {@link LangString} + * Sets 2nd level of a 3 level manufacturer specific product hierarchy Note: + * mandatory property according to EU Machine Directive 2006/42/EC. + * + * @param manufacturerProductFamily + * {@link LangString} */ public void setManufacturerProductFamily(LangString manufacturerProductFamily) { MultiLanguageProperty manufacturerProductFamilyProp = new MultiLanguageProperty(MANUFACTURERPRODUCTFAMILYID); @@ -330,30 +326,32 @@ public void setManufacturerProductFamily(LangString manufacturerProductFamily) { manufacturerProductFamilyProp.setValue(new LangStrings(manufacturerProductFamily)); setManufacturerProductFamily(manufacturerProductFamilyProp); } - + /** - * Gets 2nd level of a 3 level manufacturer specific product hierarchy - * Note: mandatory property according to EU Machine Directive - * 2006/42/EC. + * Gets 2nd level of a 3 level manufacturer specific product hierarchy Note: + * mandatory property according to EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IMultiLanguageProperty getManufacturerProductFamily() { return MultiLanguageProperty.createAsFacade((Map) getSubmodelElement(MANUFACTURERPRODUCTFAMILYID)); } - + /** * Sets unique combination of numbers and letters used to identify the device * once it has been manufactured + * * @param serialNumber */ public void setSerialNumber(Property serialNumber) { addSubmodelElement(serialNumber); } - + /** * Sets unique combination of numbers and letters used to identify the device * once it has been manufactured + * * @param serialNumber */ public void setSerialNumber(String serialNumber) { @@ -362,29 +360,32 @@ public void setSerialNumber(String serialNumber) { serialNumberProp.setValue(serialNumber); setSerialNumber(serialNumberProp); } - + /** * Gets unique combination of numbers and letters used to identify the device * once it has been manufactured + * * @return */ @SuppressWarnings("unchecked") public IProperty getSerialNumber() { return Property.createAsFacade((Map) getSubmodelElement(SERIALNUMBERID)); } - + /** - * Sets year as completion date of object - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Sets year as completion date of object Note: mandatory property according to + * EU Machine Directive 2006/42/EC. + * * @param yearsOfConstruction */ public void setYearOfConstruction(Property yearsOfConstruction) { addSubmodelElement(yearsOfConstruction); } - + /** - * Sets year as completion date of object - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Sets year as completion date of object Note: mandatory property according to + * EU Machine Directive 2006/42/EC. + * * @param yearsOfConstruction */ public void setYearOfConstruction(String yearsOfConstruction) { @@ -393,31 +394,32 @@ public void setYearOfConstruction(String yearsOfConstruction) { yearsOfConstructionProp.setValue(yearsOfConstruction); setYearOfConstruction(yearsOfConstructionProp); } - + /** - * Gets year as completion date of object - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Gets year as completion date of object Note: mandatory property according to + * EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IProperty getYearOfConstruction() { return Property.createAsFacade((Map) getSubmodelElement(YEARSOFCONSTRUCTIONID)); } - + /** - * Sets collection of product markings - * Note: CE marking is declared as mandatory according to EU Machine - * Directive 2006/42/EC. + * Sets collection of product markings Note: CE marking is declared as mandatory + * according to EU Machine Directive 2006/42/EC. + * * @param markings */ public void setMarkings(Markings markings) { addSubmodelElement(markings); } - + /** - * Gets collection of product markings - * Note: CE marking is declared as mandatory according to EU Machine - * Directive 2006/42/EC. + * Gets collection of product markings Note: CE marking is declared as mandatory + * according to EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") @@ -425,17 +427,19 @@ public Markings getMarkings() { ISubmodelElement element = getSubmodelElement(MARKINGSID); return element == null ? null : Markings.createAsFacade((Map) element); } - + /** * Sets collection of guideline specific properties + * * @param assetSpecificProperties */ public void setAssetSpecificProperties(AssetSpecificProperties assetSpecificProperties) { addSubmodelElement(assetSpecificProperties); } - + /** * Gets collection of guideline specific properties + * * @return */ @SuppressWarnings("unchecked") diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java index 74e8074e..7f1ffb11 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/FaxType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.enums; @@ -13,23 +28,24 @@ import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper; /** - * characterization of the fax according its location or usage - * as described in the AAS Digital Nameplate template + * characterization of the fax according its location or usage as described in + * the AAS Digital Nameplate template + * * @author haque * */ -public enum FaxType implements StandardizedLiteralEnum { - +public enum FaxType implements StandardizedLiteralEnum { + /** * (office, 0173-1#07-AAS754#001) */ OFFICE("1"), - + /** * (secretary, 0173-1#07-AAS756#001) */ SECRETARY("3"), - + /** * (home, 0173-1#07-AAS758#001) */ diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java index 9a6b1b60..8eb373ae 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/MailType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.enums; @@ -13,29 +28,30 @@ import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper; /** - * characterization of an e-mail address according to its location or usage - * as described in the AAS Digital Nameplate template + * characterization of an e-mail address according to its location or usage as + * described in the AAS Digital Nameplate template + * * @author haque * */ public enum MailType implements StandardizedLiteralEnum { // Enum values - + /** * (office, 0173-1#07-AAS754#001) */ OFFICE("1"), - + /** * (secretary, 0173-1#07-AAS756#001) */ SECRETARY("3"), - + /** * (substitute, 0173-1#07-AAS757#001) */ SUBSTITUTE("4"), - + /** * (home, 0173-1#07-AAS758#001) */ diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java index b588eae5..a7ba41ba 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/enums/PhoneType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.enums; @@ -13,42 +28,44 @@ import org.eclipse.basyx.submodel.metamodel.enumhelper.StandardizedLiteralEnumHelper; /** - * characterization of a telephone according to its location or usage - * as described in the AAS Digital Nameplate template + * characterization of a telephone according to its location or usage as + * described in the AAS Digital Nameplate template + * * @author haque * */ public enum PhoneType implements StandardizedLiteralEnum { - + /** * (office, 0173-1#07-AAS754#001) */ OFFICE("1"), - + /** * (office mobile, 0173-1#07-AAS755#001) */ OFFICEMOBILE("2"), - + /** * (secretary, 0173-1#07-AAS756#001) */ SECRETARY("3"), - + /** * (substitute, 0173-1#07-AAS757#001) */ SUBSTITUTE("4"), - + /** * (home, 0173-1#07-AAS758#001) */ HOME("5"), - + /** * (private mobile, 0173-1#07-AAS759#001) */ - PRIVATEMOBILE("6");; + PRIVATEMOBILE("6"); + ; private String standardizedLiteral; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java index ea3d94af..e6129e95 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Address.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address; @@ -33,9 +48,9 @@ /** * Address as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains - * The standardized SMC Address contains information - * about address of a partner within the value chain. + * It is a submodel element collection which contains The standardized SMC + * Address contains information about address of a partner within the value + * chain. * * @author haque * @@ -57,12 +72,13 @@ public class Address extends SubmodelElementCollection { public static final String EMAILPREFIX = "Email"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ832#005", KeyType.IRDI)); public static final String ADDRESSIDSHORT = "Address"; - + private Address() { } - + /** * Constructor with default idShort + * * @param street * @param zipCode * @param cityTown @@ -71,9 +87,10 @@ private Address() { public Address(MultiLanguageProperty street, MultiLanguageProperty zipCode, MultiLanguageProperty cityTown, MultiLanguageProperty nationalCode) { this(ADDRESSIDSHORT, street, zipCode, cityTown, nationalCode); } - + /** * Constructor with default idShort + * * @param street * @param zipCode * @param cityTown @@ -82,9 +99,10 @@ public Address(MultiLanguageProperty street, MultiLanguageProperty zipCode, Mult public Address(LangString street, LangString zipCode, LangString cityTown, LangString nationalCode) { this(ADDRESSIDSHORT, street, zipCode, cityTown, nationalCode); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param street * @param zipCode @@ -99,9 +117,10 @@ public Address(String idShort, MultiLanguageProperty street, MultiLanguageProper setCityTown(cityTown); setNationalCode(nationalCode); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param street * @param zipCode @@ -116,18 +135,19 @@ public Address(String idShort, LangString street, LangString zipCode, LangString setCityTown(cityTown); setNationalCode(nationalCode); } - + /** * Creates a Address SMC object from a map * - * @param obj a Address SMC object as raw map + * @param obj + * a Address SMC object as raw map * @return a Address SMC object, that behaves like a facade for the given map */ public static Address createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Address.class, obj); } @@ -136,11 +156,12 @@ public static Address createAsFacade(Map obj) { address.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return address; } - + /** * Creates a Address SMC object from a map without validation * - * @param obj a Address SMC object as raw map + * @param obj + * a Address SMC object as raw map * @return a Address SMC object, that behaves like a facade for the given map */ private static Address createAsFacadeNonStrict(Map obj) { @@ -152,10 +173,9 @@ private static Address createAsFacadeNonStrict(Map obj) { address.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return address; } - + /** - * Check whether all mandatory elements for Address SMC - * exist in the map + * Check whether all mandatory elements for Address SMC exist in the map * * @param obj * @@ -164,16 +184,15 @@ private static Address createAsFacadeNonStrict(Map obj) { @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { Address address = createAsFacadeNonStrict(obj); - - return SubmodelElementCollection.isValid(obj) - && MultiLanguageProperty.isValid((Map) address.getStreet()) - && MultiLanguageProperty.isValid((Map) address.getZipCode()) - && MultiLanguageProperty.isValid((Map) address.getCityTown()) - && MultiLanguageProperty.isValid((Map) address.getNationalCode()); + + return SubmodelElementCollection.isValid(obj) && MultiLanguageProperty.isValid((Map) address.getStreet()) && MultiLanguageProperty.isValid((Map) address.getZipCode()) + && MultiLanguageProperty.isValid((Map) address.getCityTown()) && MultiLanguageProperty.isValid((Map) address.getNationalCode()); } /** - * Gets administrative section within an organisation where a business partner is located + * Gets administrative section within an organisation where a business partner + * is located + * * @return */ @SuppressWarnings("unchecked") @@ -182,16 +201,22 @@ public IMultiLanguageProperty getDepartment() { } /** - * Sets administrative section within an organisation where a business partner is located - * @param department {@link MultiLanguageProperty} + * Sets administrative section within an organisation where a business partner + * is located + * + * @param department + * {@link MultiLanguageProperty} */ public void setDepartment(MultiLanguageProperty department) { addSubmodelElement(department); } - + /** - * Sets administrative section within an organisation where a business partner is located - * @param department {@link LangString} + * Sets administrative section within an organisation where a business partner + * is located + * + * @param department + * {@link LangString} */ public void setDepartment(LangString department) { MultiLanguageProperty deptProp = new MultiLanguageProperty(DEPARTMENTID); @@ -201,8 +226,9 @@ public void setDepartment(LangString department) { } /** - * Gets street name and house number - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Gets street name and house number Note: mandatory property according to EU + * Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") @@ -211,18 +237,22 @@ public IMultiLanguageProperty getStreet() { } /** - * Sets street name and house number - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param street {@link MultiLanguageProperty} + * Sets street name and house number Note: mandatory property according to EU + * Machine Directive 2006/42/EC. + * + * @param street + * {@link MultiLanguageProperty} */ public void setStreet(MultiLanguageProperty street) { addSubmodelElement(street); } - + /** - * Sets street name and house number - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param street {@link LangString} + * Sets street name and house number Note: mandatory property according to EU + * Machine Directive 2006/42/EC. + * + * @param street + * {@link LangString} */ public void setStreet(LangString street) { MultiLanguageProperty streetProp = new MultiLanguageProperty(STREETID); @@ -232,8 +262,9 @@ public void setStreet(LangString street) { } /** - * Gets ZIP code of address - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Gets ZIP code of address Note: mandatory property according to EU Machine + * Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") @@ -242,18 +273,22 @@ public IMultiLanguageProperty getZipCode() { } /** - * Sets ZIP code of address - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param zipCode {@link MultiLanguageProperty} + * Sets ZIP code of address Note: mandatory property according to EU Machine + * Directive 2006/42/EC. + * + * @param zipCode + * {@link MultiLanguageProperty} */ public void setZipCode(MultiLanguageProperty zipCode) { addSubmodelElement(zipCode); } - + /** - * Sets ZIP code of address - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param zipCode {@link LangString} + * Sets ZIP code of address Note: mandatory property according to EU Machine + * Directive 2006/42/EC. + * + * @param zipCode + * {@link LangString} */ public void setZipCode(LangString zipCode) { MultiLanguageProperty zipCodeProp = new MultiLanguageProperty(ZIPCODEID); @@ -264,6 +299,7 @@ public void setZipCode(LangString zipCode) { /** * Gets P.O. box number + * * @return */ @SuppressWarnings("unchecked") @@ -273,15 +309,19 @@ public IMultiLanguageProperty getPOBox() { /** * Sets P.O. box number - * @param poBox {@link MultiLanguageProperty} + * + * @param poBox + * {@link MultiLanguageProperty} */ public void setPOBox(MultiLanguageProperty poBox) { addSubmodelElement(poBox); } - + /** * Sets P.O. box number - * @param poBox {@link LangString} + * + * @param poBox + * {@link LangString} */ public void setPOBox(LangString poBox) { MultiLanguageProperty poBoxProp = new MultiLanguageProperty(POBOXID); @@ -292,6 +332,7 @@ public void setPOBox(LangString poBox) { /** * Gets ZIP code of P.O. box address + * * @return */ @SuppressWarnings("unchecked") @@ -301,15 +342,19 @@ public IMultiLanguageProperty getZipCodeOfPOBox() { /** * Sets ZIP code of P.O. box address - * @param zipCodeOfPoBox {@link MultiLanguageProperty} + * + * @param zipCodeOfPoBox + * {@link MultiLanguageProperty} */ public void setZipCodeOfPOBox(MultiLanguageProperty zipCodeOfPoBox) { addSubmodelElement(zipCodeOfPoBox); } - + /** * Sets ZIP code of P.O. box address - * @param zipCodeOfPoBox {@link LangString} + * + * @param zipCodeOfPoBox + * {@link LangString} */ public void setZipCodeOfPOBox(LangString zipCodeOfPoBox) { MultiLanguageProperty zipCodeOfPoBoxProp = new MultiLanguageProperty(ZIPCODEOFPOBOXID); @@ -319,28 +364,33 @@ public void setZipCodeOfPOBox(LangString zipCodeOfPoBox) { } /** - * Gets town or city - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Gets town or city Note: mandatory property according to EU Machine Directive + * 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IMultiLanguageProperty getCityTown() { return MultiLanguageProperty.createAsFacade((Map) getSubmodelElement(CITYTOWNID)); } - + /** - * Sets town or city - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param cityTown {@link MultiLanguageProperty} + * Sets town or city Note: mandatory property according to EU Machine Directive + * 2006/42/EC. + * + * @param cityTown + * {@link MultiLanguageProperty} */ public void setCityTown(MultiLanguageProperty cityTown) { addSubmodelElement(cityTown); } - + /** - * Sets town or city - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param cityTown {@link LangString} + * Sets town or city Note: mandatory property according to EU Machine Directive + * 2006/42/EC. + * + * @param cityTown + * {@link LangString} */ public void setCityTown(LangString cityTown) { MultiLanguageProperty cityTownProp = new MultiLanguageProperty(CITYTOWNID); @@ -351,6 +401,7 @@ public void setCityTown(LangString cityTown) { /** * Gets federal state a part of a state + * * @return */ @SuppressWarnings("unchecked") @@ -360,7 +411,9 @@ public IMultiLanguageProperty getStateCounty() { /** * Sets federal state a part of a state - * @param stateCounty {@link MultiLanguageProperty} + * + * @param stateCounty + * {@link MultiLanguageProperty} */ public void setStateCounty(MultiLanguageProperty stateCounty) { addSubmodelElement(stateCounty); @@ -368,7 +421,9 @@ public void setStateCounty(MultiLanguageProperty stateCounty) { /** * Sets federal state a part of a state - * @param stateCounty {@link LangString} + * + * @param stateCounty + * {@link LangString} */ public void setStateCounty(LangString stateCounty) { MultiLanguageProperty stateCountyProp = new MultiLanguageProperty(STATECOUNTYID); @@ -376,11 +431,11 @@ public void setStateCounty(LangString stateCounty) { stateCountyProp.setValue(new LangStrings(stateCounty)); setStateCounty(stateCountyProp); } - + /** - * Gets code of a country - * Note: Country codes defined accord. to DIN EN ISO 3166-1 - * Note: mandatory property according to EU Machine Directive 2006/42/EC. + * Gets code of a country Note: Country codes defined accord. to DIN EN ISO + * 3166-1 Note: mandatory property according to EU Machine Directive 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") @@ -389,20 +444,22 @@ public IMultiLanguageProperty getNationalCode() { } /** - * Sets code of a country - * Note: Country codes defined accord. to DIN EN ISO 3166-1 - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param nationalCode {@link MultiLanguageProperty} + * Sets code of a country Note: Country codes defined accord. to DIN EN ISO + * 3166-1 Note: mandatory property according to EU Machine Directive 2006/42/EC. + * + * @param nationalCode + * {@link MultiLanguageProperty} */ public void setNationalCode(MultiLanguageProperty nationalCode) { addSubmodelElement(nationalCode); } - + /** - * Sets code of a country - * Note: Country codes defined accord. to DIN EN ISO 3166-1 - * Note: mandatory property according to EU Machine Directive 2006/42/EC. - * @param nationalCode {@link LangString} + * Sets code of a country Note: Country codes defined accord. to DIN EN ISO + * 3166-1 Note: mandatory property according to EU Machine Directive 2006/42/EC. + * + * @param nationalCode + * {@link LangString} */ public void setNationalCode(LangString nationalCode) { MultiLanguageProperty nationalCodeProp = new MultiLanguageProperty(NATIONALCODEID); @@ -413,6 +470,7 @@ public void setNationalCode(LangString nationalCode) { /** * Gets VAT identification number of the business partner + * * @return */ @SuppressWarnings("unchecked") @@ -422,15 +480,19 @@ public IMultiLanguageProperty getVatNumber() { /** * Sets VAT identification number of the business partner - * @param vatNumber {@link MultiLanguageProperty} + * + * @param vatNumber + * {@link MultiLanguageProperty} */ public void setVatNumber(MultiLanguageProperty vatNumber) { addSubmodelElement(vatNumber); } - + /** * Sets VAT identification number of the business partner - * @param vatNumber {@link LangString} + * + * @param vatNumber + * {@link LangString} */ public void setVatNumber(LangString vatNumber) { MultiLanguageProperty vatNumberProp = new MultiLanguageProperty(VATNUMBERID); @@ -440,7 +502,9 @@ public void setVatNumber(LangString vatNumber) { } /** - * Gets plain text characterizing address information for which there is no property + * Gets plain text characterizing address information for which there is no + * property + * * @return */ @SuppressWarnings("unchecked") @@ -449,16 +513,22 @@ public IMultiLanguageProperty getAddressRemarks() { } /** - * Sets plain text characterizing address information for which there is no property - * @param addressRemarks {@link MultiLanguageProperty} + * Sets plain text characterizing address information for which there is no + * property + * + * @param addressRemarks + * {@link MultiLanguageProperty} */ public void setAddressRemarks(MultiLanguageProperty addressRemarks) { addSubmodelElement(addressRemarks); } - + /** - * Sets plain text characterizing address information for which there is no property - * @param addressRemarks {@link LangString} + * Sets plain text characterizing address information for which there is no + * property + * + * @param addressRemarks + * {@link LangString} */ public void setAddressRemarks(LangString addressRemarks) { MultiLanguageProperty addressRemarksProp = new MultiLanguageProperty(ADDRESSREMARKSID); @@ -469,6 +539,7 @@ public void setAddressRemarks(LangString addressRemarks) { /** * Gets web site address where information about the product or contact is given + * * @return */ @SuppressWarnings("unchecked") @@ -478,15 +549,19 @@ public IProperty getAddressOfAdditionalLink() { /** * Sets web site address where information about the product or contact is given - * @param addressOfAdditionalLink {@link Property} + * + * @param addressOfAdditionalLink + * {@link Property} */ public void setAddressOfAdditionalLink(Property addressOfAdditionalLink) { addSubmodelElement(addressOfAdditionalLink); } - + /** * Sets web site address where information about the product or contact is given - * @param addressOfAdditionalLink {@link String} + * + * @param addressOfAdditionalLink + * {@link String} */ public void setAddressOfAdditionalLink(String addressOfAdditionalLink) { Property addressOfAdditionalLinkProp = new Property(ADDRESSOFADDITIONALLINKID, ValueType.String); @@ -497,14 +572,15 @@ public void setAddressOfAdditionalLink(String addressOfAdditionalLink) { /** * Gets Phone number including type + * * @return */ @SuppressWarnings("unchecked") public List getPhone() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PHONEPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(Phone.createAsFacade((Map) element)); } return ret; @@ -512,6 +588,7 @@ public List getPhone() { /** * Sets Phone number including type + * * @param phones */ public void setPhone(List phones) { @@ -524,14 +601,15 @@ public void setPhone(List phones) { /** * Gets fax number including type + * * @return */ @SuppressWarnings("unchecked") public List getFax() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(FAXPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(Fax.createAsFacade((Map) element)); } return ret; @@ -539,6 +617,7 @@ public List getFax() { /** * Sets fax number including type + * * @param faxes */ public void setFax(List faxes) { @@ -551,14 +630,15 @@ public void setFax(List faxes) { /** * Gets E-mail address and encryption method + * * @return */ @SuppressWarnings("unchecked") public List getEmail() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(EMAILPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(Email.createAsFacade((Map) element)); } return ret; @@ -566,6 +646,7 @@ public List getEmail() { /** * Sets E-mail address and encryption method + * * @param emails */ public void setEmail(List emails) { diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java index b830e03c..c32eff69 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Email.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address; @@ -30,7 +45,8 @@ /** * Email as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains email address and encryption method + * It is a submodel element collection which contains email address and + * encryption method * * @author haque * @@ -41,12 +57,13 @@ public class Email extends SubmodelElementCollection { public static final String TYPEOFEMAILADDRESSID = "TypeOfEmailAddress"; public static final String TYPEOFPUBLICKEYID = "TypeOfPublickKey"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ836#005", KeyType.IRDI)); - + private Email() { } - + /** * Constructor with mandatory attributes + * * @param idShort * @param emailAddress */ @@ -55,9 +72,10 @@ public Email(String idShort, Property emailAddress) { setSemanticId(SEMANTICID); setEmailAddress(emailAddress); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param emailAddress */ @@ -66,46 +84,47 @@ public Email(String idShort, String emailAddress) { setSemanticId(SEMANTICID); setEmailAddress(emailAddress); } - + /** * Creates a Email SMC object from a map * - * @param obj a Email SMC object as raw map + * @param obj + * a Email SMC object as raw map * @return a Email SMC object, that behaves like a facade for the given map */ public static Email createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Email.class, obj); } - + Email email = new Email(); email.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return email; } - + /** * Creates a Email SMC object from a map without validation * - * @param obj a Email SMC object as raw map + * @param obj + * a Email SMC object as raw map * @return a Email SMC object, that behaves like a facade for the given map */ private static Email createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + Email email = new Email(); email.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return email; } - + /** - * Check whether all mandatory elements for Email SMC - * exist in the map + * Check whether all mandatory elements for Email SMC exist in the map * * @param obj * @@ -114,22 +133,25 @@ private static Email createAsFacadeNonStrict(Map obj) { @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { Email email = createAsFacadeNonStrict(obj); - - return SubmodelElementCollection.isValid(obj) - && Property.isValid((Map) email.getEmailAddress()); + + return SubmodelElementCollection.isValid(obj) && Property.isValid((Map) email.getEmailAddress()); } - + /** * Sets electronic mail address of a business partner - * @param emailAddress Property + * + * @param emailAddress + * Property */ public void setEmailAddress(Property emailAddress) { addSubmodelElement(emailAddress); } - + /** * Sets electronic mail address of a business partner - * @param emailAddress String + * + * @param emailAddress + * String */ public void setEmailAddress(String emailAddress) { Property emailProp = new Property(EMAILADDRESSID, ValueType.String); @@ -137,27 +159,34 @@ public void setEmailAddress(String emailAddress) { emailProp.setValue(emailAddress); setEmailAddress(emailProp); } - + /** * Gets electronic mail address of a business partner + * * @return */ @SuppressWarnings("unchecked") public IProperty getEmailAddress() { return Property.createAsFacade((Map) getSubmodelElement(EMAILADDRESSID)); } - + /** - * Sets public part of an unsymmetrical key pair to sign or encrypt text or messages - * @param key {@link MultiLanguageProperty} + * Sets public part of an unsymmetrical key pair to sign or encrypt text or + * messages + * + * @param key + * {@link MultiLanguageProperty} */ public void setPublicKey(MultiLanguageProperty key) { addSubmodelElement(key); } - + /** - * Sets public part of an unsymmetrical key pair to sign or encrypt text or messages - * @param key {@link LangString} + * Sets public part of an unsymmetrical key pair to sign or encrypt text or + * messages + * + * @param key + * {@link LangString} */ public void setPublicKey(LangString key) { MultiLanguageProperty publicKey = new MultiLanguageProperty(PUBLICKEYID); @@ -165,29 +194,35 @@ public void setPublicKey(LangString key) { publicKey.setValue(new LangStrings(key)); setPublicKey(publicKey); } - + /** - * Gets public part of an unsymmetrical key pair to sign or encrypt text or messages + * Gets public part of an unsymmetrical key pair to sign or encrypt text or + * messages + * * @return */ @SuppressWarnings("unchecked") public IMultiLanguageProperty getPublicKey() { return MultiLanguageProperty.createAsFacade((Map) getSubmodelElement(PUBLICKEYID)); } - + /** * Sets characterization of an e-mail address according to its location or usage * enumeration - * @param type {@link Property} + * + * @param type + * {@link Property} */ public void setTypeOfEmailAddress(Property type) { addSubmodelElement(type); } - + /** * Sets characterization of an e-mail address according to its location or usage * enumeration - * @param type {@link MailType} + * + * @param type + * {@link MailType} */ public void setTypeOfEmailAddress(MailType type) { Property mailTypeProp = new Property(TYPEOFEMAILADDRESSID, ValueType.String); @@ -195,28 +230,33 @@ public void setTypeOfEmailAddress(MailType type) { mailTypeProp.setValue(type.toString()); setTypeOfEmailAddress(mailTypeProp); } - + /** * Gets characterization of an e-mail address according to its location or usage * enumeration + * * @return */ @SuppressWarnings("unchecked") public IProperty getTypeOfEmailAddress() { return Property.createAsFacade((Map) getSubmodelElement(TYPEOFEMAILADDRESSID)); } - + /** * Sets characterization of a public key according to its encryption process - * @param key {@link MultiLanguageProperty} + * + * @param key + * {@link MultiLanguageProperty} */ public void setTypeOfPublicKey(MultiLanguageProperty key) { addSubmodelElement(key); } - + /** * Sets characterization of a public key according to its encryption process - * @param key {@link LangString} + * + * @param key + * {@link LangString} */ public void setTypeOfPublicKey(LangString key) { MultiLanguageProperty typeOfPublicKey = new MultiLanguageProperty(TYPEOFPUBLICKEYID); @@ -224,9 +264,10 @@ public void setTypeOfPublicKey(LangString key) { typeOfPublicKey.setValue(new LangStrings(key)); setTypeOfPublicKey(typeOfPublicKey); } - + /** * Gets characterization of a public key according to its encryption process + * * @return */ @SuppressWarnings("unchecked") diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java index 9be6e8be..b09ffae5 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Fax.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address; @@ -30,7 +45,8 @@ /** * Fax as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains a fax number including type + * It is a submodel element collection which contains a fax number including + * type * * @author haque * @@ -39,12 +55,13 @@ public class Fax extends SubmodelElementCollection { public static final String FAXNUMBERID = "FaxNumber"; public static final String TYPEOFFAXID = "TypeOfFaxNumber"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ834#005", KeyType.IRDI)); - + private Fax() { } - + /** * Constructor with mandatory attributes + * * @param idShort * @param faxNumber */ @@ -53,9 +70,10 @@ public Fax(String idShort, LangString faxNumber) { setSemanticId(SEMANTICID); setFaxNumber(faxNumber); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param faxNumber */ @@ -64,46 +82,47 @@ public Fax(String idShort, MultiLanguageProperty faxNumber) { setSemanticId(SEMANTICID); setFaxNumber(faxNumber); } - + /** * Creates a Fax SMC object from a map * - * @param obj a Fax SMC object as raw map + * @param obj + * a Fax SMC object as raw map * @return a Fax SMC object, that behaves like a facade for the given map */ public static Fax createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Fax.class, obj); } - + Fax fax = new Fax(); fax.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return fax; } - + /** * Creates a Fax SMC object from a map without validation * - * @param obj a Fax SMC object as raw map + * @param obj + * a Fax SMC object as raw map * @return a Fax SMC object, that behaves like a facade for the given map */ private static Fax createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + Fax fax = new Fax(); fax.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return fax; } - + /** - * Check whether all mandatory elements for Fax SMC - * exist in the map + * Check whether all mandatory elements for Fax SMC exist in the map * * @param obj * @@ -112,23 +131,26 @@ private static Fax createAsFacadeNonStrict(Map obj) { @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { Fax fax = createAsFacadeNonStrict(obj); - return SubmodelElementCollection.isValid(obj) - && MultiLanguageProperty.isValid((Map) fax.getFaxNumber()); + return SubmodelElementCollection.isValid(obj) && MultiLanguageProperty.isValid((Map) fax.getFaxNumber()); } - + /** - * Sets complete telephone number to be called to reach a - * business partner's fax machine - * @param faxNumber {@link MultiLanguageProperty} + * Sets complete telephone number to be called to reach a business partner's fax + * machine + * + * @param faxNumber + * {@link MultiLanguageProperty} */ public void setFaxNumber(MultiLanguageProperty faxNumber) { addSubmodelElement(faxNumber); } - + /** - * Sets complete telephone number to be called to reach a - * business partner's fax machine - * @param faxNumber {@link LangString} + * Sets complete telephone number to be called to reach a business partner's fax + * machine + * + * @param faxNumber + * {@link LangString} */ public void setFaxNumber(LangString faxNumber) { MultiLanguageProperty faxProp = new MultiLanguageProperty(FAXNUMBERID); @@ -136,18 +158,22 @@ public void setFaxNumber(LangString faxNumber) { faxProp.setValue(new LangStrings(faxNumber)); setFaxNumber(faxProp); } - + /** * Sets characterization of the fax according its location or usage - * @param type {@link Property} + * + * @param type + * {@link Property} */ public void setTypeOfFaxNumber(Property type) { addSubmodelElement(type); } - + /** * Sets characterization of the fax according its location or usage - * @param type {@link FaxType} + * + * @param type + * {@link FaxType} */ public void setTypeOfFaxNumber(FaxType type) { Property faxTypeProp = new Property(TYPEOFFAXID, ValueType.String); @@ -155,19 +181,21 @@ public void setTypeOfFaxNumber(FaxType type) { faxTypeProp.setValue(type.toString()); setTypeOfFaxNumber(faxTypeProp); } - + /** * Gets characterization of the fax according its location or usage + * * @return */ @SuppressWarnings("unchecked") public IProperty getTypeOfFaxNumber() { return Property.createAsFacade((Map) getSubmodelElement(TYPEOFFAXID)); } - + /** - * Gets complete telephone number to be called to reach a - * business partner's fax machine + * Gets complete telephone number to be called to reach a business partner's fax + * machine + * * @return */ @SuppressWarnings("unchecked") diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java index e208c202..02f94f5f 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/address/Phone.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.address; @@ -30,7 +45,8 @@ /** * Phone as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains a phone number including type + * It is a submodel element collection which contains a phone number including + * type * * @author haque * @@ -40,11 +56,13 @@ public class Phone extends SubmodelElementCollection { public static final String TYPEOFTELEPHONEID = "TypeOfTelephone"; public static final String PHONEID = "Phone"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAQ833#005", KeyType.IRDI)); - - private Phone() {} - + + private Phone() { + } + /** * Constructor with mandatory attributes + * * @param idShort * @param telephoneNumber */ @@ -53,9 +71,10 @@ public Phone(String idShort, LangString telephoneNumber) { setSemanticId(SEMANTICID); setTelephoneNumber(telephoneNumber); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param telephoneNumber */ @@ -64,46 +83,47 @@ public Phone(String idShort, MultiLanguageProperty telephoneNumber) { setSemanticId(SEMANTICID); setTelephoneNumber(telephoneNumber); } - + /** * Creates a Phone SMC object from a map * - * @param obj a Phone SMC object as raw map + * @param obj + * a Phone SMC object as raw map * @return a Phone SMC object, that behaves like a facade for the given map */ public static Phone createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Phone.class, obj); } - + Phone phone = new Phone(); phone.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return phone; } - + /** * Creates a Phone SMC object from a map without checking validity * - * @param obj a Phone SMC object as raw map + * @param obj + * a Phone SMC object as raw map * @return a Phone SMC object, that behaves like a facade for the given map */ private static Phone createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + Phone phone = new Phone(); phone.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return phone; } - + /** - * Check whether all mandatory elements for Phone SMC - * exist in the map + * Check whether all mandatory elements for Phone SMC exist in the map * * @param obj * @@ -112,22 +132,25 @@ private static Phone createAsFacadeNonStrict(Map obj) { @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { Phone phone = createAsFacadeNonStrict(obj); - - return SubmodelElementCollection.isValid(obj) - && MultiLanguageProperty.isValid((Map) phone.getTelephoneNumber()); + + return SubmodelElementCollection.isValid(obj) && MultiLanguageProperty.isValid((Map) phone.getTelephoneNumber()); } - + /** * Sets complete telephone number to be called to reach a business partner - * @param telephoneNumber {@link MultiLanguageProperty} + * + * @param telephoneNumber + * {@link MultiLanguageProperty} */ public void setTelephoneNumber(MultiLanguageProperty telephoneNumber) { addSubmodelElement(telephoneNumber); } - + /** * Sets complete telephone number to be called to reach a business partner - * @param telephoneNumber {@link LangString} + * + * @param telephoneNumber + * {@link LangString} */ public void setTelephoneNumber(LangString telephoneNumber) { MultiLanguageProperty phoneProp = new MultiLanguageProperty(TELEPHONENUMBERID); @@ -135,18 +158,24 @@ public void setTelephoneNumber(LangString telephoneNumber) { phoneProp.setValue(new LangStrings(telephoneNumber)); setTelephoneNumber(phoneProp); } - + /** - * Sets characterization of a telephone according to its location or usage enumeration - * @param type {@link Property} + * Sets characterization of a telephone according to its location or usage + * enumeration + * + * @param type + * {@link Property} */ public void setTypeOfTelephone(Property type) { addSubmodelElement(type); } - + /** - * Sets characterization of a telephone according to its location or usage enumeration - * @param type {@link PhoneType} + * Sets characterization of a telephone according to its location or usage + * enumeration + * + * @param type + * {@link PhoneType} */ public void setTypeOfTelephone(PhoneType type) { Property phoneTypeProp = new Property(TYPEOFTELEPHONEID, ValueType.String); @@ -154,18 +183,21 @@ public void setTypeOfTelephone(PhoneType type) { phoneTypeProp.setValue(type.toString()); setTypeOfTelephone(phoneTypeProp); } - + /** - * Gets characterization of a telephone according to its location or usage enumeration + * Gets characterization of a telephone according to its location or usage + * enumeration + * * @return */ @SuppressWarnings("unchecked") public IProperty getTypeOfTelephone() { return Property.createAsFacade((Map) getSubmodelElement(TYPEOFTELEPHONEID)); } - + /** * Gets complete telephone number to be called to reach a business partner + * * @return */ @SuppressWarnings("unchecked") diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java index e89fe051..062f4740 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/AssetSpecificProperties.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties; @@ -24,8 +39,10 @@ import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper; /** - * AssetSpecificProperties as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains collection of guideline specific properties + * AssetSpecificProperties as defined in the AAS Digital Nameplate Template + * document
+ * It is a submodel element collection which contains collection of guideline + * specific properties * * @author haque * @@ -34,18 +51,19 @@ public class AssetSpecificProperties extends SubmodelElementCollection { public static final String ASSETSPECIFICPROPERTIESID = "AssetSpecificProperties"; public static final String GUIDELINESPECIFICPROPERTYPREFIX = "GuidelineSpecificProperties"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties", KeyType.IRI)); - + private AssetSpecificProperties() { } - + /** * Constructor with default idShort + * * @param guidelineSpecificProperties */ public AssetSpecificProperties(List guidelineSpecificProperties) { - this (ASSETSPECIFICPROPERTIESID, guidelineSpecificProperties); + this(ASSETSPECIFICPROPERTIESID, guidelineSpecificProperties); } - + /** * Constructor with mandatory attributes * @@ -57,46 +75,50 @@ public AssetSpecificProperties(String idShort, List setSemanticId(SEMANTICID); setGuidelineSpecificProperties(guidelineSpecificProperties); } - + /** * Creates a AssetSpecificProperties SMC object from a map * - * @param obj a AssetSpecificProperties SMC object as raw map - * @return a AssetSpecificProperties SMC object, that behaves like a facade for the given map + * @param obj + * a AssetSpecificProperties SMC object as raw map + * @return a AssetSpecificProperties SMC object, that behaves like a facade for + * the given map */ public static AssetSpecificProperties createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(AssetSpecificProperties.class, obj); } - + AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties(); - assetSpecificProperties.setMap((Map)SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); + assetSpecificProperties.setMap((Map) SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return assetSpecificProperties; } - + /** * Creates a AssetSpecificProperties SMC object from a map without validation * - * @param obj a AssetSpecificProperties SMC object as raw map - * @return a AssetSpecificProperties SMC object, that behaves like a facade for the given map + * @param obj + * a AssetSpecificProperties SMC object as raw map + * @return a AssetSpecificProperties SMC object, that behaves like a facade for + * the given map */ private static AssetSpecificProperties createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties(); - assetSpecificProperties.setMap((Map)SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); + assetSpecificProperties.setMap((Map) SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return assetSpecificProperties; } - + /** - * Check whether all mandatory elements for AssetSpecificProperties SMC - * exist in the map + * Check whether all mandatory elements for AssetSpecificProperties SMC exist in + * the map * * @param obj * @@ -104,10 +126,8 @@ private static AssetSpecificProperties createAsFacadeNonStrict(Map obj) { AssetSpecificProperties props = createAsFacadeNonStrict(obj); - - if (SubmodelElementCollection.isValid(obj) - && props.getGuidelineSpecificProperties() != null - && props.getGuidelineSpecificProperties().size() > 0) { + + if (SubmodelElementCollection.isValid(obj) && props.getGuidelineSpecificProperties() != null && props.getGuidelineSpecificProperties().size() > 0) { for (GuidelineSpecificProperties prop : props.getGuidelineSpecificProperties()) { if (!GuidelineSpecificProperties.isValid((Map) prop)) { return false; @@ -115,10 +135,10 @@ public static boolean isValid(Map obj) { } return true; } else { - return false; + return false; } } - + public void setGuidelineSpecificProperties(List properties) { if (properties != null & properties.size() > 0) { for (GuidelineSpecificProperties prop : properties) { @@ -131,8 +151,8 @@ public void setGuidelineSpecificProperties(List pro public List getGuidelineSpecificProperties() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(GUIDELINESPECIFICPROPERTYPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(GuidelineSpecificProperties.createAsFacade((Map) element)); } return ret; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java index 7473dbc8..4ad6d049 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/GuidelineSpecificProperties.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties; @@ -27,8 +42,9 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; /** - * GuidelineSpecificProperties as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains Asset specific nameplate + * GuidelineSpecificProperties as defined in the AAS Digital Nameplate Template + * document
+ * It is a submodel element collection which contains Asset specific nameplate * information required by guideline, stipulation or legislation. * * @author haque @@ -37,10 +53,10 @@ public class GuidelineSpecificProperties extends SubmodelElementCollection { public static final String GUIDELINEFORCONFORMITYDECLARATIONID = "GuidelineForConformityDeclaration"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://adminshell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties/GuidelineSpecificProperties", KeyType.IRI)); - + private GuidelineSpecificProperties() { } - + /** * Constructor with mandatory attributes * @@ -54,7 +70,7 @@ public GuidelineSpecificProperties(String idShort, Property declaration, List obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(GuidelineSpecificProperties.class, obj); } - + GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties(); guidelineSpecificProperties.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return guidelineSpecificProperties; } - + /** - * Creates a GuidelineSpecificProperties SMC object from a map without validation + * Creates a GuidelineSpecificProperties SMC object from a map without + * validation * - * @param obj a GuidelineSpecificProperties SMC object as raw map - * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map + * @param obj + * a GuidelineSpecificProperties SMC object as raw map + * @return a GuidelineSpecificProperties SMC object, that behaves like a facade + * for the given map */ private static GuidelineSpecificProperties createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties(); guidelineSpecificProperties.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return guidelineSpecificProperties; } - + /** * Check whether all mandatory elements for GuidelineSpecificProperties SMC * exist in the map @@ -116,36 +137,34 @@ private static GuidelineSpecificProperties createAsFacadeNonStrict(Map obj) { GuidelineSpecificProperties props = createAsFacadeNonStrict(obj); - - if (SubmodelElementCollection.isValid(obj) - && Property.isValid((Map) props.getGuidelineForConformityDeclaration()) - && props.getArbitrary() != null - && props.getArbitrary().size() > 0) { - for (IProperty arbitrary: props.getArbitrary()) { + + if (SubmodelElementCollection.isValid(obj) && Property.isValid((Map) props.getGuidelineForConformityDeclaration()) && props.getArbitrary() != null && props.getArbitrary().size() > 0) { + for (IProperty arbitrary : props.getArbitrary()) { if (!Property.isValid((Map) arbitrary)) { return false; - } + } } return true; - } - else { - return false; + } else { + return false; } } - + /** * Sets guideline, stipulation or legislation used for determining conformity * - * @param declaration {@link Property} + * @param declaration + * {@link Property} */ public void setGuidelineForConformityDeclaration(Property declaration) { addSubmodelElement(declaration); } - + /** * Sets guideline, stipulation or legislation used for determining conformity * - * @param declaration {@link String} + * @param declaration + * {@link String} */ public void setGuidelineForConformityDeclaration(String declaration) { Property declarationProp = new Property(GUIDELINEFORCONFORMITYDECLARATIONID, ValueType.String); @@ -153,7 +172,7 @@ public void setGuidelineForConformityDeclaration(String declaration) { declarationProp.setValue(declaration); setGuidelineForConformityDeclaration(declarationProp); } - + /** * Gets guideline, stipulation or legislation used for determining conformity * @@ -163,16 +182,17 @@ public void setGuidelineForConformityDeclaration(String declaration) { public IProperty getGuidelineForConformityDeclaration() { return Property.createAsFacade((Map) getSubmodelElement(GUIDELINEFORCONFORMITYDECLARATIONID)); } - + /** * Gets arbitrary, representing information required by further standards + * * @return */ public List getArbitrary() { List ret = new ArrayList(); Map elemMap = getSubmodelElements(); if (elemMap != null && elemMap.size() > 0) { - for (Map.Entry singleElement: elemMap.entrySet()) { + for (Map.Entry singleElement : elemMap.entrySet()) { if (!singleElement.getKey().equals(GUIDELINEFORCONFORMITYDECLARATIONID)) { ret.add((IProperty) singleElement.getValue()); } @@ -183,6 +203,7 @@ public List getArbitrary() { /** * Sets arbitrary, representing information required by further standards + * * @param arbitraries */ public void setArbitrary(List arbitraries) { diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java index be52f3f3..b463bdae 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Marking.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings; @@ -31,8 +46,8 @@ /** * Marking as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which - * contains information about the marking labelled on the device + * It is a submodel element collection which contains information about the + * marking labelled on the device * * @author haque * @@ -42,10 +57,10 @@ public class Marking extends SubmodelElementCollection { public static final String MARKINGFILEID = "MarkingFile"; public static final String MARKINGADDITIONALTEXTPREFIX = "MarkingAdditionalText"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/0/1/Nameplate/Markings/Marking", KeyType.IRI)); - + private Marking() { } - + /** * Constructor with mandatory attributes * @@ -60,7 +75,7 @@ public Marking(String idShort, Property markingName, File markingFile) { setMarkingName(markingName); setMarkingFile(markingFile); } - + /** * Constructor with mandatory attributes * @@ -75,46 +90,47 @@ public Marking(String idShort, String markingName, File markingFile) { setMarkingName(markingName); setMarkingFile(markingFile); } - + /** * Creates a Marking SMC object from a map * - * @param obj a Marking SMC object as raw map + * @param obj + * a Marking SMC object as raw map * @return a Marking SMC object, that behaves like a facade for the given map */ public static Marking createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Marking.class, obj); } - + Marking marking = new Marking(); marking.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return marking; } - + /** * Creates a Marking SMC object from a map without validation * - * @param obj a Marking SMC object as raw map + * @param obj + * a Marking SMC object as raw map * @return a Marking SMC object, that behaves like a facade for the given map */ private static Marking createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + Marking marking = new Marking(); marking.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return marking; } - + /** - * Check whether all mandatory elements for Marking SMC - * exist in the map + * Check whether all mandatory elements for Marking SMC exist in the map * * @param obj * @@ -123,27 +139,27 @@ private static Marking createAsFacadeNonStrict(Map obj) { @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { Marking marking = createAsFacadeNonStrict(obj); - return SubmodelElementCollection.isValid(obj) - && Property.isValid((Map) marking.getMarkingName()) - && File.isValid((Map) marking.getMarkingFile()); + return SubmodelElementCollection.isValid(obj) && Property.isValid((Map) marking.getMarkingName()) && File.isValid((Map) marking.getMarkingFile()); } - + /** * Sets common name of the marking * - * Note: CE marking is declared as mandatory according to EU - * Machine Directive 2006/42/EC. + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @param markingName */ public void setMarkingName(Property markingName) { addSubmodelElement(markingName); } - + /** * Sets common name of the marking * - * Note: CE marking is declared as mandatory according to EU - * Machine Directive 2006/42/EC. + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @param markingName */ public void setMarkingName(String markingName) { @@ -152,45 +168,48 @@ public void setMarkingName(String markingName) { markingNameProp.setValue(markingName); setMarkingName(markingNameProp); } - + /** * Gets common name of the marking * - * Note: CE marking is declared as mandatory according to EU - * Machine Directive 2006/42/EC. + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IProperty getMarkingName() { return Property.createAsFacade((Map) getSubmodelElement(MARKINGNAMEID)); } - + /** * Sets picture of the marking - * - * Note: CE marking is declared as mandatory according to EU - * Machine Directive 2006/42/EC. + * + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @param markingFile */ public void setMarkingFile(File markingFile) { addSubmodelElement(markingFile); } - + /** * Gets picture of the marking - * - * Note: CE marking is declared as mandatory according to EU - * Machine Directive 2006/42/EC. + * + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public IFile getMarkingFile() { return File.createAsFacade((Map) getSubmodelElement(MARKINGFILEID)); } - + /** - * Sets where applicable, additional information on the marking in - * plain text + * Sets where applicable, additional information on the marking in plain text + * * @param markingAdditionalText */ public void setMarkingAdditionalText(List markingAdditionalText) { @@ -200,17 +219,17 @@ public void setMarkingAdditionalText(List markingAdditionalText) { } } } - + /** - * Gets where applicable, additional information on the marking in - * plain text + * Gets where applicable, additional information on the marking in plain text + * * @return */ public List getMarkingAdditionalText() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MARKINGADDITIONALTEXTPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add((IProperty) element); } return ret; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java index ec0bab01..bef65fac 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/digitalnameplate/submodelelementcollections/markings/Markings.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.markings; @@ -25,9 +40,11 @@ /** * Markings as defined in the AAS Digital Nameplate Template document
- * It is a submodel element collection which contains a collection of product markings + * It is a submodel element collection which contains a collection of product + * markings * - * Note: CE marking is declared as mandatory according to EU Machine Directive 2006/42/EC. + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. * * @author haque * @@ -36,18 +53,19 @@ public class Markings extends SubmodelElementCollection { public static final String IDSHORT = "Markings"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate/Markings", KeyType.IRI)); public static final String MARKINGPREFIX = "Marking"; - + private Markings() { } - + /** * Constructor with default idShort + * * @param markings */ public Markings(List markings) { this(IDSHORT, markings); } - + /** * Constructor with mandatory attributes * @@ -59,46 +77,47 @@ public Markings(String idShort, List markings) { setSemanticId(SEMANTICID); setMarking(markings); } - + /** * Creates a Markings SMC object from a map * - * @param obj a Markings SMC object as raw map + * @param obj + * a Markings SMC object as raw map * @return a Markings SMC object, that behaves like a facade for the given map */ public static Markings createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(Markings.class, obj); } - + Markings markings = new Markings(); - markings.setMap((Map)SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); + markings.setMap((Map) SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return markings; } - + /** * Creates a Markings SMC object from a map without validation * - * @param obj a Markings SMC object as raw map + * @param obj + * a Markings SMC object as raw map * @return a Markings SMC object, that behaves like a facade for the given map */ private static Markings createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + Markings markings = new Markings(); - markings.setMap((Map)SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); + markings.setMap((Map) SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return markings; } - + /** - * Check whether all mandatory elements for Markings SMC - * exist in the map + * Check whether all mandatory elements for Markings SMC exist in the map * * @param obj * @@ -106,27 +125,25 @@ private static Markings createAsFacadeNonStrict(Map obj) { */ public static boolean isValid(Map obj) { Markings markings = createAsFacadeNonStrict(obj); - - if (SubmodelElementCollection.isValid(obj) - && markings.getMarking() != null - && markings.getMarking().size() > 0) { + + if (SubmodelElementCollection.isValid(obj) && markings.getMarking() != null && markings.getMarking().size() > 0) { for (Marking marking : markings.getMarking()) { if (!Marking.isValid((Map) marking)) { return false; - } + } } return true; - } - else { - return false; + } else { + return false; } } - + /** * Sets information about the marking labelled on the device - - * Note: CE marking is declared as mandatory according to EU Machine - * Directive 2006/42/EC. + * + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @param markings */ public void setMarking(List markings) { @@ -136,20 +153,21 @@ public void setMarking(List markings) { } } } - + /** * Gets information about the marking labelled on the device - - * Note: CE marking is declared as mandatory according to EU Machine - * Directive 2006/42/EC. + * + * Note: CE marking is declared as mandatory according to EU Machine Directive + * 2006/42/EC. + * * @return */ @SuppressWarnings("unchecked") public List getMarking() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MARKINGPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(Marking.createAsFacade((Map) element)); } return ret; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java b/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java index a5fccbda..c70b665b 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/helper/SubmodelElementRetrievalHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.helper; @@ -17,7 +32,7 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; public class SubmodelElementRetrievalHelper { - + public static List getSubmodelElementsByIdPrefix(String prefix, Map elemMap) { if (elemMap != null && elemMap.size() > 0) { return elemMap.values().stream().filter(s -> s.getIdShort().startsWith(prefix)).collect(Collectors.toList()); diff --git a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java index 8839c921..f0061c57 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/TechnicalDataSubmodel.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.technicaldata; @@ -28,9 +43,11 @@ import org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties.TechnicalProperties; /** - * TechnicalDataSubmodel as described in the Submodel Template AAS Technical Data Document + * TechnicalDataSubmodel as described in the Submodel Template AAS Technical + * Data Document * - * this contains Submodel containing technical data of the asset and associated product classifications. + * this contains Submodel containing technical data of the asset and associated + * product classifications. * * @author haque * @@ -42,29 +59,26 @@ public class TechnicalDataSubmodel extends Submodel { public static final String FURTHERINFORMATIONID = "FurtherInformation"; public static final Reference SEMANTICID = new Reference(Collections.singletonList(new Key(KeyElements.CONCEPTDESCRIPTION, false, "http://admin-shell.io/ZVEI/TechnicalData/Submodel/1/1", KeyType.IRI))); public static final String SUBMODELID = "TechnicalData"; - - private TechnicalDataSubmodel() {} - + + private TechnicalDataSubmodel() { + } + /** * Constructor with default idShort + * * @param identifier * @param generalInformation * @param productClassifications * @param properties * @param furtherInformation */ - public TechnicalDataSubmodel( - Identifier identifier, - GeneralInformation generalInformation, - ProductClassifications productClassifications, - TechnicalProperties properties, - FurtherInformation furtherInformation - ) { + public TechnicalDataSubmodel(Identifier identifier, GeneralInformation generalInformation, ProductClassifications productClassifications, TechnicalProperties properties, FurtherInformation furtherInformation) { this(SUBMODELID, identifier, generalInformation, productClassifications, properties, furtherInformation); } - + /** * Constructor with mandatory attributes + * * @param idShort * @param identifier * @param generalInformation @@ -72,14 +86,7 @@ public TechnicalDataSubmodel( * @param properties * @param furtherInformation */ - public TechnicalDataSubmodel( - String idShort, - Identifier identifier, - GeneralInformation generalInformation, - ProductClassifications productClassifications, - TechnicalProperties properties, - FurtherInformation furtherInformation - ) { + public TechnicalDataSubmodel(String idShort, Identifier identifier, GeneralInformation generalInformation, ProductClassifications productClassifications, TechnicalProperties properties, FurtherInformation furtherInformation) { super(idShort, identifier); setSemanticId(SEMANTICID); setGeneralInformation(generalInformation); @@ -87,46 +94,50 @@ public TechnicalDataSubmodel( setTechnicalProperties(properties); setFurtherInformation(furtherInformation); } - + /** * Creates a TechnicalDataSubmodel object from a map * - * @param obj a TechnicalDataSubmodel SMC object as raw map - * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for the given map + * @param obj + * a TechnicalDataSubmodel SMC object as raw map + * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for + * the given map */ public static TechnicalDataSubmodel createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(TechnicalDataSubmodel.class, obj); } - + TechnicalDataSubmodel ret = new TechnicalDataSubmodel(); - ret.setMap((Map)SubmodelElementMapCollectionConverter.mapToSM(obj)); + ret.setMap((Map) SubmodelElementMapCollectionConverter.mapToSM(obj)); return ret; } - + /** * Creates a TechnicalDataSubmodel object from a map without validation * - * @param obj a TechnicalDataSubmodel SMC object as raw map - * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for the given map + * @param obj + * a TechnicalDataSubmodel SMC object as raw map + * @return a TechnicalDataSubmodel SMC object, that behaves like a facade for + * the given map */ private static TechnicalDataSubmodel createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + TechnicalDataSubmodel ret = new TechnicalDataSubmodel(); - ret.setMap((Map)SubmodelElementMapCollectionConverter.mapToSM(obj)); + ret.setMap((Map) SubmodelElementMapCollectionConverter.mapToSM(obj)); return ret; } - + /** - * Check whether all mandatory elements for TechnicalDataSubmodel - * exist in the map + * Check whether all mandatory elements for TechnicalDataSubmodel exist in the + * map * * @param obj * @@ -134,12 +145,10 @@ private static TechnicalDataSubmodel createAsFacadeNonStrict(Map */ public static boolean isValid(Map obj) { TechnicalDataSubmodel submodel = createAsFacadeNonStrict(obj); - - return Submodel.isValid(obj) - && GeneralInformation.isValid((Map) submodel.getGeneralInformation()) - && TechnicalProperties.isValid((Map) submodel.getTechnicalProperties()); + + return Submodel.isValid(obj) && GeneralInformation.isValid((Map) submodel.getGeneralInformation()) && TechnicalProperties.isValid((Map) submodel.getTechnicalProperties()); } - + /** * Sets general information, for example ordering and manufacturer information. * @@ -148,7 +157,7 @@ public static boolean isValid(Map obj) { public void setGeneralInformation(GeneralInformation information) { addSubmodelElement(information); } - + /** * * Gets general information, for example ordering and manufacturer information. @@ -159,19 +168,21 @@ public void setGeneralInformation(GeneralInformation information) { public GeneralInformation getGeneralInformation() { return GeneralInformation.createAsFacade((Map) getSubmodelElement(GENERALINFORMATIONID)); } - + /** - * Sets product classifications by association of product classes with common classification systems. + * Sets product classifications by association of product classes with common + * classification systems. * * @param classifications */ public void setProductClassifications(ProductClassifications classifications) { addSubmodelElement(classifications); } - + /** * - * Gets product classifications by association of product classes with common classification systems. + * Gets product classifications by association of product classes with common + * classification systems. * * @return */ @@ -179,19 +190,21 @@ public void setProductClassifications(ProductClassifications classifications) { public ProductClassifications getProductClassifications() { return ProductClassifications.createAsFacade((Map) getSubmodelElement(PRODUCTCLASSIFICATIONSID)); } - + /** - * Sets technical and product properties. Individual characteristics that describe the product and its technical properties. + * Sets technical and product properties. Individual characteristics that + * describe the product and its technical properties. * * @param properties */ public void setTechnicalProperties(TechnicalProperties properties) { addSubmodelElement(properties); } - + /** * - * Gets technical and product properties. Individual characteristics that describe the product and its technical properties. + * Gets technical and product properties. Individual characteristics that + * describe the product and its technical properties. * * @return */ @@ -199,19 +212,21 @@ public void setTechnicalProperties(TechnicalProperties properties) { public TechnicalProperties getTechnicalProperties() { return TechnicalProperties.createAsFacade((Map) getSubmodelElement(TECHNICALPROPERTIESID)); } - + /** - * Sets further information on the product, the validity of the information provided and this data record. + * Sets further information on the product, the validity of the information + * provided and this data record. * * @param information */ public void setFurtherInformation(FurtherInformation information) { addSubmodelElement(information); } - + /** * - * Gets further information on the product, the validity of the information provided and this data record. + * Gets further information on the product, the validity of the information + * provided and this data record. * * @return */ diff --git a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java index 7b355cad..f4f159c4 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/furtherinformation/FurtherInformation.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.furtherinformation; @@ -34,8 +49,9 @@ import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper; /** - * FurtherInformation as described in the Submodel Template AAS Technical Data Document - * It contains Further information on the product, the validity of the information provided and this data record. + * FurtherInformation as described in the Submodel Template AAS Technical Data + * Document It contains Further information on the product, the validity of the + * information provided and this data record. * * @author haque * @@ -45,26 +61,28 @@ public class FurtherInformation extends SubmodelElementCollection { public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/FurtherInformation/1/1", KeyType.IRI)); public static final String TEXTSTATEMENTPREFIX = "TextStatement"; public static final String VALIDDATEID = "ValidDate"; - + private FurtherInformation() { } - + /** * Constructor with default idShort + * * @param validDate */ public FurtherInformation(Property validDate) { this(IDSHORT, validDate); } - + /** * Constructor with default idShort + * * @param validDate */ public FurtherInformation(XMLGregorianCalendar validDate) { this(IDSHORT, validDate); } - + /** * Constructor with mandatory attributes * @@ -77,7 +95,7 @@ public FurtherInformation(String idShort, Property validDate) { setValidDate(validDate); setTextStatements(new ArrayList()); } - + /** * Constructor with mandatory attributes * @@ -90,46 +108,50 @@ public FurtherInformation(String idShort, XMLGregorianCalendar validDate) { setValidDate(validDate); setTextStatements(new ArrayList()); } - + /** * Creates a FurtherInformation SMC object from a map * - * @param obj a FurtherInformation SMC object as raw map - * @return a FurtherInformation SMC object, that behaves like a facade for the given map + * @param obj + * a FurtherInformation SMC object as raw map + * @return a FurtherInformation SMC object, that behaves like a facade for the + * given map */ public static FurtherInformation createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(FurtherInformation.class, obj); } - + FurtherInformation furtherInformation = new FurtherInformation(); furtherInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return furtherInformation; } - + /** * Creates a FurtherInformation SMC object from a map without validation * - * @param obj a FurtherInformation SMC object as raw map - * @return a FurtherInformation SMC object, that behaves like a facade for the given map + * @param obj + * a FurtherInformation SMC object as raw map + * @return a FurtherInformation SMC object, that behaves like a facade for the + * given map */ private static FurtherInformation createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + FurtherInformation furtherInformation = new FurtherInformation(); furtherInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return furtherInformation; } - + /** - * Check whether all mandatory elements for FurtherInformation SMC - * exist in the map + * Check whether all mandatory elements for FurtherInformation SMC exist in the + * map * * @param obj * @@ -138,15 +160,13 @@ private static FurtherInformation createAsFacadeNonStrict(Map ob @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { FurtherInformation furtherInformation = createAsFacadeNonStrict(obj); - - return SubmodelElementCollection.isValid(obj) - && Property.isValid((Map) furtherInformation.getValidDate()); + + return SubmodelElementCollection.isValid(obj) && Property.isValid((Map) furtherInformation.getValidDate()); } - + /** - * Sets statement by the manufacturer in text form, - * e.g. scope of validity of the statements, scopes of application, - * conditions of operation. + * Sets statement by the manufacturer in text form, e.g. scope of validity of + * the statements, scopes of application, conditions of operation. * * Note: Whenever possible, a multi-language definition is preferred. * @@ -154,16 +174,15 @@ public static boolean isValid(Map obj) { */ public void setTextStatements(List statements) { if (statements != null && statements.size() > 0) { - for (MultiLanguageProperty statement: statements) { + for (MultiLanguageProperty statement : statements) { addSubmodelElement(statement); } } } - + /** - * Gets statement by the manufacturer in text form, - * e.g. scope of validity of the statements, scopes of application, - * conditions of operation. + * Gets statement by the manufacturer in text form, e.g. scope of validity of + * the statements, scopes of application, conditions of operation. * * Note: Whenever possible, a multi-language definition is preferred. * @@ -173,32 +192,34 @@ public void setTextStatements(List statements) { public List getStatements() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(TEXTSTATEMENTPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(MultiLanguageProperty.createAsFacade((Map) element)); } return ret; } - + /** - * Sets a date on which the data specified in the Submodel was valid from for the associated asset. + * Sets a date on which the data specified in the Submodel was valid from for + * the associated asset. * - * Note: Often this date will be the date of the last update of the - * corresponding data, that are the source for the technical properties - * section in the master data system. + * Note: Often this date will be the date of the last update of the + * corresponding data, that are the source for the technical properties section + * in the master data system. * * @param validDate */ public void setValidDate(Property validDate) { addSubmodelElement(validDate); } - + /** - * Sets a date on which the data specified in the Submodel was valid from for the associated asset. + * Sets a date on which the data specified in the Submodel was valid from for + * the associated asset. * - * Note: Often this date will be the date of the last update of the - * corresponding data, that are the source for the technical properties - * section in the master data system. + * Note: Often this date will be the date of the last update of the + * corresponding data, that are the source for the technical properties section + * in the master data system. * * @param validDate */ @@ -208,13 +229,14 @@ public void setValidDate(XMLGregorianCalendar validDate) { validDateProp.setValue(validDate); setValidDate(validDateProp); } - + /** - * Gets a date on which the data specified in the Submodel was valid from for the associated asset. + * Gets a date on which the data specified in the Submodel was valid from for + * the associated asset. * - * Note: Often this date will be the date of the last update of the - * corresponding data, that are the source for the technical properties - * section in the master data system. + * Note: Often this date will be the date of the last update of the + * corresponding data, that are the source for the technical properties section + * in the master data system. * * @return */ diff --git a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java index 27d72831..debc8b20 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/generalinformation/GeneralInformation.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.generalinformation; @@ -36,14 +51,16 @@ import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper; /** - * GeneralInformation as described in the Submodel Template AAS Technical Data Document + * GeneralInformation as described in the Submodel Template AAS Technical Data + * Document * - * It is a submodel element collection which contains General information, for example ordering and manufacturer information. + * It is a submodel element collection which contains General information, for + * example ordering and manufacturer information. * * @author haque * */ -public class GeneralInformation extends SubmodelElementCollection{ +public class GeneralInformation extends SubmodelElementCollection { public static final String IDSHORT = "GeneralInformation"; public static final String MANUFACTURERNAMEID = "ManufacturerName"; public static final String MANUFACTURERLOGOID = "ManufacturerLogo"; @@ -52,7 +69,7 @@ public class GeneralInformation extends SubmodelElementCollection{ public static final String MANUFACTURERORDERCODEID = "ManufacturerOrderCode"; public static final String PRODUCTIMAGEPREFIX = "ProductImage"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/GeneralInformation/1/1", KeyType.IRI)); - + private GeneralInformation() { } @@ -67,7 +84,7 @@ private GeneralInformation() { public GeneralInformation(Property manufacturerName, MultiLanguageProperty manufacturerProductDesignation, Property manufacturerPartNumber, Property manufacturerOrderCode) { this(IDSHORT, manufacturerName, manufacturerProductDesignation, manufacturerPartNumber, manufacturerOrderCode); } - + /** * Constructor with default idShort * @@ -79,7 +96,7 @@ public GeneralInformation(Property manufacturerName, MultiLanguageProperty manuf public GeneralInformation(String manufacturerName, LangString manufacturerProductDesignation, String manufacturerPartNumber, String manufacturerOrderCode) { this(IDSHORT, manufacturerName, manufacturerProductDesignation, manufacturerPartNumber, manufacturerOrderCode); } - + /** * Constructor with mandatory attributes * @@ -97,7 +114,7 @@ public GeneralInformation(String idShort, Property manufacturerName, MultiLangua setManufacturerPartNumber(manufacturerPartNumber); setManufacturerOrderCode(manufacturerOrderCode); } - + /** * Constructor with mandatory attributes * @@ -115,46 +132,50 @@ public GeneralInformation(String idShort, String manufacturerName, LangString ma setManufacturerPartNumber(manufacturerPartNumber); setManufacturerOrderCode(manufacturerOrderCode); } - + /** * Creates a GeneralInformation SMC object from a map * - * @param obj a GeneralInformation SMC object as raw map - * @return a GeneralInformation SMC object, that behaves like a facade for the given map + * @param obj + * a GeneralInformation SMC object as raw map + * @return a GeneralInformation SMC object, that behaves like a facade for the + * given map */ public static GeneralInformation createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(GeneralInformation.class, obj); } - + GeneralInformation generalInformation = new GeneralInformation(); generalInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return generalInformation; } - + /** * Creates a GeneralInformation SMC object from a map without validation * - * @param obj a GeneralInformation SMC object as raw map - * @return a GeneralInformation SMC object, that behaves like a facade for the given map + * @param obj + * a GeneralInformation SMC object as raw map + * @return a GeneralInformation SMC object, that behaves like a facade for the + * given map */ private static GeneralInformation createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + GeneralInformation generalInformation = new GeneralInformation(); generalInformation.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return generalInformation; } - + /** - * Check whether all mandatory elements for GeneralInformation SMC - * exist in the map + * Check whether all mandatory elements for GeneralInformation SMC exist in the + * map * * @param obj * @@ -163,24 +184,26 @@ private static GeneralInformation createAsFacadeNonStrict(Map ob @SuppressWarnings("unchecked") public static boolean isValid(Map obj) { GeneralInformation generalInformation = createAsFacadeNonStrict(obj); - return SubmodelElementCollection.isValid(obj) - && Property.isValid((Map) generalInformation.getManufacturerName()) - && MultiLanguageProperty.isValid((Map) generalInformation.getManufacturerProductDesignation()) - && Property.isValid((Map) generalInformation.getManufacturerPartNumber()) + return SubmodelElementCollection.isValid(obj) && Property.isValid((Map) generalInformation.getManufacturerName()) + && MultiLanguageProperty.isValid((Map) generalInformation.getManufacturerProductDesignation()) && Property.isValid((Map) generalInformation.getManufacturerPartNumber()) && Property.isValid((Map) generalInformation.getManufacturerOrderCode()); } - + /** - * Sets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market. + * Sets legally valid designation of the natural or judicial body which is + * directly responsible for the design, production, packaging and labeling of a + * product in respect to its being brought into the market. * * @param name */ public void setManufacturerName(Property name) { addSubmodelElement(name); } - + /** - * Sets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market. + * Sets legally valid designation of the natural or judicial body which is + * directly responsible for the design, production, packaging and labeling of a + * product in respect to its being brought into the market. * * @param name */ @@ -190,9 +213,11 @@ public void setManufacturerName(String name) { nameProp.setValue(name); setManufacturerName(nameProp); } - + /** - * Gets legally valid designation of the natural or judicial body which is directly responsible for the design, production, packaging and labeling of a product in respect to its being brought into the market. + * Gets legally valid designation of the natural or judicial body which is + * directly responsible for the design, production, packaging and labeling of a + * product in respect to its being brought into the market. * * @return */ @@ -200,18 +225,20 @@ public void setManufacturerName(String name) { public IProperty getManufacturerName() { return Property.createAsFacade((Map) getSubmodelElement(MANUFACTURERNAMEID)); } - + /** - * Sets imagefile for logo of manufacturer provided in common format (.png, .jpg). + * Sets imagefile for logo of manufacturer provided in common format (.png, + * .jpg). * * @param logo */ public void setManufacturerLogo(File logo) { addSubmodelElement(logo); } - + /** - * Gets imagefile for logo of manufacturer provided in common format (.png, .jpg). + * Gets imagefile for logo of manufacturer provided in common format (.png, + * .jpg). * * @return */ @@ -219,24 +246,28 @@ public void setManufacturerLogo(File logo) { public IFile getManufacturerLogo() { return File.createAsFacade((Map) getSubmodelElement(MANUFACTURERLOGOID)); } - + /** - * Sets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language. + * Sets product designation as given by the mnaufacturer. Short description of + * the product, product group or function (short text) in common language. * * Note: Whenever possible, a multi-language definition is preferred. * - * @param designation {@link MultiLanguageProperty} + * @param designation + * {@link MultiLanguageProperty} */ public void setManufacturerProductDesignation(MultiLanguageProperty designation) { addSubmodelElement(designation); } - + /** - * Sets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language. + * Sets product designation as given by the mnaufacturer. Short description of + * the product, product group or function (short text) in common language. * * Note: Whenever possible, a multi-language definition is preferred. * - * @param designation {@link LangString} + * @param designation + * {@link LangString} */ public void setManufacturerProductDesignation(LangString designation) { MultiLanguageProperty designationProp = new MultiLanguageProperty(MANUFACTURERPRODUCTDESIGNATIONID); @@ -244,32 +275,40 @@ public void setManufacturerProductDesignation(LangString designation) { designationProp.setValue(new LangStrings(designation)); setManufacturerProductDesignation(designationProp); } - + /** - * Gets product designation as given by the mnaufacturer. Short description of the product, product group or function (short text) in common language. + * Gets product designation as given by the mnaufacturer. Short description of + * the product, product group or function (short text) in common language. * * Note: Whenever possible, a multi-language definition is preferred. + * * @return */ @SuppressWarnings("unchecked") public IMultiLanguageProperty getManufacturerProductDesignation() { return MultiLanguageProperty.createAsFacade((Map) getSubmodelElement(MANUFACTURERPRODUCTDESIGNATIONID)); } - + /** - * Sets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt. + * Sets unique product identifier of the manufacturer for the product type + * respective the type designation of the industrial equipemnt. + * + * Note: The Manufacturer part number is represented as a string, although often + * a numerical id. * - * Note: The Manufacturer part number is represented as a string, although often a numerical id. * @param partNumber */ public void setManufacturerPartNumber(Property partNumber) { addSubmodelElement(partNumber); } - + /** - * Sets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt. + * Sets unique product identifier of the manufacturer for the product type + * respective the type designation of the industrial equipemnt. + * + * Note: The Manufacturer part number is represented as a string, although often + * a numerical id. * - * Note: The Manufacturer part number is represented as a string, although often a numerical id. * @param partNumber */ public void setManufacturerPartNumber(String partNumber) { @@ -278,29 +317,34 @@ public void setManufacturerPartNumber(String partNumber) { partNumberProp.setValue(partNumber); setManufacturerPartNumber(partNumberProp); } - + /** - * Gets unique product identifier of the manufacturer for the product type respective the type designation of the industrial equipemnt. + * Gets unique product identifier of the manufacturer for the product type + * respective the type designation of the industrial equipemnt. + * + * Note: The Manufacturer part number is represented as a string, although often + * a numerical id. * - * Note: The Manufacturer part number is represented as a string, although often a numerical id. * @return */ @SuppressWarnings("unchecked") public IProperty getManufacturerPartNumber() { return Property.createAsFacade((Map) getSubmodelElement(MANUFACTURERPARTNUMBERID)); } - + /** - * Sets unique product identifier of the manufacturer sufficient to order the exact same product. + * Sets unique product identifier of the manufacturer sufficient to order the + * exact same product. * * @param orderCode */ public void setManufacturerOrderCode(Property orderCode) { addSubmodelElement(orderCode); } - + /** - * Sets unique product identifier of the manufacturer sufficient to order the exact same product. + * Sets unique product identifier of the manufacturer sufficient to order the + * exact same product. * * @param orderCode */ @@ -310,9 +354,10 @@ public void setManufacturerOrderCode(String orderCode) { orderCodeProp.setValue(orderCode); setManufacturerOrderCode(orderCodeProp); } - + /** - * Gets unique product identifier of the manufacturer sufficient to order the exact same product. + * Gets unique product identifier of the manufacturer sufficient to order the + * exact same product. * * @return */ @@ -320,9 +365,10 @@ public void setManufacturerOrderCode(String orderCode) { public IProperty getManufacturerOrderCode() { return Property.createAsFacade((Map) getSubmodelElement(MANUFACTURERORDERCODEID)); } - + /** - * Sets image file for associated product provided in common format (.png, .jpg). + * Sets image file for associated product provided in common format (.png, + * .jpg). * * @param images */ @@ -333,9 +379,10 @@ public void setProductImages(List images) { } } } - + /** - * Gets image file for associated product provided in common format (.png, .jpg). + * Gets image file for associated product provided in common format (.png, + * .jpg). * * @return */ @@ -343,8 +390,8 @@ public void setProductImages(List images) { public List getProductImages() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PRODUCTIMAGEPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(File.createAsFacade((Map) element)); } return ret; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java index 1638a378..1adf1455 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassificationItem.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications; @@ -26,10 +41,11 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; /** - * ProductClassificationItem as described in the Submodel Template AAS Technical Data Document + * ProductClassificationItem as described in the Submodel Template AAS Technical + * Data Document * - * It is a submodel element collection which contains Single product - * classification by association with product class in a particular + * It is a submodel element collection which contains Single product + * classification by association with product class in a particular * classification system or property dictionary. * * @author haque @@ -40,10 +56,10 @@ public class ProductClassificationItem extends SubmodelElementCollection { public static final String CLASSIFICATIONSYSTEMVERSIONID = "ClassificationSystemVersion"; public static final String PRODUCTCLASSID = "ProductClassId"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassificationItem/1/1", KeyType.IRI)); - + private ProductClassificationItem() { } - + /** * Constructor with mandatory attributes * @@ -57,7 +73,7 @@ public ProductClassificationItem(String idShort, Property productClassificationS setProductClassificationSystem(productClassificationSystem); setProductClassId(productClassId); } - + /** * Constructor with mandatory attributes * @@ -71,43 +87,47 @@ public ProductClassificationItem(String idShort, String productClassificationSys setProductClassificationSystem(productClassificationSystem); setProductClassId(productClassId); } - + /** * Creates a ProductClassificationItem SMC object from a map * - * @param obj a ProductClassificationItem SMC object as raw map - * @return a ProductClassificationItem SMC object, that behaves like a facade for the given map + * @param obj + * a ProductClassificationItem SMC object as raw map + * @return a ProductClassificationItem SMC object, that behaves like a facade + * for the given map */ public static ProductClassificationItem createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(ProductClassificationItem.class, obj); } - + ProductClassificationItem productClassificationItem = new ProductClassificationItem(); productClassificationItem.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return productClassificationItem; } - + /** * Creates a ProductClassificationItem SMC object from a map without validation * - * @param obj a ProductClassificationItem SMC object as raw map - * @return a ProductClassificationItem SMC object, that behaves like a facade for the given map + * @param obj + * a ProductClassificationItem SMC object as raw map + * @return a ProductClassificationItem SMC object, that behaves like a facade + * for the given map */ private static ProductClassificationItem createAsFacadeNonStrict(Map obj) { if (obj == null) { return null; } - + ProductClassificationItem productClassificationItem = new ProductClassificationItem(); productClassificationItem.setMap(SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return productClassificationItem; } - + /** * Check whether all mandatory elements for ProdictClassificationSystem SMC * exist in the map @@ -119,25 +139,28 @@ private static ProductClassificationItem createAsFacadeNonStrict(Map obj) { ProductClassificationItem productClassificationItem = createAsFacadeNonStrict(obj); - return SubmodelElementCollection.isValid(obj) - && Property.isValid((Map) productClassificationItem.getProductClassificationSystem()) + return SubmodelElementCollection.isValid(obj) && Property.isValid((Map) productClassificationItem.getProductClassificationSystem()) && Property.isValid((Map) productClassificationItem.getProductClassId()); } - + /** * Sets common name of the classification system. * - * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD". + * Note: Examples for common names for classification systems are "ECLASS" or + * "IEC CDD". + * * @param system */ public void setProductClassificationSystem(Property system) { addSubmodelElement(system); } - + /** * Sets common name of the classification system. * - * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD". + * Note: Examples for common names for classification systems are "ECLASS" or + * "IEC CDD". + * * @param system */ public void setProductClassificationSystem(String system) { @@ -146,32 +169,38 @@ public void setProductClassificationSystem(String system) { productClassificationSystemProp.setValue(system); setProductClassificationSystem(productClassificationSystemProp); } - + /** * Gets common name of the classification system. * - * Note: Examples for common names for classification systems are "ECLASS" or "IEC CDD". + * Note: Examples for common names for classification systems are "ECLASS" or + * "IEC CDD". + * * @return */ @SuppressWarnings("unchecked") public IProperty getProductClassificationSystem() { return Property.createAsFacade((Map) getSubmodelElement(PRODUCTCLASSIFICATIONSYSTEMID)); } - + /** - * Sets common version identifier of the used classification system, in order to distinguish different version of the property dictionary. + * Sets common version identifier of the used classification system, in order to + * distinguish different version of the property dictionary. * * Note: Casing is to be ignored. + * * @param version */ public void setClassificationSystemVersion(Property version) { addSubmodelElement(version); } - + /** - * Sets common version identifier of the used classification system, in order to distinguish different version of the property dictionary. + * Sets common version identifier of the used classification system, in order to + * distinguish different version of the property dictionary. * * Note: Casing is to be ignored. + * * @param version */ public void setClassificationSystemVersion(String version) { @@ -180,32 +209,40 @@ public void setClassificationSystemVersion(String version) { versionProp.setValue(version); setClassificationSystemVersion(versionProp); } - + /** - * Gets common version identifier of the used classification system, in order to distinguish different version of the property dictionary. + * Gets common version identifier of the used classification system, in order to + * distinguish different version of the property dictionary. * * Note: Casing is to be ignored. + * * @return */ @SuppressWarnings("unchecked") public IProperty getClassificationSystemVersion() { return Property.createAsFacade((Map) getSubmodelElement(CLASSIFICATIONSYSTEMVERSIONID)); } - + /** - * Sets class of the associated product or industrial equipment in the classification system. According to the notation of the system. + * Sets class of the associated product or industrial equipment in the + * classification system. According to the notation of the system. + * + * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the + * product class. * - * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class. * @param id */ public void setProductClassId(Property id) { addSubmodelElement(id); } - + /** - * Sets class of the associated product or industrial equipment in the classification system. According to the notation of the system. + * Sets class of the associated product or industrial equipment in the + * classification system. According to the notation of the system. + * + * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the + * product class. * - * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class. * @param id */ public void setProductClassId(String id) { @@ -214,11 +251,14 @@ public void setProductClassId(String id) { idProp.setValue(id); setProductClassId(idProp); } - + /** - * Gets class of the associated product or industrial equipment in the classification system. According to the notation of the system. + * Gets class of the associated product or industrial equipment in the + * classification system. According to the notation of the system. + * + * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the + * product class. * - * Note: Ideally, the Property/valueId is used to reference the IRI/ IRDI of the product class. * @return */ @SuppressWarnings("unchecked") diff --git a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java index 955c34a1..e693ff27 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/productclassifications/ProductClassifications.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.productclassifications; @@ -26,8 +41,10 @@ import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper; /** - * ProductClassifications as described in the Submodel Template AAS Technical Data Document - * It is a submodel element collection which contains Product classifications by association with product classes in common classification systems. + * ProductClassifications as described in the Submodel Template AAS Technical + * Data Document It is a submodel element collection which contains Product + * classifications by association with product classes in common classification + * systems. * * @author haque * @@ -36,14 +53,14 @@ public class ProductClassifications extends SubmodelElementCollection { public static final String IDSHORT = "ProductClassifications"; public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://admin-shell.io/ZVEI/TechnicalData/ProductClassifications/1/1", KeyType.IRI)); public static final String PRODUCTCLASSIFICATIONITEMPREFIX = "ProductClassificationItem"; - + /** * Constructor with default idshort */ public ProductClassifications() { this(IDSHORT); } - + /** * Constructor with mandatory attributes * @@ -53,30 +70,32 @@ public ProductClassifications(String idShort) { super(idShort); setProductClassificationItems(new ArrayList()); } - + /** * Creates a ProductClassifications SMC object from a map * - * @param obj a ProductClassifications SMC object as raw map - * @return a ProductClassifications SMC object, that behaves like a facade for the given map + * @param obj + * a ProductClassifications SMC object as raw map + * @return a ProductClassifications SMC object, that behaves like a facade for + * the given map */ public static ProductClassifications createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(ProductClassifications.class, obj); } - + ProductClassifications productClassifications = new ProductClassifications(); - productClassifications.setMap((Map)SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); + productClassifications.setMap((Map) SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return productClassifications; } - + /** - * Check whether all mandatory elements for ProductClassifications SMC - * exist in the map + * Check whether all mandatory elements for ProductClassifications SMC exist in + * the map * * @param obj * @@ -85,22 +104,24 @@ public static ProductClassifications createAsFacade(Map obj) { public static boolean isValid(Map obj) { return SubmodelElementCollection.isValid(obj); } - + /** - * Sets single product classification item by association with product class in a particular classification system or property dictionary + * Sets single product classification item by association with product class in + * a particular classification system or property dictionary * * @param items */ public void setProductClassificationItems(List items) { if (items != null && items.size() > 0) { - for (ProductClassificationItem item: items) { + for (ProductClassificationItem item : items) { addSubmodelElement(item); } } } - + /** - * Gets single product classification item by association with product class in a particular classification system or property dictionary + * Gets single product classification item by association with product class in + * a particular classification system or property dictionary * * @return */ @@ -108,8 +129,8 @@ public void setProductClassificationItems(List items) public List getProductClassificationItems() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(PRODUCTCLASSIFICATIONITEMPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(ProductClassificationItem.createAsFacade((Map) element)); } return ret; diff --git a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java index c891ad76..186f2ca8 100644 --- a/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java +++ b/src/main/java/org/eclipse/basyx/submodel/types/technicaldata/submodelelementcollections/technicalproperties/TechnicalProperties.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.submodel.types.technicaldata.submodelelementcollections.technicalproperties; @@ -29,9 +44,12 @@ import org.eclipse.basyx.submodel.types.helper.SubmodelElementRetrievalHelper; /** - * TechnicalProperties as described in the Submodel Template AAS Technical Data Document + * TechnicalProperties as described in the Submodel Template AAS Technical Data + * Document * - * It is a submodel element collection which contains Individual characteristics that describe the product (industrial equipment) and its technical properties. + * It is a submodel element collection which contains Individual characteristics + * that describe the product (industrial equipment) and its technical + * properties. * * @author haque * @@ -51,38 +69,41 @@ public class TechnicalProperties extends SubmodelElementCollection { public TechnicalProperties() { this(IDSHORT); } - + /** * Constructor with mandatory attributes + * * @param idShort */ public TechnicalProperties(String idShort) { super(idShort); } - + /** * Creates a TechnicalProperties SMC object from a map * - * @param obj a TechnicalProperties SMC object as raw map - * @return a TechnicalProperties SMC object, that behaves like a facade for the given map + * @param obj + * a TechnicalProperties SMC object as raw map + * @return a TechnicalProperties SMC object, that behaves like a facade for the + * given map */ public static TechnicalProperties createAsFacade(Map obj) { if (obj == null) { return null; } - + if (!isValid(obj)) { throw new MetamodelConstructionException(TechnicalProperties.class, obj); } - + TechnicalProperties technicalProperties = new TechnicalProperties(); - technicalProperties.setMap((Map)SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); + technicalProperties.setMap((Map) SubmodelElementMapCollectionConverter.mapToSmECollection(obj)); return technicalProperties; } - + /** - * Check whether all mandatory elements for TechnicalProperties SMC - * exist in the map + * Check whether all mandatory elements for TechnicalProperties SMC exist in the + * map * * @param obj * @@ -91,96 +112,103 @@ public static TechnicalProperties createAsFacade(Map obj) { public static boolean isValid(Map obj) { return SubmodelElementCollection.isValid(obj); } - + /** * Sets arbitrary semanticId but defined in a classification system * - * Arbitrary SubmodelElement with semanticId possibly referring to a ConceptDescription can be used within the Technical Properties. + * Arbitrary SubmodelElement with semanticId possibly referring to a + * ConceptDescription can be used within the Technical Properties. * * @param elements */ public void setArbitrary(List elements) { if (elements != null && elements.size() > 0) { - for (SubmodelElement elem: elements) { - addSubmodelElement(elem); + for (SubmodelElement elem : elements) { + addSubmodelElement(elem); } } } - + /** * Gets arbitrary semanticId but defined in a classification system * - * Arbitrary SubmodelElement with semanticId possibly referring to a ConceptDescription can be used within the Technical Properties. + * Arbitrary SubmodelElement with semanticId possibly referring to a + * ConceptDescription can be used within the Technical Properties. * * @return */ public List getArbitrary() { - return getSubmodelElements() - .values().stream() - .filter(x -> { - String id = x.getSemanticId().getKeys().get(0).getValue(); - if (id.equals(MAINSECTIONID) || id.equals(SUBSECTIONID) || id.equals(SMENOTDESCRIBEDID)) { - return false; - } else { - return true; - } - }) - .collect(Collectors.toList()); + return getSubmodelElements().values().stream().filter(x -> { + String id = x.getSemanticId().getKeys().get(0).getValue(); + if (id.equals(MAINSECTIONID) || id.equals(SUBSECTIONID) || id.equals(SMENOTDESCRIBEDID)) { + return false; + } else { + return true; + } + }).collect(Collectors.toList()); } - + /** * Set arbitrary * - * Represents a SubmodelElement that is not described using a common classification system, a consortium specification, an open community standard, a published manufacturer specification or such. + * Represents a SubmodelElement that is not described using a common + * classification system, a consortium specification, an open community + * standard, a published manufacturer specification or such. + * + * Note: The idShort of the SubmodelElement can be named accordingly. + * Constraints concerning the usable characters for idShort shall be respected. + * Note: Only perceivable by human understanding. Note: The special case of SME + * being a SMC is accepted, will be rendered as MainSection/ SubSection + * accordingly. * - * Note: The idShort of the SubmodelElement can be named accordingly. Constraints concerning the usable characters for idShort shall be respected. - * Note: Only perceivable by human understanding. - * Note: The special case of SME being a SMC is accepted, will be rendered as MainSection/ SubSection accordingly. * @param elements */ public void setSMENotDescribedBySemanticId(List elements) { if (elements != null && elements.size() > 0) { - for (SubmodelElement elem: elements) { - addSubmodelElement(elem); + for (SubmodelElement elem : elements) { + addSubmodelElement(elem); } } } - + /** - * Get arbitrary - * Represents a SubmodelElement that is not described using a common classification system, a consortium specification, an open community standard, a published manufacturer specification or such. + * Get arbitrary Represents a SubmodelElement that is not described using a + * common classification system, a consortium specification, an open community + * standard, a published manufacturer specification or such. + * + * Note: The idShort of the SubmodelElement can be named accordingly. + * Constraints concerning the usable characters for idShort shall be respected. + * Note: Only perceivable by human understanding. Note: The special case of SME + * being a SMC is accepted, will be rendered as MainSection/ SubSection + * accordingly. * - * Note: The idShort of the SubmodelElement can be named accordingly. Constraints concerning the usable characters for idShort shall be respected. - * Note: Only perceivable by human understanding. - * Note: The special case of SME being a SMC is accepted, will be rendered as MainSection/ SubSection accordingly. * @return */ public List getSMENotDescribedBySemanticId() { - return getSubmodelElements() - .values().stream() - .filter(x -> x.getSemanticId().getKeys().get(0).getValue() - .equals(SMENOTDESCRIBEDID)) - .collect(Collectors.toList()); + return getSubmodelElements().values().stream().filter(x -> x.getSemanticId().getKeys().get(0).getValue().equals(SMENOTDESCRIBEDID)).collect(Collectors.toList()); } - + /** * Sets main subdivision possibility for properties. * - * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection. + * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, + * SemanticIdNotAvailable, SubSection. + * * @param mainSections */ public void setMainSections(List mainSections) { if (mainSections != null && mainSections.size() > 0) { - for (SubmodelElementCollection section: mainSections) { - addSubmodelElement(section); + for (SubmodelElementCollection section : mainSections) { + addSubmodelElement(section); } } } - + /** * Gets main subdivision possibility for properties. * - * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection. + * Note: Each Main Section SMC may contain arbitray sets of SubmodelElements, + * SemanticIdNotAvailable, SubSection. * * @return */ @@ -188,31 +216,34 @@ public void setMainSections(List mainSections) { public List getMainSections() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(MAINSECTIONPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(SubmodelElementCollection.createAsFacade((Map) element)); } return ret; } - + /** * Sets subordinate subdivision possibility for properties. * - * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection. + * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, + * SemanticIdNotAvailable, SubSection. + * * @param subSections */ public void setSubSections(List subSections) { if (subSections != null && subSections.size() > 0) { - for (SubmodelElementCollection section: subSections) { - addSubmodelElement(section); + for (SubmodelElementCollection section : subSections) { + addSubmodelElement(section); } } } - + /** * Gets subordinate subdivision possibility for properties. * - * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, SemanticIdNotAvailable, SubSection. + * Note: Each Sub Section SMC may contain arbitray sets of SubmodelElements, + * SemanticIdNotAvailable, SubSection. * * @return */ @@ -220,8 +251,8 @@ public void setSubSections(List subSections) { public List getSubSections() { List ret = new ArrayList(); List elements = SubmodelElementRetrievalHelper.getSubmodelElementsByIdPrefix(SUBSECTIONPREFIX, getSubmodelElements()); - - for (ISubmodelElement element: elements) { + + for (ISubmodelElement element : elements) { ret.add(SubmodelElementCollection.createAsFacade((Map) element)); } return ret; diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java b/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java index 6fc5eaa1..a2b4bfe6 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/connector/JSONConnector.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.connector; @@ -25,7 +40,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Connector Class responsible for serializing parameters and de-serializing * results. It verifies the results, removes the message header and returns the @@ -38,26 +52,22 @@ public class JSONConnector implements IModelProvider { private static final Logger LOGGER_DEFAULT = LoggerFactory.getLogger(JSONConnector.class); private static final Logger LOGGER_COMMUNICATION = LoggerFactory.getLogger(LOGGER_DEFAULT.getName() + ".MALFORMED"); - - + /** * Reference to Connector backend */ protected IBaSyxConnector provider = null; - - + /** * Reference to serializer / deserializer */ protected GSONTools serializer = null; - - + /** * Handle meta protocol in JSON String - * */ + */ protected IMetaProtocolHandler metaProtocolHandler = null; - - + /** * Constructor * @@ -66,15 +76,14 @@ public class JSONConnector implements IModelProvider { public JSONConnector(IBaSyxConnector provider) { // Store provider backend this.provider = provider; - + // Create the meta protocal handler this.metaProtocolHandler = new MetaprotocolHandler(); - + // Create GSON serializer serializer = new GSONTools(new DefaultTypeFactory()); } - /** * Constructor that accepts specific factory for serializer * @@ -83,13 +92,11 @@ public JSONConnector(IBaSyxConnector provider) { public JSONConnector(IBaSyxConnector provider, GSONToolsFactory factory) { // Store provider backend this.provider = provider; - + // Create GSON serializer serializer = new GSONTools(factory); } - - @Override public Object getValue(String path) throws ProviderException { VABPathTools.checkPathForNull(path); @@ -127,7 +134,7 @@ public void setValue(String path, Object newValue) throws ProviderException { @Override public void createValue(String path, Object newEntity) throws ProviderException { VABPathTools.checkPathForNull(path); - + // Serialize value Object String jsonString = serializer.serialize(newEntity); diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java index 634c4b52..5b7645ad 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/IMetaProtocolHandler.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.metaprotocol; @@ -18,14 +33,14 @@ */ public interface IMetaProtocolHandler { - + /** - * Deserialize the returned JSON String, handle meta-information of the protocol and return response object + * Deserialize the returned JSON String, handle meta-information of the protocol + * and return response object * - * @param message - * serialized JSON String - * @return - * response object with handled meta-information + * @param message + * serialized JSON String + * @return response object with handled meta-information */ public Object deserialize(String message) throws ProviderException; diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java index a11de573..50c6e58f 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Message.java @@ -1,15 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.metaprotocol; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; /** * @@ -17,8 +33,8 @@ * */ @SuppressWarnings("serial") -public class Message extends HashMap { - +public class Message extends LinkedHashMap { + public static final String MESSAGETYPE = "messageType"; public static final String CODE = "code"; public static final String TEXT = "text"; @@ -26,16 +42,24 @@ public class Message extends HashMap { public Message(MessageType messageType, String text) { this(messageType, null, text); } - + public Message(MessageType messageType, String code, String text) { put(MESSAGETYPE, messageType.getId()); put(CODE, code); put(TEXT, text); } + public static Message createAsFacade(Map map) { + MessageType type = MessageType.getById(((Number) map.get(MESSAGETYPE)).intValue()); + String code = (String) map.get(CODE); + String text = (String) map.get(TEXT); + return new Message(type, code, text); + } + public String getText() { return (String) get(TEXT); } + public String getCode() { return (String) get(CODE); } @@ -43,7 +67,7 @@ public String getCode() { public MessageType getMessageType() { return MessageType.getById((int) get(MESSAGETYPE)); } - + @Override public String toString() { String code = getCode(); diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java index fe6cce7f..04ef555b 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MessageType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.metaprotocol; @@ -15,30 +30,24 @@ * */ public enum MessageType { - - Unspecified(0), - Debug(1), - Information(2), - Warning(3), - Error(4), - Fatal(5), - Exception(6), - Unknown(-1); - - private int id; - - MessageType(int id) { - this.id = id; + + Unspecified(0), Debug(1), Information(2), Warning(3), Error(4), Fatal(5), Exception(6), Unknown(-1); + + private int id; + + MessageType(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static MessageType getById(int id) { + for (MessageType t : values()) { + if (t.getId() == id) + return t; } - - public int getId() { - return id; - } - - public static MessageType getById(int id) { - for(MessageType t : values()) { - if(t.getId() == id) return t; - } - return Unknown; - } + return Unknown; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java index f80fb553..6cba9510 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/MetaprotocolHandler.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.metaprotocol; @@ -23,7 +38,7 @@ public class MetaprotocolHandler implements IMetaProtocolHandler { * Reference to serializer / deserializer */ protected GSONTools serializer = null; - + /** * Constructor that create the serializer * @@ -32,41 +47,40 @@ public MetaprotocolHandler() { // Create GSON serializer serializer = new GSONTools(new DefaultTypeFactory()); } - + /** * Constructor that accepts specific factory for serializer + * * @param factory */ public MetaprotocolHandler(GSONToolsFactory factory) { // Create GSON serializer serializer = new GSONTools(factory); } - - + @Override @SuppressWarnings("unchecked") public Object deserialize(String message) throws ProviderException { // First get the GSON object from the JSON string Object gsonObj = serializer.deserialize(message); - + // Then interpret and verify the result object Object result = null; // If it is a map, see if it does contain an exception if (gsonObj instanceof Map) { Map responseMap = (Map) gsonObj; - + // Handle meta information and exceptions result = handleResult(responseMap); } else { // Otherwise, return directly. result = gsonObj; } - return result; + return result; } - - + /** * Verify the Result and try to extract the entity if available. Process * information of "success", "entityType" and "messages" @@ -88,7 +102,7 @@ private Object handleResult(Map responseMap) throws ProviderExce if (messages == null) { throw new ProviderException("Unknown error occured: Success entry is indicating an error but no message was attached"); } - + Map first = messages.iterator().next(); // assumes an Exception always comes with a message // Get the code of the exception message @@ -99,19 +113,20 @@ private Object handleResult(Map responseMap) throws ProviderExce throw getExceptionFromCode(code, text); } - + /** * Creates a ProviderException from a String received form the Server
* The String has to be formated e.g. "ResourceNotFoundException: Requested Item * was not found" * - * @param code - code of the exception message + * @param code + * - code of the exception message * @return the matching ProviderException */ public static ProviderException getExceptionFromCode(String code, String text) { int exceptionCode = Integer.parseInt(code); - + // return exception based on code return ExceptionToHTTPCodeMapper.mapToException(exceptionCode, text); } diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java index 4fa9bc06..35fdae7e 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/metaprotocol/Result.java @@ -1,16 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.metaprotocol; +import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -25,7 +41,7 @@ * */ @SuppressWarnings("serial") -public class Result extends HashMap { +public class Result extends LinkedHashMap { public static final String SUCCESS = "success"; public static final String ISEXCEPTION = "isException"; @@ -79,28 +95,36 @@ public Result(Exception e) { this(false, getMessageListFromException(e)); } + @SuppressWarnings("unchecked") + public static Result createAsFacade(Map map) { + boolean success = (Boolean) map.get(SUCCESS); + Object entity = map.get(ENTITY); + List messages = new ArrayList<>(); + + for (Map messageMap : (List>) map.get(MESSAGES)) { + messages.add(Message.createAsFacade(messageMap)); + } + + return new Result(success, entity, messages); + } + private static List getMessageListFromException(Exception e) { List messageList = new LinkedList(); - // Translate the exception to code if (e instanceof ProviderException) { String code = new Integer(ExceptionToHTTPCodeMapper.mapFromException((ProviderException) e)).toString(); - Message message = new Message(MessageType.Exception, code, - e.getClass().getSimpleName() + ": " + e.getMessage()); + Message message = new Message(MessageType.Exception, code, e.getClass().getSimpleName() + ": " + e.getMessage()); // replace with desired debugging output messageList.add(message); } - - if (e.getCause() != null) { messageList.addAll(getMessageListFromException((Exception) e.getCause())); } - return messageList; } diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java b/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java index 52c47941..7e1c6125 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/provider/JSONProvider.java @@ -1,19 +1,37 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.provider; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.Collection; +import javax.servlet.ServletOutputStream; + import org.eclipse.basyx.vab.coder.json.metaprotocol.Result; import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory; import org.eclipse.basyx.vab.coder.json.serialization.GSONTools; @@ -25,8 +43,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - - /** * Provider class that supports JSON serialized communication
* Generic Caller is required since messages can be technology specific. @@ -36,78 +52,72 @@ * */ public class JSONProvider { - + private static Logger logger = LoggerFactory.getLogger(JSONProvider.class); - /** * Reference to IModelProvider backend */ protected ModelProvider providerBackend = null; - - + /** * Reference to serializer / deserializer */ protected GSONTools serializer = null; - - /** * Constructor */ public JSONProvider(ModelProvider modelProviderBackend) { // Store reference to backend providerBackend = modelProviderBackend; - + // Create GSON serializer serializer = new GSONTools(new DefaultTypeFactory()); } - /** * Constructor */ public JSONProvider(ModelProvider modelProviderBackend, GSONToolsFactory factory) { // Store reference to backend providerBackend = modelProviderBackend; - + // Create GSON serializer serializer = new GSONTools(factory); } - - + /** * Get serializer reference */ public GSONTools getSerializerReference() { return serializer; } - /** * Get backend reference */ public ModelProvider getBackendReference() { return providerBackend; - } - + } + /** - * Marks success as false and delivers exception cause messages + * Marks success as false and delivers exception cause messages + * * @param e * @return */ private String serialize(Exception e) { // Create Ack Result result = new Result(e); - + // Serialize the whole thing return serialize(result); } - - + /** - * Serialize IResult (HashMap) + * Serialize IResult (LinkedHashMap) + * * @param string * @return */ @@ -115,35 +125,34 @@ private String serialize(Result string) { // Serialize the whole thing return serializer.serialize(string); } - /** * Send Error + * * @param e * @param path * @param resp */ private void sendException(OutputStream resp, Exception e) throws ProviderException { - + // Serialize Exception String jsonString = serialize(e); try { resp.write(jsonString.getBytes(StandardCharsets.UTF_8)); - } catch(IOException innerE) { + } catch (IOException innerE) { throw new ProviderException("Failed to send Exception '" + e.getMessage() + "' to client", innerE); } - - //If the Exception is a ProviderException, just rethrow it - if(e instanceof ProviderException) { + + // If the Exception is a ProviderException, just rethrow it + if (e instanceof ProviderException) { throw (ProviderException) e; } - - //If the Exception is not a ProviderException encapsulate it in one and log it + + // If the Exception is not a ProviderException encapsulate it in one and log it logger.error("Unknown Exception in JSONProvider", e); throw new ProviderException(e); } - /** * Extracts parameter from JSON and handles de-serialization errors * @@ -151,8 +160,8 @@ private void sendException(OutputStream resp, Exception e) throws ProviderExcept * @param serializedJSONValue * @param outputStream * @return - * @throws MalformedRequestException - * @throws LostHTTPRequestParameterException + * @throws MalformedRequestException + * @throws LostHTTPRequestParameterException * @throws ProviderException */ private Object extractParameter(String path, String serializedJSONValue, OutputStream outputStream) throws MalformedRequestException { @@ -163,17 +172,17 @@ private Object extractParameter(String path, String serializedJSONValue, OutputS // Deserialize json body result = serializer.deserialize(serializedJSONValue); } catch (Exception e) { - //JSON could not be deserialized + // JSON could not be deserialized throw new MalformedRequestException(e); } - + return result; } - /** * Process a BaSys get operation, return JSON serialized result - * @throws ProviderException + * + * @throws ProviderException */ public void processBaSysGet(String path, OutputStream outputStream) throws ProviderException { @@ -191,20 +200,19 @@ public void processBaSysGet(String path, OutputStream outputStream) throws Provi } } - /** * Process a BaSys set operation * * @param path * @param serializedJSONValue * @param outputStream - * @throws ProviderException + * @throws ProviderException */ public void processBaSysSet(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException { - + // Try to set value of BaSys VAB element try { - + // Deserialize json body. If parameter is not ex Object parameter = extractParameter(path, serializedJSONValue, outputStream); @@ -219,19 +227,19 @@ public void processBaSysSet(String path, String serializedJSONValue, OutputStrea } } - /** * Process a BaSys invoke operation - * @throws ProviderException + * + * @throws ProviderException */ @SuppressWarnings("unchecked") public void processBaSysInvoke(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException { try { - - // Deserialize json body. + + // Deserialize json body. Object parameter = extractParameter(path, serializedJSONValue, outputStream); - + // If only a single parameter has been sent, pack it into an array so it can be // casted safely if (parameter instanceof Collection) { @@ -244,7 +252,7 @@ public void processBaSysInvoke(String path, String serializedJSONValue, OutputSt } parameter = parameterArray; } - + if (!(parameter instanceof Object[])) { Object[] parameterArray = new Object[1]; Object tmp = parameter; @@ -256,7 +264,7 @@ public void processBaSysInvoke(String path, String serializedJSONValue, OutputSt // Serialize result as json string String jsonString = serializer.serialize(result); - + // Send response outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8)); @@ -265,22 +273,24 @@ public void processBaSysInvoke(String path, String serializedJSONValue, OutputSt } } - /** * Implement "Delete" operation. Deletes any resource under the given path. * * @param path - * @param serializedJSONValue If this parameter is not null (basystype),we remove an element from a collection by index / remove from map by key. We assume that the parameter only contains 1 element + * @param serializedJSONValue + * If this parameter is not null (basystype),we remove an element + * from a collection by index / remove from map by key. We assume + * that the parameter only contains 1 element * @param outputStream - * @throws ProviderException + * @throws ProviderException */ public void processBaSysDelete(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException { - + try { // Deserialize json body. If parameter is not ex Object parameter = extractParameter(path, serializedJSONValue, outputStream); - + // Process delete request with or without argument if (parameter == null) { this.providerBackend.deleteValue(path); @@ -296,21 +306,19 @@ public void processBaSysDelete(String path, String serializedJSONValue, OutputSt } } - /** * Creates a resource under the given path * * @param path * @param serializedJSONValue * @param outputStream - * @throws ProviderException + * @throws ProviderException */ public void processBaSysCreate(String path, String serializedJSONValue, OutputStream outputStream) throws ProviderException { try { - // Deserialize json body. + // Deserialize json body. Object parameter = extractParameter(path, serializedJSONValue, outputStream); - providerBackend.createValue(path, parameter); @@ -320,4 +328,22 @@ public void processBaSysCreate(String path, String serializedJSONValue, OutputSt sendException(outputStream, e); } } + + /** + * Uploads a resource at given path + * + * @param path + * @param fileContent + * @param outputStream + */ + public void processBaSysUpload(String path, InputStream fileContent, ServletOutputStream outputStream) { + try { + providerBackend.createValue(path, fileContent); + + // Send response + outputStream.write("".getBytes(StandardCharsets.UTF_8)); + } catch (Exception e) { + sendException(outputStream, e); + } + } } diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java index 3066bf80..5408c9ee 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/DefaultTypeFactory.java @@ -1,21 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.serialization; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; - - /** * Default type factory * @@ -29,10 +42,9 @@ public class DefaultTypeFactory implements GSONToolsFactory { */ @Override public Map createMap() { - return new HashMap<>(); + return new LinkedHashMap<>(); } - /** * Create a collection */ diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java index 22f7fa0e..2011f889 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONTools.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.serialization; @@ -51,9 +66,9 @@ * */ public class GSONTools implements Serializer { - + private static Logger logger = LoggerFactory.getLogger(GSONTools.class); - + // Used string constants public static final String OPERATION = "operation"; public static final String LAMBDA = "lambda"; @@ -70,14 +85,14 @@ public class GSONTools implements Serializer { * Type factory */ protected GSONToolsFactory toolsFactory = null; - + /** * Flag to remove null values from serialized JSON */ private boolean removeNull = true; - + /** - * Flag to remove empty arrays from serialized JSON + * Flag to remove empty arrays from serialized JSON */ private boolean removeEmpty = false; @@ -88,7 +103,7 @@ public GSONTools(GSONToolsFactory factory) { // Store factory reference toolsFactory = factory; } - + /** * Constructor */ @@ -187,7 +202,7 @@ private Object deserializeJsonPrimitive(JsonPrimitive primitive) { return primitive.getAsDouble(); } else { // Get value as Big integer - BigInteger tmp= primitive.getAsBigInteger(); + BigInteger tmp = primitive.getAsBigInteger(); if (BigInteger.valueOf(Integer.MAX_VALUE).compareTo(tmp) >= 0 && BigInteger.valueOf(Integer.MIN_VALUE).compareTo(tmp) <= 0) { // convert to int return primitive.getAsInt(); @@ -207,7 +222,6 @@ private Object deserializeJsonPrimitive(JsonPrimitive primitive) { } } - /** * Serializes either string, number or boolean to a JsonPrimitive * @@ -271,18 +285,18 @@ private JsonObject serializeMap(Map map) { for (Entry entry : map.entrySet()) { Object value = entry.getValue(); // Remove empty list if removeEmpty flag is on - if (!removeEmpty || !(value instanceof Collection && ((Collection)value).isEmpty())) { - obj.add(entry.getKey(), serializeObject(value)); - } + if (!removeEmpty || !(value instanceof Collection && ((Collection) value).isEmpty())) { + obj.add(entry.getKey(), serializeObject(value)); + } } return obj; } /** * Deserializes a JsonArray to a Collection
- * Remark: internally, a List will be used for deserialization & it is assumed, that - * the order in the json equals the correct intended order for the list. - * => The ordering will be preserved in the returned collection + * Remark: internally, a List will be used for deserialization & it is assumed, + * that the order in the json equals the correct intended order for the list. => + * The ordering will be preserved in the returned collection * * @param array * @return @@ -302,10 +316,7 @@ private Collection deserializeJsonArray(JsonArray array) { * @return */ private boolean isFunction(Object value) { - return (value instanceof Supplier) - || (value instanceof Function) - || (value instanceof Consumer) - || (value instanceof BiConsumer); + return (value instanceof Supplier) || (value instanceof Function) || (value instanceof Consumer) || (value instanceof BiConsumer || (value instanceof Runnable)); } /** @@ -341,7 +352,7 @@ protected Object deserializeObjectFromString(String s) { Object result = null; byte[] data = Base64.getDecoder().decode(s); InputStream byteStream = new ByteArrayInputStream(data); - + try (ObjectInputStream stream = new ObjectInputStream(byteStream)) { result = stream.readObject(); } catch (IOException | ClassNotFoundException e) { diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java index ee0685ba..ddb9fda0 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/GSONToolsFactory.java @@ -1,34 +1,46 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.serialization; import java.util.Collection; import java.util.Map; - - /** - * Factory that controls the kind of Maps and Collections that are produced when an Object is deserialized + * Factory that controls the kind of Maps and Collections that are produced when + * an Object is deserialized * * @author kuhn, espen * */ public interface GSONToolsFactory { - /** * Create a Map */ public Map createMap(); - - + /** * Create a Collection */ diff --git a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java index 1ea9f8bf..195d53d8 100644 --- a/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java +++ b/src/main/java/org/eclipse/basyx/vab/coder/json/serialization/Serializer.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.coder.json.serialization; @@ -21,7 +36,6 @@ public interface Serializer { */ public String serialize(Object value); - /** * Deserialize a primitive or complex value from JSON object */ diff --git a/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java b/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java index 07ac87d5..6f73db6d 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/AtomicTransactionFailedException.java @@ -1,21 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception; public class AtomicTransactionFailedException extends Exception { - - private static final long serialVersionUID = 1L; private String message; - + /** * Constructor */ @@ -23,9 +36,7 @@ public AtomicTransactionFailedException(String name) { // Store message message = "The atomic transaction on the submodel " + name + " failed since a subproperty has been changed on the server!"; } - - - + /** * Return detailed message */ diff --git a/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java b/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java index 5690bf07..e6ff4a30 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/FeatureNotImplementedException.java @@ -1,15 +1,29 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception; - /** * Exception that indicates that a SDK feature is not yet implemented * @@ -18,10 +32,9 @@ */ public class FeatureNotImplementedException extends RuntimeException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - + } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java b/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java index 35130dd9..11e40d55 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/LostHTTPRequestParameterException.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception; @@ -15,13 +30,13 @@ public class LostHTTPRequestParameterException extends Exception { * */ private static final long serialVersionUID = 1L; - + private String message; public LostHTTPRequestParameterException(String path) { message = "A request on " + path + "has been received without a valid json parameter (unresolved issue)"; } - + @Override public String getMessage() { return message; diff --git a/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java b/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java index e9b3dc6d..a08fcebe 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/ReadOnlyException.java @@ -1,31 +1,42 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception; public class ReadOnlyException extends Exception { - - private static final long serialVersionUID = 1L; private String message; - + /** * Constructor */ public ReadOnlyException(String name) { // Store message - message = "The Submodel "+name+" is frozen."; + message = "The Submodel " + name + " is frozen."; } - - - + /** * Return detailed message */ diff --git a/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java b/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java index 01a48085..4b80de8f 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/TypeMismatchException.java @@ -1,31 +1,42 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception; public class TypeMismatchException extends Exception { - - private static final long serialVersionUID = 1L; private String message; - + /** * Constructor */ public TypeMismatchException(String name, String expectedType) { // Store message - message = "The property '"+name+"' must be of type '"+expectedType+"'"; + message = "The property '" + name + "' must be of type '" + expectedType + "'"; } - - - + /** * Return detailed message */ diff --git a/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java b/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java index 4e6fbf6c..880adf69 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/UnknownElementTypeException.java @@ -1,27 +1,41 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception; - /** - * Exception that indicates that a reference to an unknown element type was requested or resolved + * Exception that indicates that a reference to an unknown element type was + * requested or resolved * * @author kuhn * */ public class UnknownElementTypeException extends RuntimeException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - + } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java b/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java index 61d3acad..a2e9be59 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/provider/MalformedRequestException.java @@ -1,17 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception.provider; +import java.util.List; + +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; + /** - * Used to indicate by a ModelProvider, - * that a given request was malformed.
+ * Used to indicate by a ModelProvider, that a given request was malformed.
* e.g. an invalid path or a invalid JSON. * * @author conradi @@ -19,21 +37,23 @@ */ public class MalformedRequestException extends ProviderException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Constructor */ public MalformedRequestException(String msg) { super(msg); } - + public MalformedRequestException(Exception e) { super(e); } + + public MalformedRequestException(List msgs) { + super(msgs); + } } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java b/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java index 62d87fe3..5063c4b0 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/provider/NotAnInvokableException.java @@ -1,37 +1,50 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception.provider; /** - * Used to indicate by a ModelProvider, - * that invoke was called with a path to a non invokable resource. + * Used to indicate by a ModelProvider, that invoke was called with a path to a + * non invokable resource. * * @author conradi * */ public class NotAnInvokableException extends ProviderException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Constructor */ public NotAnInvokableException(String msg) { super(msg); } - + public NotAnInvokableException(Exception e) { super(e); } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java b/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java index 7e0e3af9..d3e31636 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/provider/ProviderException.java @@ -1,14 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception.provider; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; +import org.eclipse.basyx.vab.coder.json.metaprotocol.MessageType; + /** * Used to indicate a general exception in a ModelProvider * @@ -17,7 +38,8 @@ */ public class ProviderException extends RuntimeException { - + private List messages = new ArrayList<>(); + /** * Version information for serialized instances */ @@ -25,6 +47,12 @@ public class ProviderException extends RuntimeException { public ProviderException(String msg) { super(msg); + messages.add(new Message(MessageType.Exception, msg)); + } + + public ProviderException(List messages) { + super(messages.toString()); + this.messages = messages; } public ProviderException(Throwable cause) { @@ -34,4 +62,8 @@ public ProviderException(Throwable cause) { public ProviderException(String message, Throwable cause) { super(message, cause); } + + public List getMessages() { + return messages; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java b/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java index 6b6a589d..90420a25 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceAlreadyExistsException.java @@ -1,38 +1,59 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception.provider; +import java.util.List; + +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; + /** - * Used to indicate by a ModelProvider, - * that a resource to be created already exists + * Used to indicate by a ModelProvider, that a resource to be created already + * exists * * @author conradi * */ public class ResourceAlreadyExistsException extends ProviderException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Constructor */ public ResourceAlreadyExistsException(String msg) { super(msg); } - + public ResourceAlreadyExistsException(Exception e) { super(e); } + + public ResourceAlreadyExistsException(List msgs) { + super(msgs); + } } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java b/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java index 07e64e20..9c46fdf3 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/provider/ResourceNotFoundException.java @@ -1,38 +1,59 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception.provider; +import java.util.List; + +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; /** - * Exception that indicates that a requested resource (AAS, sub model, property) was not found + * Exception that indicates that a requested resource (AAS, sub model, property) + * was not found * * @author kuhn * */ public class ResourceNotFoundException extends ProviderException { - /** * Version information for serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Constructor */ public ResourceNotFoundException(String msg) { super(msg); } - + public ResourceNotFoundException(Exception e) { super(e); } + + public ResourceNotFoundException(List msgs) { + super(msgs); + } } diff --git a/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java b/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java index 32bff37d..81a0bda4 100644 --- a/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java +++ b/src/main/java/org/eclipse/basyx/vab/exception/provider/WrongNumberOfParametersException.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.exception.provider; @@ -18,11 +33,16 @@ public class WrongNumberOfParametersException extends MalformedRequestException * Version information for serialized instances */ private static final long serialVersionUID = 1L; + public WrongNumberOfParametersException(String operationIdShort, Collection expected, Object... actual) { - super(constructErrorMessage(operationIdShort, expected, actual)); + super(constructErrorMessage(operationIdShort, expected, actual.length)); + } + + public WrongNumberOfParametersException(String operationIdShort, Collection expected, int actualSize) { + super(constructErrorMessage(operationIdShort, expected, actualSize)); } - private static String constructErrorMessage(String operationIdShort, Collection expected, Object... actual) { - return "Operation with idShort " + operationIdShort + " was called using the wrong number of parameters. Expected size: " + expected.size() + ", actual: " + actual.length; + private static String constructErrorMessage(String operationIdShort, Collection expected, int actualSize) { + return "Operation with idShort " + operationIdShort + " was called using the wrong number of parameters. Expected size: " + expected.size() + ", actual size: " + actualSize; } } diff --git a/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java b/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java index 705571a6..2612fd51 100644 --- a/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/factory/java/ModelProxyFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.factory.java; @@ -15,9 +30,10 @@ import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; /** - * A factory for creating model providers out of addresses with multiple endpoints included. + * A factory for creating model providers out of addresses with multiple + * endpoints included. * - * @author espen + * @author espen * */ public class ModelProxyFactory { @@ -26,18 +42,20 @@ public class ModelProxyFactory { public ModelProxyFactory(IConnectorFactory connectorFactory) { this.connectorFactory = connectorFactory; } - + /** * Returns an element proxy for a path that can contain multiple endpoints * - * @param path A path containing one or more endpoints. - * @return A proxy that directly connects to the element referenced by the given path. + * @param path + * A path containing one or more endpoints. + * @return A proxy that directly connects to the element referenced by the given + * path. */ public VABElementProxy createProxy(String path) { // Create a model provider for the first endpoint String addressEntry = VABPathTools.getFirstEndpoint(path); - IModelProvider provider = connectorFactory.getConnector(addressEntry); - + IModelProvider provider = connectorFactory.create(addressEntry); + // Return a proxy for the whole path using the connector to the first endpoint String subPath = VABPathTools.removeFirstEndpoint(path); return new VABElementProxy(subPath, provider); diff --git a/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java b/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java index 4391edfd..efc90e59 100644 --- a/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/factory/xml/VABXmlProviderFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.factory.xml; @@ -21,7 +36,7 @@ * */ public class VABXmlProviderFactory { - + private static Logger logger = LoggerFactory.getLogger(VABXmlProviderFactory.class); public VABXmlProviderFactory() { diff --git a/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java b/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java index 251e6f8a..566a8357 100644 --- a/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java +++ b/src/main/java/org/eclipse/basyx/vab/factory/xml/XmlParser.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.factory.xml; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -43,18 +58,21 @@ * {@literal v => {a={b=v}}}

* * -Text Node with Attributes
- * {@literal v3 => {ele :{#text:v3,b:v1, c:v2}}}
+ * {@literal v3 => {ele :{#text:v3,b:v1, c:v2}}}
*
* * -Multiple Text Nodes
* {@literal v1v2 => {a={b=[v1,v2]}}}

* * -Multiple Text Nodes with Attributes
- * {@literal v1v2 => {a={b=[{#text=v1, d=v3, e=v5}, {#text=v2, d=v4, e=v6}]}}}
+ * {@literal v1v2 => {a={b=[{#text=v1, d=v3, e=v5}, {#text=v2, d=v4, e=v6}]}}}
*
* * -Element Node Attributes
- * {@literal v3 => {a={b=v3}, c=v1, d=v2}}
+ * {@literal v3 => {a={b=v3}, c=v1, d=v2}}
*
* * @author kannoth @@ -65,17 +83,17 @@ public class XmlParser { private static final String TEXT = "#text"; /** - * Parses the XML string content and returns the nested HashMap + * Parses the XML string content and returns the nested LinkedHashMap * - * @param xmlContent - String content of the xml file + * @param xmlContent + * - String content of the xml file * @throws ParserConfigurationException * @throws SAXException * @throws IOException */ - public static Map buildXmlMap(String xmlContent) - throws ParserConfigurationException, SAXException, IOException { + public static Map buildXmlMap(String xmlContent) throws ParserConfigurationException, SAXException, IOException { - Map retMap = new HashMap<>(); + Map retMap = new LinkedHashMap<>(); // Getting rid of the white spaces between the tags in order to avoid creation // of // unwanted nodes with no content. Applying the regex has no implications @@ -104,12 +122,13 @@ public static Map buildXmlMap(String xmlContent) * Traverse through the given DOM Node and build nested map representing the DOM * tree. * - * @param parentNode - Node from which the traversal should be initiated. + * @param parentNode + * - Node from which the traversal should be initiated. * @return */ private static Object traverseDomTree(Node parentNode) { - Map retMap = new HashMap<>(); + Map retMap = new LinkedHashMap<>(); Object leafNode = null; NodeList childNodes = parentNode.getChildNodes(); @@ -161,14 +180,15 @@ private static Object handleTextNode(Node node) { /** * Creates a Map of with element's text and attributes combined * - * @param nodeAttrs - Text node of interest + * @param nodeAttrs + * - Text node of interest * @return */ private static Map makeAttrMapForTxtNode(Node node) { // Get all attributes of the node NamedNodeMap nodeAttrs = node.getAttributes(); // Create a special key for text of the element - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); ret.put(TEXT, node.getTextContent()); // Collect all attributes of the Text node and append // to the text map contents. @@ -183,14 +203,16 @@ private static Map makeAttrMapForTxtNode(Node node) { * Appends the attributes of the Element node to the given map. Useful for * nested Element nodes. * - * @param eleMap - Nested map corresponding to an element node where the - * attributes needs to be appended. - * @param node - Element node of interest + * @param eleMap + * - Nested map corresponding to an element node where the attributes + * needs to be appended. + * @param node + * - Element node of interest * @return */ private static Map makeAttrMapForEleNode(Map eleMap, Node node) { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); ret = eleMap; // Collect all attributes of the Element node and append to // nested map contents. @@ -203,9 +225,12 @@ private static Map makeAttrMapForEleNode(Map ele /** * Updates the nested Map until created with new element. * - * @param map - Map which is created until - * @param nodeName - Node name of interest - * @param leafNode - Leaf object that to be added + * @param map + * - Map which is created until + * @param nodeName + * - Node name of interest + * @param leafNode + * - Leaf object that to be added */ @SuppressWarnings("unchecked") private static void updateNestedMap(Map map, String nodeName, Object leafNode) { @@ -235,7 +260,8 @@ private static void updateNestedMap(Map map, String nodeName, Ob /** * Makes the given NodeList iterable * - * @param nodeList - NodeList to be made iterable + * @param nodeList + * - NodeList to be made iterable * @return */ private static Iterable iterableNodeMap(final NodeList nodeList) { @@ -261,7 +287,8 @@ public Node next() { /** * Makes the given NamedNodeMap iterable * - * @param namedNodeMap - NamedNodeMap to be made iterable + * @param namedNodeMap + * - NamedNodeMap to be made iterable * @return */ private static Iterable iterableNamedNodeMap(final NamedNodeMap namedNodeMap) { diff --git a/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java b/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java index 54120a35..ed5fd8bd 100644 --- a/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java +++ b/src/main/java/org/eclipse/basyx/vab/gateway/ConnectorProviderMapper.java @@ -1,15 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.gateway; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; @@ -26,7 +41,7 @@ */ public class ConnectorProviderMapper implements IConnectorFactory { - private Map providerMap = new HashMap<>(); + private Map providerMap = new LinkedHashMap<>(); /** * @@ -45,7 +60,7 @@ public void removeConnectorProvider(String prefix) { @Override public IModelProvider getConnector(String addr) { - return providerMap.get(getPrefix(addr)).getConnector(addr); + return providerMap.get(getPrefix(addr)).create(addr); } /** diff --git a/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java b/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java index c055d632..6e7b4bad 100644 --- a/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/gateway/DelegatingModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.gateway; diff --git a/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java b/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java index 9760e349..7547ce18 100644 --- a/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java +++ b/src/main/java/org/eclipse/basyx/vab/manager/VABConnectionManager.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.manager; @@ -14,8 +29,6 @@ import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; import org.eclipse.basyx.vab.registry.api.IVABRegistryService; - - /** * Allows access to elements provided by the VAB * @@ -29,12 +42,11 @@ public class VABConnectionManager { */ protected IVABRegistryService directoryService = null; - /** * Store connection providers */ protected IConnectorFactory connectorFactory = null; - + /** * Factory for creating proxies for addresses with multiple endpoints */ @@ -53,15 +65,16 @@ public VABConnectionManager(IVABRegistryService networkDirectoryService, IConnec // Set connector reference this.connectorFactory = providerProvider; - + // Set proxy factory this.proxyFactory = new ModelProxyFactory(providerProvider); } - + /** * Connect to an VAB element * - * @param urn the URN that describes the element. + * @param urn + * the URN that describes the element. */ public VABElementProxy connectToVABElement(String urn) { @@ -70,7 +83,7 @@ public VABElementProxy connectToVABElement(String urn) { // Lookup address in directory server addr = directoryService.lookup(urn); - + return connectToVABElementByPath(addr); } @@ -81,6 +94,6 @@ public VABElementProxy connectToVABElement(String urn) { * the path that describes the element location. */ public VABElementProxy connectToVABElementByPath(String path) { - return proxyFactory.createProxy(path); + return proxyFactory.createProxy(path); } } diff --git a/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java b/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java index 92e3dae8..8b1121da 100644 --- a/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java +++ b/src/main/java/org/eclipse/basyx/vab/model/VABModelMap.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.model; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -18,19 +33,19 @@ import org.eclipse.basyx.vab.support.TypeDestroyer; /** -* Base class for all hash maps that contain VAB meta models -* + * Base class for all hash maps that contain VAB meta models + * * Subclasses contain meta model structures for the virtual automation bus. They -* may be copied during instantiation and when creating facades. Implementations -* need to support this behavior.
-*
-* Warning: equals and hashcode are overwritten so that classes extending -* maps with equal content are always seen as producting the same hashcode/being -* equal -* + * may be copied during instantiation and when creating facades. Implementations + * need to support this behavior.
+ *
+ * Warning: equals and hashcode are overwritten so that classes extending + * maps with equal content are always seen as producting the same hashcode/being + * equal + * * @author kuhn -* -*/ + * + */ public class VABModelMap implements Map { protected Map map; @@ -39,7 +54,7 @@ public class VABModelMap implements Map { * Default constructor */ public VABModelMap() { - map = new HashMap<>(); + map = new LinkedHashMap<>(); } public void setMap(Map map) { @@ -179,7 +194,7 @@ public Collection values() { public Set> entrySet() { return map.entrySet(); } - + @SuppressWarnings("unchecked") @Override public int hashCode() { diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java index bfcf1493..235e59fe 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABElementProxy.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider; @@ -35,23 +50,24 @@ public class VABElementProxy implements IModelProvider { protected IModelProvider provider = null; /** - * Creates the proxy based on a specific model provider. - * E.g, if the element resides on basyx://127.0.0.1 in the path - * a/b/c, provider would realize the connection to - * basyx://127.0.0.1 and addr would be a/b/c. The - * VABElementProxy then directly points to the element. + * Creates the proxy based on a specific model provider. E.g, if the element + * resides on basyx://127.0.0.1 in the path a/b/c, provider + * would realize the connection to basyx://127.0.0.1 and addr + * would be a/b/c. The VABElementProxy then directly points to the + * element. * * @param addr * Address "within" the provider - * @param provider The provider this proxy is based on - * + * @param provider + * The provider this proxy is based on + * */ public VABElementProxy(String addr, IModelProvider provider) { // Store references this.addr = VABPathTools.stripSlashes(addr); this.provider = provider; } - + /** * Read VAB element value */ @@ -155,8 +171,6 @@ public Object invokeOperation(String elementPath, Object... parameter) throws Pr } } - - /** * Add path to VAB element address. Make sure that resulting path contains the * proper number of slashes ("/") @@ -174,7 +188,7 @@ private String constructPath(String path) { path = VABPathTools.stripSlashes(path); // Now combine both paths - if ( path.isEmpty() ) { + if (path.isEmpty()) { return addr; } else if (addr != null && !addr.isEmpty()) { if (path.startsWith("?")) { diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java index 31f6ed9b..6d9ec6a2 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider; @@ -239,8 +254,9 @@ public static String buildPath(String[] pathElements, int startIndex) { } /** - * Check if the path to an VAB elements leads to the invocation of an operation. In this case, the - * element path conforms to /aas/submodels/{subModelId}/submodelElements/{operationId}/invoke + * Check if the path to an VAB elements leads to the invocation of an operation. + * In this case, the element path conforms to + * /aas/submodels/{subModelId}/submodelElements/{operationId}/invoke */ public static boolean isOperationInvokationPath(String path) { // null-Paths are no operation paths @@ -250,8 +266,8 @@ public static boolean isOperationInvokationPath(String path) { // Split path String[] pathElements = splitPath(path); - - if(pathElements.length == 0) { + + if (pathElements.length == 0) { return false; } @@ -273,14 +289,16 @@ public static boolean isEmptyPath(String path) { /** * Gets the first endpoint of a path. - * @param fullPath - * A path that can contain 0..* endpoints. - * @return - * The first address entry of a path. The address entry is the first endpoint combined with a protocol. - * If there is no protocol defined, the address entry is empty (""). - * E.g. basyx://127.0.0.1:6998//https://localhost/test/ will return basyx://127.0.0.1:6998, - * https://localhost/test//basyx://127.0.0.1:6998/ will return https://localhost/test - * and http://localhost/test/ will return "". + * + * @param fullPath + * A path that can contain 0..* endpoints. + * @return The first address entry of a path. The address entry is the first + * endpoint combined with a protocol. If there is no protocol defined, + * the address entry is empty (""). E.g. + * basyx://127.0.0.1:6998//https://localhost/test/ will return + * basyx://127.0.0.1:6998, + * https://localhost/test//basyx://127.0.0.1:6998/ will return + * https://localhost/test and http://localhost/test/ will return "". */ public static String getFirstEndpoint(String fullPath) { // Return null result for null argument @@ -298,10 +316,11 @@ public static String getFirstEndpoint(String fullPath) { /** * Removes the first endpoint from a path.
+ * * @param fullPath - * @return - * The first endpoint. E.g. basyx://127.0.0.1:6998//https://localhost/test/ will return - * https://localhost/test/. + * @return The first endpoint. E.g. + * basyx://127.0.0.1:6998//https://localhost/test/ will return + * https://localhost/test/. * */ public static String removeFirstEndpoint(String fullPath) { @@ -362,7 +381,7 @@ public static String concatenatePaths(String... paths) { // Return combined path return result.toString(); } - + /** * Checks if path is null, if yes throw exception * @@ -373,7 +392,7 @@ public static void checkPathForNull(String path) throws MalformedRequestExceptio throw new MalformedRequestException("Path is not allowed to be null"); } } - + /** * Strips the last path element if it is "invoke" * @@ -381,45 +400,56 @@ public static void checkPathForNull(String path) throws MalformedRequestExceptio * @return path without last element "invoke" or unchanged path */ public static String stripInvokeFromPath(String path) { - - if(path == null) + return stripFromPath(path, Operation.INVOKE); + } + + /** + * Strips the last path element if it is elementToStrip + * + * @param path + * @param elementToStrip + * @return path without last element "invoke" or unchanged path + */ + public static String stripFromPath(String path, String elementToStrip) { + if (path == null) return null; - - if(getLastElement(path).startsWith(Operation.INVOKE)) { + + if (getLastElement(path).startsWith(elementToStrip)) { return getParentPath(path); } - + return path; } - + /** - * Gets the path from a URL - * e.g "http://localhost:8080/path/to/test.file" results in "/path/to/test.file" + * Gets the path from a URL e.g "http://localhost:8080/path/to/test.file" + * results in "/path/to/test.file" * * @param url * @return the path from the URL */ public static String getPathFromURL(String url) { - if(url == null) { + if (url == null) { return null; } - - if(url.contains("://")) { - + + if (url.contains("://")) { + // Find the ":" and and remove the "http://" from the url int index = url.indexOf(":") + 3; url = url.substring(index); - - // Find the first "/" from the URL (now without the "http://") and remove everything before that + + // Find the first "/" from the URL (now without the "http://") and remove + // everything before that index = url.indexOf("/"); url = url.substring(index); - - // Recursive call to deal with more than one server parts + + // Recursive call to deal with more than one server parts // (e.g. basyx://127.0.0.1:6998//https://localhost/test/) return getPathFromURL(url); } else { // Make sure the path has a / at the start - if(!url.startsWith("/")) { + if (!url.startsWith("/")) { url = "/" + url; } return url; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java index 36c89bee..d9bb361f 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/api/IModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.api; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java index 6b8c14a1..04946b04 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/consistency/ConsistencyProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.consistency; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java index 6a3920d4..9154f5e7 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/FileSystemProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.filesystem; @@ -14,7 +29,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -51,9 +66,9 @@ public class FileSystemProvider implements IModelProvider { private final GSONTools tools = new GSONTools(new DefaultTypeFactory()); /** - * Constructor which takes a file system and a root directory - * Removes the last '/' from the passed root directory if it exists - * Creates the root directory folder + * Constructor which takes a file system and a root directory Removes the last + * '/' from the passed root directory if it exists Creates the root directory + * folder */ public FileSystemProvider(FileSystem fileSystem, String rootDir) throws ProviderException { this.fileSystem = fileSystem; @@ -74,8 +89,7 @@ public FileSystemProvider(FileSystem fileSystem, String rootDir, Map VABelement, - boolean doEmptyDirectory) throws ProviderException { + public FileSystemProvider(FileSystem fileSystem, String rootDir, Map VABelement, boolean doEmptyDirectory) throws ProviderException { this.fileSystem = fileSystem; this.rootDir = unifyPath(rootDir); @@ -87,7 +101,8 @@ public FileSystemProvider(FileSystem fileSystem, String rootDir, Map readMetaFile(String path) throws ProviderException { path = path.equals("") ? rootDir + "/" + metaFileName : rootDir + "/" + path + "/" + metaFileName; if (fileSystem.getType(path) == FileType.DATA) { Object deserialized = loadAndDeserialize(path); - // Especially for "[]", deserialization can not differentiate between lists and sets + // Especially for "[]", deserialization can not differentiate between lists and + // sets if (deserialized instanceof HashSet) { return (HashSet) deserialized; } else if (deserialized instanceof Collection) { @@ -156,18 +172,18 @@ private Collection readCollection(String path) throws ProviderException /** * Reads the folder in the relative path specified */ - private HashMap readDirectory(String path) throws ProviderException { + private LinkedHashMap readDirectory(String path) throws ProviderException { String fullPath = rootDir + "/" + path; - HashMap returnData = new HashMap(); + LinkedHashMap returnData = new LinkedHashMap(); HashSet collections = readMetaFile(path); List directoryFiles; try { directoryFiles = fileSystem.readDirectory(fullPath); } catch (IOException e) { - throw new ProviderException("Path \"" + path + "\" could not be read."); + throw new ProviderException("Path \"" + path + "\" could not be read."); } - + removeMetaFile(directoryFiles); for (File file : directoryFiles) { @@ -203,8 +219,8 @@ private String stripRootDir(String path) { } /** - * Adds collection to the __meta file present in directoryPath - * Works whether "/" is at the end of path or not + * Adds collection to the __meta file present in directoryPath Works whether "/" + * is at the end of path or not */ private void addCollectionToMetaFile(String directoryPath, String collectionName) throws ProviderException { HashSet collections = readMetaFile(directoryPath); @@ -219,9 +235,9 @@ private void addCollectionToMetaFile(String directoryPath, String collectionName } /** - * Serializes and writes the object in the path specified. The path is relative to the RootDir - * If the write folder is not present, it is created - * If the object is an array or a collection, a collection is written in a folder + * Serializes and writes the object in the path specified. The path is relative + * to the RootDir If the write folder is not present, it is created If the + * object is an array or a collection, a collection is written in a folder */ @SuppressWarnings("unchecked") private void writeObject(String path, Object o) throws ProviderException { @@ -259,7 +275,7 @@ private void writeObject(String path, Object o) throws ProviderException { serializeAndSave(fullPath, o); } } - + private void createDirectory(String path) throws ProviderException { try { fileSystem.createDirectory(path); @@ -267,7 +283,7 @@ private void createDirectory(String path) throws ProviderException { throw new ProviderException("Directory \"" + path + "\" could not be created."); } } - + private void deleteDirectory(String path) throws ProviderException { try { fileSystem.deleteDirectory(path); @@ -275,7 +291,7 @@ private void deleteDirectory(String path) throws ProviderException { throw new ProviderException("Directory \"" + path + "\" could not be deleted."); } } - + private void deleteFile(String path) throws ProviderException { try { fileSystem.deleteFile(path); @@ -286,14 +302,14 @@ private void deleteFile(String path) throws ProviderException { /** * Mirrors a Map folder structure in the specified relative path - * Works whether "/" is at the end of path or not - * Does not create the directory "path" + * Works whether "/" is at the end of path or not Does not create the directory + * "path" */ @SuppressWarnings("unchecked") private void fromMapToDirectory(String path, Map map) throws ProviderException { path = unifyPath(path); String fullPath = rootDir + "/" + path; - + createDirectory(fullPath); for (Map.Entry entry : map.entrySet()) { @@ -341,7 +357,7 @@ public synchronized Object getValue(String path) throws ProviderException { String fullDirPath = rootDir + "/" + directory; if (fileSystem.getType(fullDirPath) == FileType.DIRECTORY) { - + List directoryFiles; try { directoryFiles = fileSystem.readDirectory(fullDirPath); @@ -370,8 +386,7 @@ public synchronized Object getValue(String path) throws ProviderException { } else if (fileName.matches(regexCollectionElem)) { // We wanted to read an element of a collection. The element does not exist, // throw an Invalid List Reference Exception - throw new ResourceNotFoundException("The specified list element \"" + - fileName.substring(collectionElemPrefix.length()) + "\" does not exist."); + throw new ResourceNotFoundException("The specified list element \"" + fileName.substring(collectionElemPrefix.length()) + "\" does not exist."); } } } @@ -379,8 +394,8 @@ public synchronized Object getValue(String path) throws ProviderException { } /** - * Sets the file, folder, or collection at the specified path to newValue - * Only works if the types match (i.e. file ↔ file, folder ↔ folder, etc...) + * Sets the file, folder, or collection at the specified path to newValue Only + * works if the types match (i.e. file ??? file, folder ??? folder, etc...) */ @Override @SuppressWarnings("unchecked") @@ -397,8 +412,7 @@ public synchronized void setValue(String path, Object newValue) throws ProviderE if (!(newValue instanceof Map) && !(newValue instanceof Collection)) { serializeAndSave(fullPath, newValue); } else { - throw new MalformedRequestException("The single value at \"" + path + - "\" can not be replaced with a Map or Collection"); + throw new MalformedRequestException("The single value at \"" + path + "\" can not be replaced with a Map or Collection"); } } else if (type == FileType.DIRECTORY) { if ((collections == null || !collections.contains(fileName)) && newValue instanceof Map) { @@ -414,8 +428,8 @@ public synchronized void setValue(String path, Object newValue) throws ProviderE } /** - * Creates newEntity at the specified path - * If a collection exists at the specified path, add newEntity to it IF newEntity is not a collection + * Creates newEntity at the specified path If a collection exists at the + * specified path, add newEntity to it IF newEntity is not a collection */ @Override @SuppressWarnings("unchecked") @@ -423,12 +437,11 @@ public synchronized void createValue(String path, Object newEntity) throws Provi path = unifyPath(path); String parentPath = VABPathTools.getParentPath(path); String fileName = VABPathTools.getLastElement(path); - - - if(fileSystem.getType(rootDir + "/" + parentPath) == null) { + + if (fileSystem.getType(rootDir + "/" + parentPath) == null) { throw new ResourceNotFoundException("Parent-path for \"" + path + "\" does not exist."); } - + String fullPath = rootDir + "/" + path; FileType type = fileSystem.getType(fullPath); @@ -459,8 +472,7 @@ public synchronized void createValue(String path, Object newEntity) throws Provi // If the new Object is a Collection, don't add it to the existing one serializeAndSave(constructCollectionRefPath(fullPath, max + 1), newEntity); } else { - throw new MalformedRequestException("The given newEntity is a Collection " - + "and can therefore not be added to the existing Collection \"" + path + "\"."); + throw new MalformedRequestException("The given newEntity is a Collection " + "and can therefore not be added to the existing Collection \"" + path + "\"."); } references.add(max + 1); @@ -480,9 +492,9 @@ public synchronized void createValue(String path, Object newEntity) throws Provi } /** - * Deletes the Object, folder or collection at the specified path - * If it is a collection, remove its name from the meta file of - * the folder that contains the collection + * Deletes the Object, folder or collection at the specified path If it is a + * collection, remove its name from the meta file of the folder that contains + * the collection */ @Override public synchronized void deleteValue(String path) throws ProviderException { @@ -520,9 +532,8 @@ public synchronized void deleteValue(String path) throws ProviderException { } /** - * Deletes the Object or Map that is equal to obj from the collection - * in the specified path - * Otherwise, throw a ResourceNotFoundException + * Deletes the Object or Map that is equal to obj from the collection in the + * specified path Otherwise, throw a ResourceNotFoundException */ @Override public void deleteValue(String path, Object obj) throws ProviderException { diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java index 6f3045db..3bcd1ec0 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/TimeProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.filesystem; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java index 828832d5..b2e21ac1 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/File.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java index af068640..75a412e6 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileSystem.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem; @@ -14,14 +29,15 @@ /** * Abstracts from a generic file system + * * @author schnicke * */ public interface FileSystem { - + /** * Reads the content of a file formated as UTF-8.
- * Throws an Exception if file at given path does not exist. + * Throws an Exception if file at given path does not exist. * * @param path * @return The content of specified file as String @@ -36,7 +52,8 @@ public interface FileSystem { * Does not create nonexistent parent directories. * * @param path - * @param content the String to be written to a file + * @param content + * the String to be written to a file * @throws IOException */ public void writeFile(String path, String content) throws IOException; @@ -68,23 +85,23 @@ public interface FileSystem { * @throws IOException */ public List readDirectory(String path) throws IOException; - + /** - * Deletes the directory at the specified path, - * including contained files and subdirectories.
- * Does not throw an Exception if directory at path does not exist. + * Deletes the directory at the specified path, including contained files and + * subdirectories.
+ * Does not throw an Exception if directory at path does not exist. * * @param path * @throws IOException */ public void deleteDirectory(String path) throws IOException; - + /** * Gets the FileType of an object at a specified path * * @param path - * @return The FileType of the object at the given path - * or null if this object does not exist + * @return The FileType of the object at the given path or null if this object + * does not exist */ public FileType getType(String path); } diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java index 635ce2b1..e0e20a15 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/FileType.java @@ -1,16 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem; /** * Represent the type of a file: Either it is data or a directory + * * @author schnicke * */ diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java index 772e3c28..ee087e30 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/filesystem/filesystem/GenericFileSystem.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.filesystem.filesystem; @@ -65,15 +80,12 @@ public List readDirectory(String path) throws IOException { // Use try to ensure that close is called try (Stream directory = Files.list(getPath(path))) { - files.addAll(directory.filter(Files::isRegularFile) - .map(p -> new File(restoreCase(p.toString().replace("\\", "/")), FileType.DATA)).collect(Collectors.toList())); + files.addAll(directory.filter(Files::isRegularFile).map(p -> new File(restoreCase(p.toString().replace("\\", "/")), FileType.DATA)).collect(Collectors.toList())); } // Use try to ensure that close is called try (Stream directory = Files.list(getPath(path))) { - files.addAll(directory.filter(Files::isDirectory) - .map(p -> new File(restoreCase(p.toString().replace("\\", "/")), FileType.DIRECTORY)) - .collect(Collectors.toList())); + files.addAll(directory.filter(Files::isDirectory).map(p -> new File(restoreCase(p.toString().replace("\\", "/")), FileType.DIRECTORY)).collect(Collectors.toList())); } return files; @@ -85,27 +97,27 @@ public void deleteDirectory(String path) throws IOException { try { Files.walk(getPath(path)).sorted(Comparator.reverseOrder()).map(p -> p.toFile()).forEach(f -> f.delete()); } catch (NoSuchFileException e) { - //Do nothing if the File to delete doesn't exist + // Do nothing if the File to delete doesn't exist } } - + @Override public FileType getType(String path) { path = toLowerCase(path); - - if(!Files.exists(getPath(path))) + + if (!Files.exists(getPath(path))) return null; - - if(Files.isDirectory(getPath(path))) + + if (Files.isDirectory(getPath(path))) return FileType.DIRECTORY; - + return FileType.DATA; } private Path getPath(String path) { return FileSystems.getDefault().getPath(path); } - + /** * Replaces each capital character by (_small character) ([A-Z] by _[a-z]) and * each _ by __ @@ -124,7 +136,7 @@ private String restoreCase(String path) { while (m.find()) m.appendReplacement(result, m.group(1).toUpperCase()); - + m.appendTail(result); return result.toString(); diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java index 01a2273a..314605a0 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/IVABElementHandler.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.generic; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java index f1dc60be..7e7a95f2 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/generic/VABModelProvider.java @@ -1,17 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.generic; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import org.eclipse.basyx.vab.exception.provider.NotAnInvokableException; +import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.modelprovider.VABPathTools; @@ -105,26 +123,80 @@ public void deleteValue(String path, Object obj) { handler.deleteValue(targetElement, obj); } - @SuppressWarnings("unchecked") @Override public Object invokeOperation(String path, Object... parameters) { - + path = VABPathTools.stripInvokeFromPath(path); - + Object childElement = getValue(path); // Invoke operation for function interfaces if (childElement instanceof Function) { - Function function = (Function) childElement; - return function.apply(parameters); + return runFunction(childElement, parameters); + } else if (childElement instanceof Supplier) { + return runSupplier(childElement); + } else if (childElement instanceof Consumer) { + return runConsumer(childElement, parameters); + } else if (childElement instanceof Runnable) { + return runRunnable(childElement); } else { throw new NotAnInvokableException("Element \"" + path + "\" is not a function."); } } + private Object runRunnable(Object childElement) { + Runnable runnable = (Runnable) childElement; + try { + runnable.run(); + } catch (ProviderException e) { + throw e; + } catch (Exception e) { + throw new ProviderException(e); + } + return null; + } + + @SuppressWarnings("unchecked") + private Object runConsumer(Object childElement, Object... parameters) { + Consumer consumer = (Consumer) childElement; + try { + consumer.accept(parameters); + } catch (ProviderException e) { + throw e; + } catch (Exception e) { + throw new ProviderException(e); + } + return null; + } + + @SuppressWarnings("unchecked") + private Object runSupplier(Object childElement) { + Supplier supplier = (Supplier) childElement; + try { + return supplier.get(); + } catch (ProviderException e) { + throw e; + } catch (Exception e) { + throw new ProviderException(e); + } + } + + @SuppressWarnings("unchecked") + private Object runFunction(Object childElement, Object... parameters) { + Function function = (Function) childElement; + try { + return function.apply(parameters); + } catch (ProviderException e) { + throw e; + } catch (Exception e) { + throw new ProviderException(e); + } + } + /** - * Get the parent of an element in this provider. The path should include the path to the element separated by '/'. - * E.g., for accessing element c in path a/b, the path should be a/b/c. + * Get the parent of an element in this provider. The path should include the + * path to the element separated by '/'. E.g., for accessing element c in path + * a/b, the path should be a/b/c. */ private Object getParentElement(String path) { VABPathTools.checkPathForNull(path); @@ -145,10 +217,9 @@ private Object getParentElement(String path) { return currentElement; } - /** - * Instead of returning the parent element of a path, this function gives the target element. - * E.g., it returns c for the path a/b/c + * Instead of returning the parent element of a path, this function gives the + * target element. E.g., it returns c for the path a/b/c */ protected Object getTargetElement(String path) { VABPathTools.checkPathForNull(path); diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java index 815783a2..e46fba46 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaHandler.java @@ -1,17 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.lambda; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; @@ -52,12 +67,12 @@ public void setModelPropertyValue(Object element, String propertyName, Object ne Object child = null; try { child = getElementProperty(element, propertyName); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } if (hasHiddenSetter(child)) { ((Consumer) ((Map) child).get(VALUE_SET_SUFFIX)).accept(newValue); } else if (hasHiddenInserter(element) && (resolveSingle(element) instanceof Map)) { - ((BiConsumer) ((Map) element).get(VALUE_INSERT_SUFFIX)).accept(propertyName, - newValue); + ((BiConsumer) ((Map) element).get(VALUE_INSERT_SUFFIX)).accept(propertyName, newValue); } else { super.setModelPropertyValue(resolveSingle(element), propertyName, newValue); } @@ -126,7 +141,7 @@ private Object resolveAll(Object o) { } private Object resolveMap(Map map) { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); for (String s : map.keySet()) { ret.put(s, resolveAll(map.get(s))); } diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java index 2708bbbb..6783e6cf 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.lambda; diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java index b2a95b97..16041afa 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/lambda/VABLambdaProviderHelper.java @@ -1,15 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.lambda; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -33,7 +48,7 @@ public class VABLambdaProviderHelper { * @return */ public static Map createSimple(Supplier get, Consumer set) { - Map value = new HashMap<>(); + Map value = new LinkedHashMap<>(); value.put(VABLambdaHandler.VALUE_GET_SUFFIX, get); value.put(VABLambdaHandler.VALUE_SET_SUFFIX, set); return value; @@ -54,9 +69,8 @@ public static Map createSimple(Supplier get, Consumer createMap(Supplier get, Consumer set, BiConsumer insert, - Consumer removeObject, Consumer removeKey) { - Map value = new HashMap<>(); + public static Map createMap(Supplier get, Consumer set, BiConsumer insert, Consumer removeObject, Consumer removeKey) { + Map value = new LinkedHashMap<>(); value.put(VABLambdaHandler.VALUE_GET_SUFFIX, get); value.put(VABLambdaHandler.VALUE_SET_SUFFIX, set); value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, removeObject); @@ -80,9 +94,8 @@ public static Map createMap(Supplier get, Consumer set, Bi * Method used to remove a key from the map * @return */ - public static Map createCollection(Supplier get, Consumer set, Consumer insert, - Consumer removeObject, Consumer removeKey) { - Map value = new HashMap<>(); + public static Map createCollection(Supplier get, Consumer set, Consumer insert, Consumer removeObject, Consumer removeKey) { + Map value = new LinkedHashMap<>(); value.put(VABLambdaHandler.VALUE_GET_SUFFIX, get); value.put(VABLambdaHandler.VALUE_SET_SUFFIX, set); value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, removeObject); diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java index 1da707c6..5027a358 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapHandler.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.map; @@ -30,7 +45,7 @@ public Object getElementProperty(Object element, String propertyName) { if (element instanceof Map) { Map map = (Map) element; - //check if requested property exists in map + // check if requested property exists in map if (!map.containsKey(propertyName)) { throw new ResourceNotFoundException("Property \"" + propertyName + "\" does not exist."); } @@ -72,7 +87,7 @@ public void deleteValue(Object element, String propertyName) { if (element instanceof Map) { Map map = (Map) element; // check if requested property exists in map - if(!map.containsKey(propertyName)) { + if (!map.containsKey(propertyName)) { throw new ResourceNotFoundException("Property \"" + propertyName + "\" does not exist. Therefore it can not be deleted."); } map.remove(propertyName); diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java index 1a90239f..9c40f777 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/map/VABMapProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.modelprovider.map; @@ -14,10 +29,8 @@ import org.eclipse.basyx.vab.modelprovider.generic.IVABElementHandler; import org.eclipse.basyx.vab.modelprovider.generic.VABModelProvider; - - /** - * A simple VAB model provider based on a HashMap. + * A simple VAB model provider based on a LinkedHashMap. * * This provider demonstrates the inclusion of new data sources to the VAB * diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java b/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java index 11b7db5b..86028532 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/api/ConnectorFactory.java @@ -1,15 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.api; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; @@ -22,7 +37,7 @@ */ public abstract class ConnectorFactory implements IConnectorFactory { - private Map providerMap = new HashMap<>(); + private Map providerMap = new LinkedHashMap<>(); @Override public IModelProvider getConnector(String addr) { diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java b/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java index f4582bf0..05db35c0 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/api/IBaSyxConnector.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.api; @@ -76,10 +91,12 @@ public interface IBaSyxConnector { * @return Return value */ public String invokeOperation(String path, String jsonObject) throws ProviderException; - + /** - * Get string representation of endpoint for given path for debugging. - * @param path Requested path + * Get string representation of endpoint for given path for debugging. + * + * @param path + * Requested path * @return String representing requested endpoint */ public String getEndpointRepresentation(String path); diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java b/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java index b0065e83..c54e7c76 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/api/IConnectorFactory.java @@ -16,14 +16,24 @@ public interface IConnectorFactory { /** * Gets an IModelProvider connecting the specific address. + * + * @deprecated This method is deprecated please use {@link #create(String)} * - * @param addr - * The address for which a provider is returned. Must be an address limited to one included endpoint. - * For example, it does NOT support basyx://localhost:6998//http://localhost/a/b/c, but http://localhost/a/b/c - * @return - * A provider that directly points to the element referenced by the given address. - * E.g. the returned model provider for http://localhost/a/b/c directly points to the element c. Therefore, - * getConnector("http://localhost/a/b/c").getModelPropertyValue(""); returns the value of the element c. + * @param addr + * The address for which a provider is returned. Must be an address + * limited to one included endpoint. For example, it does NOT support + * basyx://localhost:6998//http://localhost/a/b/c, but + * http://localhost/a/b/c + * @return A provider that directly points to the element referenced by the + * given address. E.g. the returned model provider for + * http://localhost/a/b/c directly points to the element c. Therefore, + * getConnector("http://localhost/a/b/c").getModelPropertyValue(""); + * returns the value of the element c. */ + @Deprecated public IModelProvider getConnector(String addr); + + public default IModelProvider create(String addr) { + return getConnector(addr); + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java b/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java index 100c3043..0b72e387 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/basyx/CoderTools.java @@ -1,18 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.basyx; import java.nio.charset.StandardCharsets; - - /** * Byte en/decoding tools * @@ -21,154 +34,145 @@ */ public class CoderTools { - /** * Get a uint32 from a byte array with offset, MSB is first bit */ public static int getInt32(byte[] data, int offset) { long result = 0; - - result += data[offset+3] & 0xFF; result = result << 8; - result += data[offset+2] & 0xFF; result = result << 8; - result += data[offset+1] & 0xFF; result = result << 8; - result += data[offset+0] & 0xFF; - + + result += data[offset + 3] & 0xFF; + result = result << 8; + result += data[offset + 2] & 0xFF; + result = result << 8; + result += data[offset + 1] & 0xFF; + result = result << 8; + result += data[offset + 0] & 0xFF; + return (int) result; } - /** * Copy an uint32 to a byte array at given offset, MSB is first bit */ public static byte[] setInt32(byte[] data, int offset, int value) { - data[offset+3] = (byte) ((value >> 24) & 0xFF); - data[offset+2] = (byte) ((value >> 16) & 0xFF); - data[offset+1] = (byte) ((value >> 8) & 0xFF); - data[offset+0] = (byte) (value & 0xFF); - + data[offset + 3] = (byte) ((value >> 24) & 0xFF); + data[offset + 2] = (byte) ((value >> 16) & 0xFF); + data[offset + 1] = (byte) ((value >> 8) & 0xFF); + data[offset + 0] = (byte) (value & 0xFF); + return data; } - - /** * Get a uint16 from a byte array with offset, MSB is first bit */ public static int getInt16(byte[] data, int offset) { int result = 0; - - result += data[offset+1] & 0xFF; result = result << 8; - result += data[offset+0] & 0xFF; - + + result += data[offset + 1] & 0xFF; + result = result << 8; + result += data[offset + 0] & 0xFF; + return result; } - /** * Copy an uint16 to a byte array at given offset, MSB is first bit */ public static byte[] setInt16(byte[] data, int offset, int value) { - data[offset+1] = (byte) ((value >> 8) & 0xFF); - data[offset+0] = (byte) (value & 0xFF); - + data[offset + 1] = (byte) ((value >> 8) & 0xFF); + data[offset + 0] = (byte) (value & 0xFF); + return data; } - - /** * Get a uint8 from a byte array with offset, MSB is first bit */ public static int getInt8(byte[] data, int offset) { int result = 0; - - result += data[offset+0] & 0xFF; - + + result += data[offset + 0] & 0xFF; + return result; } - /** * Copy an uint8 to a byte array at given offset, MSB is first bit */ public static byte[] setInt8(byte[] data, int offset, int value) { - data[offset+0] = (byte) (value & 0xFF); - + data[offset + 0] = (byte) (value & 0xFF); + return data; } - - /** * Get all remaining bytes from byte array */ public static byte[] getByteArray(byte[] data, int offset) { - byte[] result = new byte[data.length-offset]; - - for (int i=offset; i implements Runnable, BaSyxService { - + private static Logger logger = LoggerFactory.getLogger(BaSyxTCPServer.class); - /** * Store server socket channel instance */ protected ServerSocketChannel serverSockChannel = null; - /** * Reference to IModelProvider backend */ protected T providerBackend = null; - /** * Exit flag */ protected boolean exit = false; - - + /** * Store thread */ protected Thread thread = null; - - + /** * Store name */ protected String name = null; - - - + /** * Constructor */ @@ -75,7 +81,8 @@ public BaSyxTCPServer(T modelProviderBackend, int serverPort) { // Create communication channel try { - // The channel should listen on all interfaces, binding on 127.0.0.1 prohibits remote communication + // The channel should listen on all interfaces, binding on 127.0.0.1 prohibits + // remote communication InetAddress hostIPAddress = InetAddress.getByName("0.0.0.0"); // Server socket channel @@ -88,7 +95,6 @@ public BaSyxTCPServer(T modelProviderBackend, int serverPort) { } } - /** * Default constructor without port number */ @@ -97,7 +103,6 @@ public BaSyxTCPServer(T modelProviderBackend) { this(modelProviderBackend, 6998); } - /** * Thread main method */ @@ -109,8 +114,7 @@ public void run() { acceptIncomingConnection(); } } - - + /** * Accept an incoming connection */ @@ -122,11 +126,12 @@ public void acceptIncomingConnection() { // Wait for connections try { - communicationSocket = serverSockChannel.accept(); + communicationSocket = serverSockChannel.accept(); } catch (SocketException e) { logger.error("Exception in acceptIncomingConnection", e); // End process; Server socket has been closed by shutdown - exit = true; return; + exit = true; + return; } // Handle an incoming connection @@ -136,21 +141,21 @@ public void acceptIncomingConnection() { tcpProvider.start(); } catch (IOException e) { // Indicate exception only iff exit flag is false - if (!exit) logger.error("Exception in acceptIncomingConnection", e); + if (!exit) + logger.error("Exception in acceptIncomingConnection", e); // Return return; } } - - + /** * End server */ protected void shutdown() { // End thread exit = true; - + // Handle IOException try { // Close stream @@ -158,10 +163,9 @@ protected void shutdown() { } catch (IOException e) { // Indicate exception logger.error("Exception in shutdown", e); - } + } } - /** * Start the server */ @@ -169,12 +173,11 @@ protected void shutdown() { public void start() { // Create thread thread = new Thread(this); - + // Start thread thread.start(); } - /** * Stop the server and block until the server thread is finished */ @@ -182,12 +185,15 @@ public void start() { public void stop() { // Shutdown thread shutdown(); - + // Wait for thread end - try {thread.join();} catch (InterruptedException e) {logger.error("Exception in stop", e);} + try { + thread.join(); + } catch (InterruptedException e) { + logger.error("Exception in stop", e); + } } - /** * Change service name */ @@ -195,12 +201,11 @@ public void stop() { public BaSyxService setName(String newName) { // Store name name = newName; - + // Return 'this' instance return this; } - /** * Return service name */ @@ -209,17 +214,19 @@ public String getName() { // Return service name return name; } - - + /** * Wait for end of runnable */ public void waitFor() { // Wait for thread end - try {thread.join();} catch (InterruptedException e) {logger.error("Exception in waitFor", e);} + try { + thread.join(); + } catch (InterruptedException e) { + logger.error("Exception in waitFor", e); + } } - - + /** * Indicate if this service has ended */ @@ -228,4 +235,3 @@ public boolean hasEnded() { return !serverSockChannel.isOpen(); } } - diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java b/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java index b67c0b00..9e9a04f0 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/basyx/server/VABBaSyxTCPInterface.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.basyx.server; @@ -106,7 +121,7 @@ public void processInputFrame(byte[] rxFrame) throws IOException { logger.debug("Exception in BASYX_GET", e); // Catch Exceptions from JSONProvider // No further action here, as the current version - // of the TCP-Mapping states, that always Statuscode 0x00 + // of the TCP-Mapping states, that always Statuscode 0x00 // should be returned with Exceptions encoded in returned String } @@ -134,7 +149,7 @@ public void processInputFrame(byte[] rxFrame) throws IOException { logger.debug("Exception in BASYX_SET", e); // Catch Exceptions from JSONProvider // No further action here, as the current version - // of the TCP-Mapping states, that always Statuscode 0x00 + // of the TCP-Mapping states, that always Statuscode 0x00 // should be returned with Exceptions encoded in returned String } @@ -160,7 +175,7 @@ public void processInputFrame(byte[] rxFrame) throws IOException { logger.debug("Exception in BASYX_CREATE", e); // Catch Exceptions from JSONProvider // No further action here, as the current version - // of the TCP-Mapping states, that always Statuscode 0x00 + // of the TCP-Mapping states, that always Statuscode 0x00 // should be returned with Exceptions encoded in returned String } @@ -195,7 +210,7 @@ public void processInputFrame(byte[] rxFrame) throws IOException { logger.debug("Exception in BASYX_DELETE", e); // Catch Exceptions from JSONProvider // No further action here, as the current version - // of the TCP-Mapping states, that always Statuscode 0x00 + // of the TCP-Mapping states, that always Statuscode 0x00 // should be returned with Exceptions encoded in returned String } @@ -220,7 +235,7 @@ public void processInputFrame(byte[] rxFrame) throws IOException { logger.debug("Exception in BASYX_INVOKE", e); // Catch Exceptions from JSONProvider // No further action here, as the current version - // of the TCP-Mapping states, that always Statuscode 0x00 + // of the TCP-Mapping states, that always Statuscode 0x00 // should be returned with Exceptions encoded in returned String } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java index e79b77a4..f7dd3b1d 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnector.java @@ -1,23 +1,46 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.connector; +import java.util.List; +import java.util.Map; +import java.util.Optional; + import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation.Builder; import javax.ws.rs.client.WebTarget; +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.basyx.vab.coder.json.metaprotocol.Message; +import org.eclipse.basyx.vab.coder.json.metaprotocol.MessageType; +import org.eclipse.basyx.vab.coder.json.metaprotocol.Result; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.basyx.vab.protocol.api.IBaSyxConnector; @@ -25,6 +48,9 @@ import org.glassfish.jersey.client.HttpUrlConnectorProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.lang.Nullable; + +import com.google.gson.Gson; import io.netty.handler.codec.http.HttpMethod; @@ -35,11 +61,13 @@ * */ public class HTTPConnector implements IBaSyxConnector { - + private static Logger logger = LoggerFactory.getLogger(HTTPConnector.class); - + private String address; private String mediaType; + @Nullable + private final IAuthorizationSupplier authorizationSupplier; protected Client client; /** @@ -58,10 +86,19 @@ public HTTPConnector(String address) { this(address, MediaType.APPLICATION_JSON + ";charset=UTF-8"); } + public HTTPConnector(String address, final IAuthorizationSupplier authorizationSupplier) { + this(address, MediaType.APPLICATION_JSON + ";charset=UTF-8", authorizationSupplier); + } + public HTTPConnector(String address, String mediaType) { + this(address, mediaType, null); + } + + public HTTPConnector(final String address, final String mediaType, @Nullable final IAuthorizationSupplier authorizationSupplier) { this.address = address; this.mediaType = mediaType; - + this.authorizationSupplier = authorizationSupplier; + // Create client client = ClientBuilder.newClient(); @@ -132,10 +169,16 @@ protected Builder buildRequest(Client client, String wsURL) { // Build request, set JSON encoding Builder request = resource.request(); request.accept(mediaType); + getAuthorization().ifPresent(authorization -> request.header(HttpHeaders.AUTHORIZATION, authorization)); + // Return JSON request return request; } + private Optional getAuthorization() { + return Optional.ofNullable(authorizationSupplier).flatMap(IAuthorizationSupplier::getAuthorization); + } + /** * Create web service path */ @@ -152,7 +195,7 @@ protected String createWSPath(String part1, String part2) { return part1 + "/" + part2; } - + /** * Perform a HTTP get request * @@ -170,7 +213,7 @@ private String httpGet(String servicePath) throws ProviderException { rsp = request.get(); } finally { if (!isRequestSuccess(rsp)) { - throw this.handleProcessingException(HttpMethod.GET, getStatusCode(rsp)); + throw this.handleProcessingException(HttpMethod.GET, rsp); } } @@ -189,7 +232,7 @@ private String httpPut(String servicePath, String newValue) throws ProviderExcep rsp = request.put(Entity.entity(newValue, mediaType)); } finally { if (!isRequestSuccess(rsp)) { - throw this.handleProcessingException(HttpMethod.PUT, getStatusCode(rsp)); + throw this.handleProcessingException(HttpMethod.PUT, rsp); } } @@ -204,10 +247,12 @@ private String httpPatch(String servicePath, String newValue) throws ProviderExc // Create and invoke HTTP PATCH request Response rsp = null; try { - rsp = this.client.target(VABPathTools.concatenatePaths(address, servicePath)).request().build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke(); + final Builder request = this.client.target(VABPathTools.concatenatePaths(address, servicePath)).request(); + getAuthorization().ifPresent(authorization -> request.header(HttpHeaders.AUTHORIZATION, authorization)); + rsp = request.build("PATCH", Entity.text(newValue)).property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true).invoke(); } finally { if (!isRequestSuccess(rsp)) { - throw this.handleProcessingException(HttpMethod.PATCH, getStatusCode(rsp)); + throw this.handleProcessingException(HttpMethod.PATCH, rsp); } } @@ -226,7 +271,7 @@ private String httpPost(String servicePath, String parameter) throws ProviderExc rsp = request.post(Entity.entity(parameter, mediaType)); } finally { if (!isRequestSuccess(rsp)) { - throw this.handleProcessingException(HttpMethod.POST, getStatusCode(rsp)); + throw this.handleProcessingException(HttpMethod.POST, rsp); } } @@ -245,7 +290,7 @@ private String httpDelete(String servicePath) throws ProviderException { rsp = request.delete(); } finally { if (!isRequestSuccess(rsp)) { - throw this.handleProcessingException(HttpMethod.DELETE, getStatusCode(rsp)); + throw this.handleProcessingException(HttpMethod.DELETE, rsp); } } @@ -269,25 +314,36 @@ private Builder retrieveBuilder(String servicePath) { return buildRequest(client, VABPathTools.concatenatePaths(address, servicePath)); } - private ProviderException handleProcessingException(HttpMethod method, int statusCode) { - if (statusCode == 0) { - return ExceptionToHTTPCodeMapper.mapToException(404, "[HTTP " + method.name() + "] Failed to request " + this.address + " with mediatype " + this.mediaType); - } else { - return ExceptionToHTTPCodeMapper.mapToException(statusCode, "[HTTP " + method.name() + "] Failed to request " + this.address + " with mediatype " + this.mediaType); + private ProviderException handleProcessingException(HttpMethod method, Response rsp) { + if (rsp == null) { + return ExceptionToHTTPCodeMapper.mapToException(404, buildMessageString(method.name(), null)); } + + int statusCode = getStatusCode(rsp); + String responseJson = rsp.readEntity(String.class); + + Result result = buildResultFromJSON(responseJson); + + List messages = result.getMessages(); + messages.add(new Message(MessageType.Exception, buildMessageString(method.name(), result))); + + ProviderException e = ExceptionToHTTPCodeMapper.mapToException(statusCode, result.getMessages()); + return e; } - + /** * Get status code from HTTP Response + * * @param rsp * @return */ private int getStatusCode(Response rsp) { return rsp != null ? rsp.getStatus() : 0; } - + /** * Returns true if the response is succeeded + * * @param rsp * @return */ @@ -296,12 +352,56 @@ private boolean isRequestSuccess(Response rsp) { } /** - * Get string representation of endpoint for given path for debugging. - * @param path Requested path + * Get string representation of endpoint for given path for debugging. + * + * @param path + * Requested path * @return String representing requested endpoint */ @Override public String getEndpointRepresentation(String path) { return VABPathTools.concatenatePaths(address, path); } + + /** + * Builds a Result object from the json response + * + * @param json + * The json response + * @return Result + */ + @SuppressWarnings("unchecked") + private Result buildResultFromJSON(String json) { + Gson gson = new Gson(); + Map map = gson.fromJson(json, Map.class); + return Result.createAsFacade(map); + } + + /** + * Builds the text for the message about the failed HTTP Request + * + * @param methodName + * the HTTP method that failed + * @param result + * the Messages returned by the server if any + * @return the message text + */ + private String buildMessageString(String methodName, Result result) { + String message = "[HTTP " + methodName + "] Failed to request " + this.address + " with mediatype " + this.mediaType; + + if (result == null) { + return message; + } + + String text = ""; + if (result.getMessages().size() > 0) { + text = result.getMessages().get(0).getText(); + } + + if (!text.isEmpty()) { + message += ". \"" + text + "\""; + } + + return message; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java index 38971ee4..e1ab6add 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/HTTPConnectorFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.connector; diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/IAuthorizationSupplier.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/IAuthorizationSupplier.java new file mode 100644 index 00000000..3a1dd17b --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/IAuthorizationSupplier.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.http.connector; + +import java.util.Optional; + +/** + * Interface for a supplier of values that can be placed in the HTTP + * Authorization request header. + * + * @author pneuschwander + */ +@FunctionalInterface +public interface IAuthorizationSupplier { + + /** + * Might provide a value that can be placed in the HTTP Authorization request + * header. + * + * @return Optional that is either empty or contains a non-blank String that can + * be placed in the HTTP Authorization request header + */ + Optional getAuthorization(); +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/OAuth2ClientCredentialsBasedAuthorizationSupplier.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/OAuth2ClientCredentialsBasedAuthorizationSupplier.java new file mode 100644 index 00000000..6cf7fc63 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/connector/OAuth2ClientCredentialsBasedAuthorizationSupplier.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.http.connector; + +import java.text.ParseException; +import java.util.Date; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.StringUtils; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.lang.Nullable; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTParser; + +/** + * Supplier for Bearer Token based HTTP Authorization request header values + * utilizing the OAuth2 Client Credentials Grant Flow and JSON Web Tokens. + * + * @author pneuschwander + * @see https://tools.ietf.org/html/rfc6749#section-4.4 + * (OAuth2 Client Credentials Grant) + * @see https://tools.ietf.org/html/rfc7519 + * (JSON Web Token (JWT)) + * @see https://tools.ietf.org/html/rfc6750 + * (Bearer Token Usage) + */ +public class OAuth2ClientCredentialsBasedAuthorizationSupplier implements IAuthorizationSupplier { + private static final Logger logger = LoggerFactory.getLogger(OAuth2ClientCredentialsBasedAuthorizationSupplier.class); + private static final String SCOPE_DELIMITER = " "; + private static final String BEARER_TOKEN_PREFIX = "Bearer "; + + private final Client client; + private final JsonParser jsonParser; + private final String tokenEndpoint; + private final Set scopes; + private final AtomicReference cachedAccessTokenReference; + + /** + * Provides supplier for Bearer Token based HTTP Authorization request header + * values utilizing the OAuth2 Client Credentials Grant Flow and JSON Web + * Tokens. + * + * @param tokenEndpoint + * The address of the tokenEndpoint of the Authorization Server + * @param clientId + * The client identifier issued to the client during the registration + * process + * @param clientSecret + * The client secret + * @param scopes + * Set of scopes to be requested from the Authorization Server + */ + public OAuth2ClientCredentialsBasedAuthorizationSupplier(final String tokenEndpoint, final String clientId, final String clientSecret, final Set scopes) { + this.client = ClientBuilder.newClient(); + this.client.register(HttpAuthenticationFeature.basicBuilder().credentials(clientId, clientSecret).build()); + this.jsonParser = new JsonParser(); + this.tokenEndpoint = tokenEndpoint; + this.scopes = new HashSet<>(scopes); + this.cachedAccessTokenReference = new AtomicReference<>(); + } + + @Override + public Optional getAuthorization() { + return Optional.ofNullable(this.getAccessToken()).map(JWT::getParsedString).map(str -> BEARER_TOKEN_PREFIX + str); + } + + @Nullable + private JWT getAccessToken() { + final JWT cachedAccessToken = this.cachedAccessTokenReference.get(); + if (isValidToken(cachedAccessToken)) { + return cachedAccessToken; + } + final JWT freshAccessToken = getFreshAccessToken(); + this.cachedAccessTokenReference.set(freshAccessToken); + return freshAccessToken; + } + + private boolean isValidToken(@Nullable final JWT jwt) { + return jwt != null && !isExpiredToken(jwt); + } + + private boolean isExpiredToken(final JWT jwt) { + try { + final Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime(); + if (expirationTime == null) { + return false; + } + return isPastDate(expirationTime); + } catch (ParseException e) { + logger.warn(e.getMessage(), e); + } + return true; + } + + private boolean isPastDate(final Date date) { + final Date now = new Date(); + return now.after(date); + } + + @Nullable + private JWT getFreshAccessToken() { + try { + final Response response = requestToken(); + final String accessToken = getAccessTokenFromResponse(response); + if (StringUtils.isNotBlank(accessToken)) { + return JWTParser.parse(accessToken); + } + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } + + return null; + } + + private Response requestToken() { + return this.client.target(this.tokenEndpoint).request().post(Entity.form(new Form().param("grant_type", "client_credentials").param("scope", String.join(SCOPE_DELIMITER, this.scopes)))); + } + + private String getAccessTokenFromResponse(final Response response) { + final String responseString = response.readEntity(String.class); + final JsonElement responseEl = jsonParser.parse(responseString); + return responseEl.getAsJsonObject().get("access_token").getAsString(); + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/helper/HTTPUploadHelper.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/helper/HTTPUploadHelper.java new file mode 100644 index 00000000..f42f3884 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/helper/HTTPUploadHelper.java @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.vab.protocol.http.helper; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +/** + * Helper class to achieve http post multipart/form-data upload + * + * @author haque + * + */ +public class HTTPUploadHelper { + + /** + * Uploads the given stream to the given API URL + * + * @param stream + * @param url + * @throws IOException + * @throws ClientProtocolException + */ + public static void uploadHTTPPost(InputStream stream, String url) throws ClientProtocolException, IOException { + CloseableHttpClient httpClient = getDefautlHTTPClient(); + HttpPost uploadPost = getUploadHTTPPost(stream, url); + executeUploadHTTPPost(httpClient, uploadPost); + } + + /** + * Executes the client with multipart entity as a post file + * + * @param httpClient + * @param uploadFile + * @throws ClientProtocolException + * @throws IOException + */ + private static void executeUploadHTTPPost(CloseableHttpClient httpClient, HttpPost uploadFile) throws ClientProtocolException, IOException { + CloseableHttpResponse response = httpClient.execute(uploadFile); + response.close(); + } + + /** + * Gets a default HTTP client + * + * @return + * @throws FileNotFoundException + */ + private static CloseableHttpClient getDefautlHTTPClient() throws FileNotFoundException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + return httpClient; + } + + /** + * Gets HTTP post with a multipart entity + * + * @param stream + * @param url + * @return + * @throws FileNotFoundException + */ + private static HttpPost getUploadHTTPPost(InputStream stream, String url) throws FileNotFoundException { + HttpPost uploadFile = new HttpPost(url); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + + builder.addBinaryBody("file", stream, ContentType.MULTIPART_FORM_DATA, ""); + + HttpEntity multipart = builder.build(); + uploadFile.setEntity(multipart); + return uploadFile; + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java index 9b776907..8d8e5967 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxContext.java @@ -1,47 +1,58 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; -import java.util.HashMap; +import org.springframework.lang.Nullable; +import java.util.LinkedHashMap; import java.util.Map; - +import java.util.Optional; import javax.servlet.http.HttpServlet; - - /** - * BaSyx context that contains an Industrie 4.0 Servlet infrastructure + * BaSyx context that contains an Industrie 4.0 Servlet infrastructure * * @author kuhn, haque * */ -public class BaSyxContext extends HashMap { +public class BaSyxContext extends LinkedHashMap { - /** * Version of serialized instance */ private static final long serialVersionUID = 1L; - - + /** * Requested server context path */ protected String contextPath; - - + /** * Requested server documents base path */ protected String docBasePath; - + /** * hostname, e.g. ip or localhost */ @@ -51,30 +62,32 @@ public class BaSyxContext extends HashMap { * Requested Tomcat apache port */ protected int port; - + /** * Indicates whether the connection is secures or not */ private boolean isSecuredConnection; - + /** * Password of the SSL key */ private String keyPassword; - + /** * Path to the certificate */ private String certificatePath; - + /** * Servlet parameter */ - protected Map> servletParameter = new HashMap<>(); - + protected Map> servletParameter = new LinkedHashMap<>(); public Object AASHTTPServerResource; - + + @Nullable + private JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration; + /** * Constructor with default port */ @@ -83,42 +96,53 @@ public BaSyxContext(String reqContextPath, String reqDocBasePath) { this(reqContextPath, reqDocBasePath, "localhost", 8080); } - /** * Initiates a BasyxContext - * @param reqContextPath context path - * @param reqDocBasePath base path of doc - * @param hostn host name - * @param reqPort connection port + * + * @param reqContextPath + * context path + * @param reqDocBasePath + * base path of doc + * @param hostn + * host name + * @param reqPort + * connection port */ public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort) { // Store context path and doc base path contextPath = reqContextPath; docBasePath = reqDocBasePath; hostname = hostn; - port = reqPort; + port = reqPort; isSecuredConnection = false; } - + /** - * Initiates a BasyxContext. this constructor can indicate whether - * the connection is secured or not - * @param reqContextPath context path - * @param reqDocBasePath base path of doc - * @param hostn host name - * @param reqPort connection port - * @param isSecuredCon boolean value indicating the connection is secured or not - * @param keyPass password of the SSL key - * @param keyPath path to the SSL certificate + * Initiates a BasyxContext. this constructor can indicate whether the + * connection is secured or not + * + * @param reqContextPath + * context path + * @param reqDocBasePath + * base path of doc + * @param hostn + * host name + * @param reqPort + * connection port + * @param isSecuredCon + * boolean value indicating the connection is secured or not + * @param keyPass + * password of the SSL key + * @param keyPath + * path to the SSL certificate */ - public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort, boolean isSecuredCon, String keyPath, String keyPass) { + public BaSyxContext(String reqContextPath, String reqDocBasePath, String hostn, int reqPort, boolean isSecuredCon, String keyPath, String keyPass) { this(reqContextPath, reqDocBasePath, hostn, reqPort); this.isSecuredConnection = isSecuredCon; this.certificatePath = keyPath; this.keyPassword = keyPass; } - - + /** * Add a servlet mapping */ @@ -136,7 +160,7 @@ public BaSyxContext addServletMapping(String key, HttpServlet servlet) { public BaSyxContext addServletMapping(String key, HttpServlet servlet, Map servletParameter) { // Add servlet mapping addServletMapping(key, servlet); - + // Add Servlet parameter addServletParameter(key, servletParameter); @@ -144,41 +168,53 @@ public BaSyxContext addServletMapping(String key, HttpServlet servlet, Map parameter) { // Add servlet parameter servletParameter.put(key, parameter); - + // Return 'this' reference to enable chaining of operations return this; } - - - + /** * Get servlet parameter */ public Map getServletParameter(String key) { // Return servlet parameter iff parameter map contains requested key - if (servletParameter.containsKey(key)) return servletParameter.get(key); - + if (servletParameter.containsKey(key)) + return servletParameter.get(key); + // Return empty map - return new HashMap(); + return new LinkedHashMap(); } - - + /** * Return Tomcat server port */ public int getPort() { return port; } - + + /** + * Return Tomcat context path. + */ + public String getContextPath() { + return contextPath; + } + + /** + * Return Tomcat hostname. + */ + public String getHostname() { + return hostname; + } + /** * Returns whether the secured connection enabled or not + * * @return */ public boolean isSecuredConnectionEnabled() { @@ -187,37 +223,45 @@ public boolean isSecuredConnectionEnabled() { /** * Returns password of the SSL key + * * @return */ public String getKeyPassword() { return keyPassword; } - /** * Sets password of the SSL key + * * @param keyPassword */ public void setKeyPassword(String keyPassword) { this.keyPassword = keyPassword; } - /** * Returns Path to the certificate + * * @return */ public String getCertificatePath() { return certificatePath; } - /** * Sets Certificate Path + * * @param certificatePath */ public void setCertificatePath(String certificatePath) { this.certificatePath = certificatePath; } -} + public Optional getJwtBearerTokenAuthenticationConfiguration() { + return Optional.ofNullable(jwtBearerTokenAuthenticationConfiguration); + } + + public void setJwtBearerTokenAuthenticationConfiguration(@Nullable final JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration) { + this.jwtBearerTokenAuthenticationConfiguration = jwtBearerTokenAuthenticationConfiguration; + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java index 3364aefd..0a811811 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BaSyxHTTPServer.java @@ -1,20 +1,39 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; import java.io.File; +import java.util.ArrayList; +import java.util.Collection; import java.util.EnumSet; import java.util.Iterator; +import java.util.List; import java.util.Map.Entry; import java.util.UUID; +import javax.servlet.Filter; import javax.servlet.http.HttpServlet; import org.apache.catalina.Context; @@ -24,31 +43,56 @@ import org.apache.catalina.LifecycleState; import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.Tomcat; +import org.apache.tomcat.util.descriptor.web.FilterDef; +import org.apache.tomcat.util.descriptor.web.FilterMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.lang.Nullable; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; +import org.springframework.security.oauth2.core.OAuth2TokenValidator; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtClaimNames; +import org.springframework.security.oauth2.jwt.JwtClaimValidator; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.JwtValidators; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; +import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; +import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.ExceptionTranslationFilter; +import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.security.web.firewall.StrictHttpFirewall; +import org.springframework.security.web.util.matcher.AnyRequestMatcher; /** - * Starter Class for Apache Tomcat HTTP server that adds the provided servlets and respective mappings on startup. + * Starter Class for Apache Tomcat HTTP server that adds the provided servlets + * and respective mappings on startup. * * @author pschorn, espen, haque * */ public class BaSyxHTTPServer { - - private static Logger logger = LoggerFactory.getLogger(BaSyxHTTPServer.class); - - private Tomcat tomcat; + + private static final Logger logger = LoggerFactory.getLogger(BaSyxHTTPServer.class); + + private final Tomcat tomcat; static { // Enable coding of forward slash in tomcat System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true"); - + // Throw exception on startup error, unless user explicitly disables it if (System.getProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE") == null) { System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true"); } } - + /** * Constructor * @@ -65,14 +109,14 @@ public BaSyxHTTPServer(BaSyxContext context) { // Set random name to prevent lifecycle expections during shutdown of multiple // instances tomcat.getEngine().setName(UUID.randomUUID().toString()); - + if (context.isSecuredConnectionEnabled()) { Connector httpsConnector = tomcat.getConnector(); configureSslConnector(context, httpsConnector); } else { tomcat.setPort(context.port); } - + tomcat.setHostname(context.hostname); tomcat.getHost().setAppBase("."); @@ -80,7 +124,9 @@ public BaSyxHTTPServer(BaSyxContext context) { // - Base path for resource files File docBase = new File(context.docBasePath); // System.getProperty("java.io.tmpdir")); // - Create context for servlets - Context rootCtx = tomcat.addContext(context.contextPath, docBase.getAbsolutePath()); + final Context rootCtx = tomcat.addContext(context.contextPath, docBase.getAbsolutePath()); + + context.getJwtBearerTokenAuthenticationConfiguration().ifPresent(jwtBearerTokenAuthenticationConfiguration -> addSecurityFiltersToContext(rootCtx, jwtBearerTokenAuthenticationConfiguration)); // Iterate all servlets in context Iterator> it = context.entrySet().iterator(); @@ -97,9 +143,97 @@ public BaSyxHTTPServer(BaSyxContext context) { rootCtx.addServletMappingDecoded(mapping, Integer.toString(servlet.hashCode())); } } - + + private void addSecurityFiltersToContext(final Context context, final JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration) { + final FilterChainProxy filterChainProxy = createFilterChainProxy(jwtBearerTokenAuthenticationConfiguration); + addFilterChainProxyFilterToContext(context, filterChainProxy); + } + + private void addFilterChainProxyFilterToContext(final Context context, final FilterChainProxy filterChainProxy) { + final FilterDef filterChainProxyFilterDefinition = createFilterChainProxyFilterDefinition(filterChainProxy); + context.addFilterDef(filterChainProxyFilterDefinition); + + final FilterMap filterChainProxyFilterMapping = createFilterChainProxyFilterMap(); + context.addFilterMap(filterChainProxyFilterMapping); + } + + private FilterMap createFilterChainProxyFilterMap() { + final FilterMap filterChainProxyFilterMapping = new FilterMap(); + filterChainProxyFilterMapping.setFilterName(FilterChainProxy.class.getSimpleName()); + filterChainProxyFilterMapping.addURLPattern("/*"); + return filterChainProxyFilterMapping; + } + + private FilterDef createFilterChainProxyFilterDefinition(final FilterChainProxy filterChainProxy) { + final FilterDef filterChainProxyFilterDefinition = new FilterDef(); + filterChainProxyFilterDefinition.setFilterName(FilterChainProxy.class.getSimpleName()); + filterChainProxyFilterDefinition.setFilterClass(FilterChainProxy.class.getName()); + filterChainProxyFilterDefinition.setFilter(filterChainProxy); + return filterChainProxyFilterDefinition; + } + + private FilterChainProxy createFilterChainProxy(final JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration) { + final FilterChainProxy filterChainProxy = new FilterChainProxy(createSecurityFilterChain(jwtBearerTokenAuthenticationConfiguration)); + filterChainProxy.setFirewall(createHttpFirewall()); + return filterChainProxy; + } + + private HttpFirewall createHttpFirewall() { + final StrictHttpFirewall httpFirewall = new StrictHttpFirewall(); + + // '/' is valid character in an Internationalized Resource Identifier (IRI) + httpFirewall.setAllowUrlEncodedSlash(true); + + return httpFirewall; + } + + private SecurityFilterChain createSecurityFilterChain(final JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration) { + final List sortedListOfFilters = new ArrayList<>(); + + sortedListOfFilters.add(createBearerTokenAuthenticationFilter(jwtBearerTokenAuthenticationConfiguration)); + sortedListOfFilters.add(createExceptionTranslationFilter()); + + return new DefaultSecurityFilterChain(AnyRequestMatcher.INSTANCE, sortedListOfFilters); + } + + private ExceptionTranslationFilter createExceptionTranslationFilter() { + final BearerTokenAuthenticationEntryPoint authenticationEntryPoint = new BearerTokenAuthenticationEntryPoint(); + return new ExceptionTranslationFilter(authenticationEntryPoint); + } + + private BearerTokenAuthenticationFilter createBearerTokenAuthenticationFilter(final JwtBearerTokenAuthenticationConfiguration jwtBearerTokenAuthenticationConfiguration) { + final JwtDecoder jwtDecoder = createJwtDecoder(jwtBearerTokenAuthenticationConfiguration.getIssuerUri(), jwtBearerTokenAuthenticationConfiguration.getJwkSetUri(), + jwtBearerTokenAuthenticationConfiguration.getRequiredAud().orElse(null)); + final JwtAuthenticationProvider jwtAuthenticationProvider = new JwtAuthenticationProvider(jwtDecoder); + final AuthenticationManager authenticationManager = new ProviderManager(jwtAuthenticationProvider); + return new BearerTokenAuthenticationFilter(authenticationManager); + } + + private JwtDecoder createJwtDecoder(final String issuerUri, final String jwkSetUri, @Nullable final String requiredAud) { + final NimbusJwtDecoder nimbusJwtDecoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).jwsAlgorithm(SignatureAlgorithm.from("RS256")).build(); + nimbusJwtDecoder.setJwtValidator(createOAuth2TokenValidator(issuerUri, requiredAud)); + + return nimbusJwtDecoder; + } + + private OAuth2TokenValidator createOAuth2TokenValidator(final String issuerUri, @Nullable final String requiredAud) { + List> validators = new ArrayList<>(); + validators.add(JwtValidators.createDefaultWithIssuer(issuerUri)); + + if (requiredAud != null) { + validators.add(createJwtClaimValidatorForRequiredAudience(requiredAud)); + } + + return new DelegatingOAuth2TokenValidator<>(validators); + } + + private JwtClaimValidator> createJwtClaimValidatorForRequiredAudience(final String requiredAud) { + return new JwtClaimValidator<>(JwtClaimNames.AUD, aud -> null != aud && aud.contains(requiredAud)); + } + /** * SSL Configuration for SSL connector + * * @param context * @param httpsConnector */ @@ -113,13 +247,13 @@ private void configureSslConnector(BaSyxContext context, Connector httpsConnecto httpsConnector.setAttribute("SSLEnabled", true); httpsConnector.setAttribute("protocol", "HTTP/1.1"); httpsConnector.setAttribute("keystorePass", context.getKeyPassword()); - + httpsConnector.setAttribute("keyAlias", "tomcat"); - + httpsConnector.setAttribute("maxThreads", "200"); httpsConnector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol"); - } - + } + /** * Starts the server in a new thread to avoid blocking the main thread * @@ -127,21 +261,25 @@ private void configureSslConnector(BaSyxContext context, Connector httpsConnecto * This method blocks until the server is up and running. * *

- * If an error occurs during server startup the process is aborted and the method returns immediately. - * {@link #hasEnded()} returns true in this case. - *
This behavior can be disabled by setting the system property - * org.apache.catalina.startup.EXIT_ON_INIT_FAILURE = false, for instance with the -D - * command line option when launching the JVM, or through {@link System#setProperty(String, String)} (before the - * first call to {@link BaSyxHTTPServer}). In this case the startup is finished regardless of any errors and - * subsequent calls to {@link #hasEnded()} return false, but the server might be left in an undefined - * and non-functional state. + * If an error occurs during server startup the process is aborted and the + * method returns immediately. {@link #hasEnded()} returns true in + * this case.
+ * This behavior can be disabled by setting the system property + * org.apache.catalina.startup.EXIT_ON_INIT_FAILURE = false, for + * instance with the -D command line option when launching the JVM, + * or through {@link System#setProperty(String, String)} (before the first call + * to {@link BaSyxHTTPServer}). In this case the startup is finished regardless + * of any errors and subsequent calls to {@link #hasEnded()} return + * false, but the server might be left in an undefined and + * non-functional state. * *

- * TODO: Throw exception upon startup failure. This is a breaking change, so wait until next major version. + * TODO: Throw exception upon startup failure. This is a breaking change, so + * wait until next major version. */ public void start() { logger.trace("Starting Tomcat....."); - + Thread serverThread = new Thread(() -> { try { tomcat.stop(); @@ -159,19 +297,19 @@ public void lifecycleEvent(LifecycleEvent event) { }); tomcat.start(); - + // Keeps the server thread alive until the server is shut down tomcat.getServer().await(); } catch (LifecycleException e) { logger.error("Failed to start HTTP server.", e); - + synchronized (tomcat) { tomcat.notifyAll(); } } }); serverThread.start(); - + // Wait until tomcat is started before returning EnumSet returnStates = EnumSet.of(LifecycleState.STARTED, LifecycleState.FAILED); synchronized (tomcat) { @@ -187,12 +325,13 @@ public void lifecycleEvent(LifecycleEvent event) { } /** - * This Method stops and destroys the tomcat instance. This is important since Tomcat would be already - * bound to port 8080 when new tests are run that require a start of tomcat + * This Method stops and destroys the tomcat instance. This is important since + * Tomcat would be already bound to port 8080 when new tests are run that + * require a start of tomcat */ public void shutdown() { logger.trace("Shutting down BaSyx HTTP Server..."); - + try { tomcat.stop(); tomcat.destroy(); @@ -201,11 +340,12 @@ public void shutdown() { logger.error("Exception in shutdown", e); } } - + /** * Returns a value indicating whether the server is currently running. * - * @return false if the server is running, true otherwise. + * @return false if the server is running, true + * otherwise. */ public boolean hasEnded() { return tomcat.getServer().getState() != LifecycleState.STARTED; diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java index be0af719..d0d5f09a 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/BasysHTTPServlet.java @@ -1,17 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; import java.io.IOException; import java.io.PrintWriter; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.ServletException; @@ -24,69 +39,64 @@ /** * HTTP Servelet superclass to enable HTTP Patch + * * @author pschorn * */ public abstract class BasysHTTPServlet extends HttpServlet { - /** * Version of serialized instances */ private static final long serialVersionUID = 1L; - - + /** * Parameter map */ - protected Map servletParameter = new HashMap<>(); + protected Map servletParameter = new LinkedHashMap<>(); /** * GSON instance */ protected GSONTools serializer = new GSONTools(new DefaultTypeFactory()); - - /** - * Dispatch service call + * Dispatch service call */ @Override public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (request.getMethod().equalsIgnoreCase("PATCH")){ - doPatch(request, response); - } else { - super.service(request, response); - } - } - - + if (request.getMethod().equalsIgnoreCase("PATCH")) { + doPatch(request, response); + } else { + super.service(request, response); + } + } + + /** + * Implement Patch request + */ + protected abstract void doPatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; + /** - * Implement Patch request + * Add a servlet parameter */ - protected abstract void doPatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; - - - /** - * Add a servlet parameter - */ - - public BasysHTTPServlet withParameter(String parameter, String value) { - // Add parameter - servletParameter.put(parameter, value); - - // Return this instance - return this; - } - - + + public BasysHTTPServlet withParameter(String parameter, String value) { + // Add parameter + servletParameter.put(parameter, value); + + // Return this instance + return this; + } + /** * Get init parameter of servlet */ @Override public String getInitParameter(String name) { // Check if servletParameter map contains requested parameter - if (servletParameter.containsKey(name)) return servletParameter.get(name); + if (servletParameter.containsKey(name)) + return servletParameter.get(name); // Call base method return super.getInitParameter(name); @@ -102,4 +112,3 @@ protected void sendResponse(Object value, PrintWriter outputStream) { } } - diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java index bcc23ea8..8c4c12c7 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/ExceptionToHTTPCodeMapper.java @@ -1,14 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; +import java.util.List; + +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException; @@ -22,35 +40,36 @@ */ public class ExceptionToHTTPCodeMapper { - /** * Maps ProviderExceptions to HTTP-Codes * - * @param e The thrown ProviderException + * @param e + * The thrown ProviderException * @return HTTP-Code */ public static int mapFromException(ProviderException e) { if (e instanceof MalformedRequestException) { return 400; - } else if(e instanceof ResourceAlreadyExistsException) { + } else if (e instanceof ResourceAlreadyExistsException) { return 422; - } else if(e instanceof ResourceNotFoundException) { + } else if (e instanceof ResourceNotFoundException) { return 404; } return 500; - + } - + /** * Maps HTTP-Codes to ProviderExceptions * - * @param statusCode The received HTTP-code + * @param statusCode + * The received HTTP-code * @return the corresponding ProviderException */ public static ProviderException mapToException(int statusCode, String text) { - - switch(statusCode) { + + switch (statusCode) { case 400: return new MalformedRequestException(text); case 422: @@ -60,7 +79,29 @@ public static ProviderException mapToException(int statusCode, String text) { default: return new ProviderException(text); } - + + } + + /** + * Maps HTTP-Codes to ProviderExceptions + * + * @param statusCode + * The received HTTP-code + * @return the corresponding ProviderException + */ + public static ProviderException mapToException(int statusCode, List messages) { + + switch (statusCode) { + case 400: + return new MalformedRequestException(messages); + case 422: + return new ResourceAlreadyExistsException(messages); + case 404: + return new ResourceNotFoundException(messages); + default: + return new ProviderException(messages); + } + } - + } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/JwtBearerTokenAuthenticationConfiguration.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/JwtBearerTokenAuthenticationConfiguration.java new file mode 100644 index 00000000..df1ebdb5 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/JwtBearerTokenAuthenticationConfiguration.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.http.server; + +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.lang.Nullable; + +/** + * Configuration for a Resource Server to support JWT Bearer Tokens for + * authentication. + * + * @author pneuschwander + */ +public class JwtBearerTokenAuthenticationConfiguration { + private final String issuerUri; + private final String jwkSetUri; + @Nullable + private final String requiredAud; + + private JwtBearerTokenAuthenticationConfiguration(final String issuerUri, final String jwkSetUri, @Nullable final String requiredAud) { + this.issuerUri = issuerUri; + this.jwkSetUri = jwkSetUri; + this.requiredAud = requiredAud; + } + + /** + * Provides configuration for a Resource Server to support JWT Bearer Tokens for + * authentication. + * + * @param issuerUri + * URI addressing the Token Issuer / Authorization Server + * @param jwkSetUri + * URI addressing the JWK Set to be used to decode and validate JWTs + * @param requiredAud + * Audience the JWT has to contain in order to be accepted + */ + public static JwtBearerTokenAuthenticationConfiguration of(final String issuerUri, final String jwkSetUri, @Nullable final String requiredAud) { + if (!isValidIssuerUri(issuerUri)) { + throw new IllegalArgumentException("invalid issuerUri"); + } + if (!isValidJwkSetUri(jwkSetUri)) { + throw new IllegalArgumentException("invalid jwkSetUri"); + } + if (requiredAud != null && !isValidRequiredAudience(requiredAud)) { + throw new IllegalArgumentException("invalid requiredAud"); + } + return new JwtBearerTokenAuthenticationConfiguration(issuerUri, jwkSetUri, requiredAud); + } + + private static boolean isValidIssuerUri(@Nullable final String issuerUri) { + return StringUtils.isNotBlank(issuerUri); + } + + private static boolean isValidJwkSetUri(@Nullable final String jwkSetUri) { + return StringUtils.isNotBlank(jwkSetUri); + } + + private static boolean isValidRequiredAudience(@Nullable final String requiredAud) { + return StringUtils.isNotBlank(requiredAud); + } + + public String getIssuerUri() { + return issuerUri; + } + + public String getJwkSetUri() { + return jwkSetUri; + } + + public Optional getRequiredAud() { + return Optional.ofNullable(requiredAud); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("JwtBearerTokenAuthenticationConfiguration{"); + sb.append("issuerUri='").append(issuerUri).append('\''); + sb.append(", jwkSetUri='").append(jwkSetUri).append('\''); + sb.append(", requiredAud='").append(requiredAud).append('\''); + sb.append('}'); + return sb.toString(); + } + + @Override + public boolean equals(final Object o) { + if (this == o) + return true; + if (!(o instanceof JwtBearerTokenAuthenticationConfiguration)) + return false; + final JwtBearerTokenAuthenticationConfiguration that = (JwtBearerTokenAuthenticationConfiguration) o; + return Objects.equals(getIssuerUri(), that.getIssuerUri()) && Objects.equals(getJwkSetUri(), that.getJwkSetUri()) && Objects.equals(getRequiredAud(), that.getRequiredAud()); + } + + @Override + public int hashCode() { + return Objects.hash(getIssuerUri(), getJwkSetUri(), getRequiredAud()); + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java index 52f9f57d..edd2f55a 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/http/server/VABHTTPInterface.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.http.server; @@ -14,6 +29,7 @@ import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.StringJoiner; @@ -22,6 +38,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.eclipse.basyx.vab.coder.json.provider.JSONProvider; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; import org.eclipse.basyx.vab.exception.provider.ProviderException; @@ -33,7 +53,6 @@ import com.google.common.base.Charsets; import com.google.common.io.ByteSource; - /** * VAB provider class that enables access to an IModelProvider via HTTP REST * interface
@@ -54,22 +73,19 @@ * */ public class VABHTTPInterface extends BasysHTTPServlet { - + private static Logger logger = LoggerFactory.getLogger(VABHTTPInterface.class); - + /** * Version information to identify the version of serialized instances */ private static final long serialVersionUID = 1L; - /** * Reference to IModelProvider backend */ protected JSONProvider providerBackend = null; - - /** * Constructor */ @@ -78,7 +94,6 @@ public VABHTTPInterface(ModelProvider provider) { providerBackend = new JSONProvider(provider); } - /** * Access model provider */ @@ -95,7 +110,6 @@ protected void sendJSONResponse(String path, PrintWriter outputStream, Object js outputStream.flush(); } - /** * Implement "Get" operation * @@ -114,15 +128,14 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se // Process get request providerBackend.processBaSysGet(path, resp.getOutputStream()); - } catch(ProviderException e) { + } catch (ProviderException e) { int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e); resp.setStatus(httpCode); logger.debug("Exception in HTTP-GET. Response-code: " + httpCode, e); } - + } - /** * Implement "Set" operation */ @@ -138,40 +151,28 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se resp.setStatus(200); providerBackend.processBaSysSet(path, serValue.toString(), resp.getOutputStream()); - } catch(ProviderException e) { + } catch (ProviderException e) { int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e); resp.setStatus(httpCode); logger.debug("Exception in HTTP-PUT. Response-code: " + httpCode, e); } } - /** * Handle HTTP POST operation. Creates a new Property, Operation, Event, - * Submodel or AAS or invokes an operation. + * Submodel or AAS or AASX or invokes an operation. */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { String path = extractPath(req); - String serValue = extractSerializedValue(req); - logger.trace("DoPost: {}", serValue); - - // Setup HTML response header - resp.setStatus(201); - resp.setContentType("application/json"); - resp.setCharacterEncoding("UTF-8"); - - // Check if request is for property creation or operation invoke - if (VABPathTools.isOperationInvokationPath(path)) { - // Invoke BaSys VAB 'invoke' primitive - - providerBackend.processBaSysInvoke(path, serValue, resp.getOutputStream()); + setPostResponseHeader(resp); + if (ServletFileUpload.isMultipartContent(req)) { + handleMultipartFormDataRequest(req, path, resp); } else { - // Invoke the BaSys 'create' primitive - providerBackend.processBaSysCreate(path, serValue, resp.getOutputStream()); + handleJSONPostRequest(req, path, resp); } } catch (ProviderException e) { int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e); @@ -180,7 +181,6 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S } } - /** * Handle a HTTP PATCH operation. Updates a map or collection * @@ -195,14 +195,13 @@ protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws resp.setStatus(200); providerBackend.processBaSysDelete(path, serValue, resp.getOutputStream()); - } catch(ProviderException e) { + } catch (ProviderException e) { int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e); resp.setStatus(httpCode); logger.debug("Exception in HTTP-PATCH. Response-code: " + httpCode, e); } } - /** * Implement "Delete" operation. Deletes any resource under the given path. */ @@ -216,16 +215,14 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws resp.setStatus(200); - providerBackend.processBaSysDelete(path, nullParam, resp.getOutputStream()); - } catch(ProviderException e) { + } catch (ProviderException e) { int httpCode = ExceptionToHTTPCodeMapper.mapFromException(e); resp.setStatus(httpCode); logger.debug("Exception in HTTP-DELETE. Response-code: " + httpCode, e); } } - private String extractPath(HttpServletRequest req) throws UnsupportedEncodingException { // Extract path String uri = req.getRequestURI(); @@ -257,7 +254,7 @@ private String extractPath(HttpServletRequest req) throws UnsupportedEncodingExc */ private String extractParameters(HttpServletRequest req) { Enumeration parameterNames = req.getParameterNames(); - + // Collect list of parameters List parameters = new ArrayList<>(); while (parameterNames.hasMoreElements()) { @@ -290,22 +287,102 @@ private int getEnvironmentPathSize(HttpServletRequest req) { return req.getContextPath().length() + req.getServletPath().length(); } - /** - * Read serialized value + * Read serialized value + * * @param req * @return * @throws IOException */ private String extractSerializedValue(HttpServletRequest req) throws IOException { // https://www.baeldung.com/convert-input-stream-to-string#guava - ByteSource byteSource = new ByteSource() { - @Override - public InputStream openStream() throws IOException { - return req.getInputStream(); - } - }; - - return byteSource.asCharSource(Charsets.UTF_8).read(); + return getByteSource(req).asCharSource(Charsets.UTF_8).read(); + } + + /** + * Extracts input streams from request + * + * @param req + * @return + * @throws IOException + * @throws ServletException + */ + private Collection extractInputStreams(HttpServletRequest req) throws IOException, ServletException { + Collection fileStreams = new ArrayList(); + try { + List items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(req); + for (FileItem item : items) { + if (!item.isFormField()) { + fileStreams.add(item.getInputStream()); + } + } + } catch (FileUploadException e) { + throw new ServletException("Cannot parse multipart request.", e); + } + return fileStreams; + } + + /** + * Gets a {@link ByteSource} from request stream + * + * @return + */ + private ByteSource getByteSource(HttpServletRequest req) { + return new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return req.getInputStream(); + } + }; + } + + /** + * Setup HTML response header for HttpPost + * + * @param resp + */ + private void setPostResponseHeader(HttpServletResponse resp) { + resp.setStatus(201); + resp.setContentType("application/json"); + resp.setCharacterEncoding("UTF-8"); + } + + /** + * Handles multipart/form-data request in HttpPost + * + * @param req + * @param path + * @param resp + * @throws IOException + * @throws ServletException + */ + private void handleMultipartFormDataRequest(HttpServletRequest req, String path, HttpServletResponse resp) throws IOException, ServletException { + Collection fileStreams = extractInputStreams(req); + for (InputStream fileStream : fileStreams) { + providerBackend.processBaSysUpload(path, fileStream, resp.getOutputStream()); + fileStream.close(); + } + } + + /** + * Handles POST request with JSON body + * + * @param req + * @param path + * @param resp + * @throws IOException + */ + private void handleJSONPostRequest(HttpServletRequest req, String path, HttpServletResponse resp) throws IOException { + String serValue = extractSerializedValue(req); + logger.trace("DoPost: {}", serValue); + + // Check if request is for property creation or operation invoke + if (VABPathTools.isOperationInvokationPath(path)) { + // Invoke BaSys VAB 'invoke' primitive + providerBackend.processBaSysInvoke(path, serValue, resp.getOutputStream()); + } else { + // Invoke the BaSys 'create' primitive + providerBackend.processBaSysCreate(path, serValue, resp.getOutputStream()); + } } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultHostNameVerifier.java b/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultHostNameVerifier.java deleted file mode 100644 index 1e2b34d0..00000000 --- a/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultHostNameVerifier.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - ******************************************************************************/ -package org.eclipse.basyx.vab.protocol.https; - - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSession; - -/** - * A default host name verifier which verifies every host name - * Used for testing with self signed certificate - * @author haque - * - */ -public class DefaultHostNameVerifier implements HostnameVerifier { - @Override - public boolean verify(String s, SSLSession sslSession) { - return true; - } -} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultTrustManager.java b/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultTrustManager.java index ceb09e53..8a27a710 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultTrustManager.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/https/DefaultTrustManager.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.https; @@ -13,22 +28,23 @@ import java.security.cert.X509Certificate; /** - * A Default Trust manager class which trusts everything - * Used for testing with self signed certificate + * A Default Trust manager class which trusts everything Used for testing with + * self signed certificate + * * @author haque * */ public class DefaultTrustManager implements X509TrustManager { - @Override - public void checkClientTrusted(X509Certificate[] x509Certificates, String s) { - } + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) { + } - @Override - public void checkServerTrusted(X509Certificate[] x509Certificates, String s) { - } + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) { + } - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnector.java b/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnector.java index c88c7b66..e4e25dc4 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnector.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnector.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.https; @@ -13,45 +28,69 @@ import java.security.NoSuchAlgorithmException; import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector; +import org.eclipse.basyx.vab.protocol.http.connector.IAuthorizationSupplier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * An HTTPS Connector class which can be used - * for creating an HTTPS Client with self signed SSL certificate - * and communicating in REST + * An HTTPS Connector class which can be used for creating an HTTPS Client with + * self signed SSL certificate and communicating in REST * * @author haque * */ public class HTTPSConnector extends HTTPConnector { private static Logger logger = LoggerFactory.getLogger(HTTPSConnector.class); - + /** * Initiates an HTTPSConnector with given address + * * @param address */ public HTTPSConnector(String address) { super(address); - setHttpsClient(); + setHttpsClientWithValidation(); } - + /** * Initiates an HTTPSConnector with given address and media type + * * @param address * @param mediaType */ - public HTTPSConnector(String address, String mediaType) { + public HTTPSConnector(String address, String mediaType) { super(address, mediaType); - setHttpsClient(); + setHttpsClientWithValidation(); + } + + public HTTPSConnector(String address, IAuthorizationSupplier authorizationSupplier) { + super(address, authorizationSupplier); + setHttpsClientWithValidation(); + } + + public HTTPSConnector(String address, IAuthorizationSupplier authorizationSupplier, boolean validateFlag) { + super(address, authorizationSupplier); + if (validateFlag) { + setHttpsClientWithValidation(); + } else { + setHttpsClientWithoutValidation(); + } } - + /** * Configures the client so that it can run with HTTPS protocol */ - private void setHttpsClient() { + private void setHttpsClientWithoutValidation() { + try { + this.client = JerseyHttpsClientFactory.getJerseyHTTPSClientWithoutValidation(); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + logger.error("Cannot create a https client"); + } + } + + private void setHttpsClientWithValidation() { try { - this.client = JerseyHttpsClientFactory.getJerseyHTTPSClient(); + this.client = JerseyHttpsClientFactory.getJerseyHTTPSClientWithValidation(); } catch (KeyManagementException | NoSuchAlgorithmException e) { logger.error("Cannot create a https client"); } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnectorProvider.java b/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnectorProvider.java index 1a8e47e7..fd694c35 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnectorProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/https/HTTPSConnectorProvider.java @@ -1,25 +1,72 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.https; import org.eclipse.basyx.vab.coder.json.connector.JSONConnector; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.basyx.vab.protocol.api.ConnectorFactory; +import org.eclipse.basyx.vab.protocol.http.connector.IAuthorizationSupplier; /** - * An HTTPS Connector provider class - * which uses a HTTPSConnector in domain having self signed certificate + * An HTTPS Connector provider class which uses a HTTPSConnector in domain + * having self signed certificate + * * @author haque * */ public class HTTPSConnectorProvider extends ConnectorFactory { + private IAuthorizationSupplier supplier; + private boolean validateFlag = true; + + public HTTPSConnectorProvider() { + } + + /** + * Constructor to create a HTTPSConenctorProvider with a given authorization + * supplier + * + * @param supplier + * given authorization supplier + */ + public HTTPSConnectorProvider(IAuthorizationSupplier supplier) { + this.supplier = supplier; + } + + /** + * Enable the validation of hostname in Jersey Https client + */ + public void enableValidation() { + this.validateFlag = true; + } + + /** + * Disable the validation of hostname in Jersey Https client + */ + public void disableValidation() { + this.validateFlag = false; + } /** * returns HTTPSConnetor wrapped with ConnectedHashmapProvider that handles @@ -27,6 +74,6 @@ public class HTTPSConnectorProvider extends ConnectorFactory { */ @Override protected IModelProvider createProvider(String addr) { - return new JSONConnector(new HTTPSConnector(addr)); + return new JSONConnector(new HTTPSConnector(addr, supplier, validateFlag)); } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/https/JerseyHttpsClientFactory.java b/src/main/java/org/eclipse/basyx/vab/protocol/https/JerseyHttpsClientFactory.java index a698383d..111f761e 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/https/JerseyHttpsClientFactory.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/https/JerseyHttpsClientFactory.java @@ -1,14 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.https; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; @@ -16,14 +35,11 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; /** - * A Factory class containing methods creating an HTTPS client - * with no verification and validation for self signed SSL - * and other helper methods + * A Factory class containing methods creating an HTTPS client with no + * verification and validation for self signed SSL and other helper methods * * @author haque * @@ -31,40 +47,50 @@ public class JerseyHttpsClientFactory { private static final String PROTOCOL = "TLSv1.2"; + /** + * Returns an HTTPS client without validation + * + * @return + * @throws KeyManagementException + * @throws NoSuchAlgorithmException + */ + public static Client getJerseyHTTPSClientWithoutValidation() throws KeyManagementException, NoSuchAlgorithmException { + return getJerseyHTTPSClient(new NonVerifyingHostnameVerifier()); + } + /** * Returns an HTTPS client + * * @return * @throws KeyManagementException * @throws NoSuchAlgorithmException */ - public static Client getJerseyHTTPSClient() throws KeyManagementException, NoSuchAlgorithmException { - SSLContext sslContext = getSslContext(PROTOCOL); - HostnameVerifier allHostsValid = new DefaultHostNameVerifier(); + public static Client getJerseyHTTPSClientWithValidation() throws KeyManagementException, NoSuchAlgorithmException { + return getJerseyHTTPSClient(new DefaultHostnameVerifier()); + } - return ClientBuilder.newBuilder() - .sslContext(sslContext) - .hostnameVerifier(allHostsValid) - .build(); - } + private static Client getJerseyHTTPSClient(HostnameVerifier hostnameVerifier) throws KeyManagementException, NoSuchAlgorithmException { + SSLContext sslContext = getSslContext(PROTOCOL); + return ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier).build(); + } - /** - * Retrieves an SSL Context - * with given protocol - * @param protocol - * @return - * @throws NoSuchAlgorithmException - * @throws KeyManagementException - */ - private static SSLContext getSslContext(String protocol) throws NoSuchAlgorithmException, - KeyManagementException { - SSLContext sslContext = SSLContext.getInstance(protocol); + /** + * Retrieves an SSL Context with given protocol + * + * @param protocol + * @return + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + private static SSLContext getSslContext(String protocol) throws NoSuchAlgorithmException, KeyManagementException { + SSLContext sslContext = SSLContext.getInstance(protocol); - KeyManager[] keyManagers = null; - TrustManager[] trustManager = {new DefaultTrustManager()}; - SecureRandom secureRandom = new SecureRandom(); + KeyManager[] keyManagers = null; + TrustManager[] trustManager = { new DefaultTrustManager() }; + SecureRandom secureRandom = new SecureRandom(); - sslContext.init(keyManagers, trustManager, secureRandom); + sslContext.init(keyManagers, trustManager, secureRandom); - return sslContext; - } + return sslContext; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/https/NonVerifyingHostnameVerifier.java b/src/main/java/org/eclipse/basyx/vab/protocol/https/NonVerifyingHostnameVerifier.java new file mode 100644 index 00000000..a2d5c706 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/https/NonVerifyingHostnameVerifier.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.https; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +/** + * A default host name verifier which verifies every host name Used for testing + * with self signed certificate + * + * @author haque + * + */ +public class NonVerifyingHostnameVerifier implements HostnameVerifier { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/CertificateHelper.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/CertificateHelper.java new file mode 100644 index 00000000..8e2df8bc --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/CertificateHelper.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua; + +import java.net.InetAddress; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CopyOnWriteArraySet; + +import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder; +import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator; + +/** + * Builds self-signed X.509 certificates. + */ +public class CertificateHelper { + private boolean buildDefault = true; + private KeyPair keyPair; + private X509Certificate certificate; + private String commonName; + private String organization; + private String organizationalUnit; + private String locality; + private String state; + private String countryCode; + private String applicationUri; + private Set ipAddresses = new HashSet<>(); + private Set dnsNames = new CopyOnWriteArraySet<>(); + + /** + * Creates a new {@link CertificateHelper}. + * + *

+ * This constructor generates a new RSA-2048 key pair used for signing the + * certificate. That's why it might take an appreciable amount of time to + * return. + */ + public CertificateHelper() { + try { + // We use RSA 2048 because it is well-supported and can't fail. + keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048); + } catch (NoSuchAlgorithmException impossible) { + throw new AssertionError("Every Java implementation is required to implement 2048 bit RSA", impossible); + } + } + + /** + * Gets the generated key pair. + * + * @return The generated key pair. + * + * @throws IllegalStateException + * if called before {@link #build()}. + */ + public KeyPair getKeyPair() { + if (certificate == null) { + throw new IllegalStateException("Must build certificate first."); + } + + return keyPair; + } + + /** + * Gets the generated self-signed certificate. + * + * @return The generated certificate. + * + * @throws IllegalStateException + * if called before {@link #build()}. + */ + public X509Certificate getCertificate() { + if (certificate == null) { + throw new IllegalStateException("Must build certificate first."); + } + + return certificate; + } + + /** + * Sets the certificate's common name (CN) field. + * + * @param commonName + * The certificate's common name. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setCommonName(String commonName) { + buildDefault = false; + this.commonName = commonName; + return this; + } + + /** + * Sets the certificate's organization (O) field. + * + * @param organization + * The certificate's organization. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setOrganization(String organization) { + buildDefault = false; + this.organization = organization; + return this; + } + + /** + * Sets the certificate's organizational unit (OU) field. + * + * @param organizationalUnit + * The certificate's organizational unit. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setOrganizationalUnit(String organizationalUnit) { + buildDefault = false; + this.organizationalUnit = organizationalUnit; + return this; + } + + /** + * Sets the certificate's locality (L) field. + * + * @param locality + * The certificate's locality. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setLocality(String locality) { + buildDefault = false; + this.locality = locality; + return this; + } + + /** + * Sets the certificate's state (ST) field. + * + * @param state + * The certificate's state or region. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setState(String state) { + buildDefault = false; + this.state = state; + return this; + } + + /** + * Sets the certificate's country code (C) field. + * + * @param countryCode + * The certificate's country code. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setCountryCode(String countryCode) { + buildDefault = false; + this.countryCode = countryCode; + return this; + } + + /** + * Sets the certificate's application URI which will be added as a subject + * alternative name. + * + * @param applicationUri + * The certificate's application URI. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper setApplicationUri(String applicationUri) { + buildDefault = false; + this.applicationUri = applicationUri; + return this; + } + + /** + * Adds a DNS name as a subject alternative name to the certificate. + * + *

+ * If you're adding an IP address to the certificate as well, you can use + * {@link #addIpAddress(InetAddress, boolean)} to add the associated host name + * automatically, without manually calling this method. However, see that + * method's documentation for important limitations. + * + * @param dnsName + * The name to add. Can be any kind of host name or FQDN. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper addDnsName(String dnsName) { + buildDefault = false; + dnsNames.add(dnsName); + return this; + } + + /** + * Adds an IP address as a subject alternative name to the certificate. + * + *

+ * Optionally, this method can also attempt to lookup the matching host name in + * the background. If successful, the name will be added to the certificate. + *
+ * If the lookup fails or doesn't finish until {@link #build()} is called, the + * name won't be added.
+ * To guarantee the host name is added use {@link #addDnsName(String)}, instead. + * + * @param ipAddress + * The address to add. + * @param lookupHostName + * If true, the host name will be looked up in the background and + * added to the certificate. + * + * @return This {@link CertificateHelper}. + */ + public CertificateHelper addIpAddress(InetAddress ipAddress, boolean lookupHostName) { + buildDefault = false; + ipAddresses.add(ipAddress); + + if (lookupHostName) { + CompletableFuture.supplyAsync(ipAddress::getHostName).thenAccept(hostName -> dnsNames.add(hostName)); + } + + return this; + } + + /** + * Builds a self-signed certificate from the information previously provided to + * this helper. + * + *

+ * If no information has been provided, a default certificate is generated + * automatically. The default certificate carries only the common name + * CN=Unknown. + * + *

+ * After this method returns, the certificate can be acquired through + * {@link #getCertificate()}. + * + * @throws CertificateException + * if certificate generation fails. + */ + public void build() throws CertificateException { + try { + SelfSignedCertificateBuilder builder = buildDefault ? configureDefaultBuilder() : configureBuilderWithInfo(); + certificate = builder.build(); + } catch (Exception e) { + throw new CertificateException("Failed to create self-signed certificate.", e); + } + } + + /** Returns a builder for a default certificate (CN=Unknown). */ + private SelfSignedCertificateBuilder configureDefaultBuilder() { + return new SelfSignedCertificateBuilder(keyPair).setCommonName("Unknown"); + } + + /** Returns a builder for a certificate with the user-provided information. */ + private SelfSignedCertificateBuilder configureBuilderWithInfo() { + SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair).setCommonName(commonName).setOrganization(organization).setOrganizationalUnit(organizationalUnit).setLocalityName(locality).setStateName(state) + .setCountryCode(countryCode).setApplicationUri(applicationUri); + + ipAddresses.forEach(ip -> builder.addIpAddress(ip.getHostName())); + dnsNames.forEach(builder::addDnsName); + + return builder; + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/ClientConfiguration.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/ClientConfiguration.java new file mode 100644 index 00000000..a268a4b5 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/ClientConfiguration.java @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.connector; + +import java.security.KeyPair; +import java.security.cert.X509Certificate; + +import org.eclipse.basyx.vab.protocol.opcua.CertificateHelper; +import org.eclipse.basyx.vab.protocol.opcua.types.MessageSecurityMode; +import org.eclipse.basyx.vab.protocol.opcua.types.SecurityPolicy; + +/** + * Holds the configuration for an {@link IOpcUaClient}. + */ +public final class ClientConfiguration implements Cloneable { + private SecurityPolicy securityPolicy = SecurityPolicy.None; + private MessageSecurityMode messageSecurityMode = MessageSecurityMode.None; + private String applicationName; + private String applicationUri; + private KeyPair keyPair; + private X509Certificate certificate; + + /** + * Creates a new {@link ClientConfiguration} with default settings. + */ + public ClientConfiguration() { + // Nothing to be done, all settings are default. + } + + /** + * Creates a shallow copy of this object. + * + * @return A shallow copy. + */ + @Override + public ClientConfiguration clone() { + try { + return (ClientConfiguration) super.clone(); + } catch (CloneNotSupportedException impossible) { + // Can't happen because we support cloning. + throw new AssertionError(impossible); + } + } + + /** + * Gets the key pair used to generate the client certificate. + * + *

+ * Default: null (i.e., no client certificate is used). + * + * @return The certificate. + */ + public KeyPair getKeyPair() { + return keyPair; + } + + /** + * Gets the certificate for client identification towards the server. + * + *

+ * Default: null (i.e., no client certificate is used). + * + * @return The certificate. + */ + public X509Certificate getCertificate() { + return certificate; + } + + /** + * Sets the key pair and associated certificate for client identification + * towards the server. + * + *

+ * Default: No certificate is used. + * + * @param keyPair + * The key pair. If null then certificate must also be + * null. + * @param certificate + * The certificate. If null then keyPair must also be + * null. + * + * @return This {@link ClientConfiguration}. + * + * @see CertificateHelper + * + * @throws IllegalArgumentException + * if keyPair is null but certificate is not or vice + * versa. + */ + public ClientConfiguration setKeyPairAndCertificate(KeyPair keyPair, X509Certificate certificate) { + if ((keyPair == null) ^ (certificate == null)) { + throw new IllegalArgumentException("Either both keyPair and certificate are null or neither."); + } + + this.keyPair = keyPair; + this.certificate = certificate; + return this; + } + + /** + * Gets the OPC UA client's application name. + * + *

+ * The client uses this name to identify itself towards the server. It needs not + * follow any specific format. + * + * @return The application name. + */ + public String getApplicationName() { + return applicationName; + } + + /** + * Sets the OPC UA client's application name. + * + *

+ * The client uses this name to identify itself towards the server. It needs not + * follow any specific format. + * + *

+ * Default: null. + * + * @param applicationName + * The application name. + * + * @return This {@link ClientConfiguration}. + */ + public ClientConfiguration setApplicationName(String applicationName) { + this.applicationName = applicationName; + return this; + } + + /** + * Gets the OPC UA client's application URI. + * + *

+ * The client uses this URI to identify itself towards the server. + * + * @return The application URI. + */ + public String getApplicationUri() { + return applicationUri; + } + + /** + * Sets the OPC UA client's application URI. + * + *

+ * The client uses this URI to identify itself towards the server. + * + *

+ * Default: null. + * + * @param applicationUri + * The application URI. + * + * @return This {@link ClientConfiguration}. + */ + public ClientConfiguration setApplicationUri(String applicationUri) { + this.applicationUri = applicationUri; + return this; + } + + /** + * Sets the message security mode. + * + *

+ * Along with {@link #getSecurityPolicy()} this parameter controls the endpoint + * selection when connecting to a server. + * + *

+ * Default: {@link MessageSecurityMode#None}. + * + * @return The message security mode. + */ + public MessageSecurityMode getMessageSecurityMode() { + return messageSecurityMode; + } + + /** + * Sets the message security mode. + * + *

+ * Along with {@link #setSecurityPolicy(SecurityPolicy)} this parameter controls + * the endpoint selection when connecting to a server. + * + *

+ * Default: {@link MessageSecurityMode#None}. + * + * @param messageSecurityMode + * The message security mode. + * + * @return This {@link ClientConfiguration}. + * + * @throws IllegalArgumentException + * if messageSecurityMode is null. + */ + public ClientConfiguration setMessageSecurityMode(MessageSecurityMode messageSecurityMode) { + if (messageSecurityMode == null) { + throw new IllegalArgumentException("messageSecurityMode can not be null."); + } + + this.messageSecurityMode = messageSecurityMode; + return this; + } + + /** + * Gets the security policy. + * + *

+ * Along with {@link #getMessageSecurityMode()} this parameter controls the + * endpoint selection when connecting to a server. + * + *

+ * Default: {@link SecurityPolicy#None}. + * + * @return The security policy. + */ + public SecurityPolicy getSecurityPolicy() { + return securityPolicy; + } + + /** + * Sets the security policy. + * + *

+ * Along with {@link #setMessageSecurityMode(MessageSecurityMode)} this + * parameter controls the endpoint selection when connecting to a server. + * + *

+ * Default: {@link SecurityPolicy#None}. + * + * @param securityPolicy + * The security policy. + * + * @return This {@link ClientConfiguration}. + * + * @throws IllegalArgumentException + * if securityPolicy is null. + */ + public ClientConfiguration setSecurityPolicy(SecurityPolicy securityPolicy) { + if (securityPolicy == null) { + throw new IllegalArgumentException("securityPolicy can not be null."); + } + + this.securityPolicy = securityPolicy; + return this; + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/IOpcUaClient.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/IOpcUaClient.java new file mode 100644 index 00000000..d3903285 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/IOpcUaClient.java @@ -0,0 +1,622 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.connector; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.protocol.opcua.connector.milo.MiloOpcUaClient; +import org.eclipse.basyx.vab.protocol.opcua.exception.AmbiguousBrowsePathException; +import org.eclipse.basyx.vab.protocol.opcua.exception.OpcUaException; +import org.eclipse.basyx.vab.protocol.opcua.types.NodeId; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedByte; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedInteger; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedLong; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedShort; + +/** + * Very simplified OPC UA client interface for reading and writing node values + * and invoking methods. + * + *

How to use

+ * + * This interface features a set of methods to call common OPC UA services on a + * server (e.g. to read a node). Each comes in a synchronous and an asynchronous + * variant, returning {@link CompletableFuture}s. When any of these methods is + * first called, a connection to the configured endpoint URL is automatically + * opened. + *

+ * Users can configure the client through + * {@link #setConfiguration(ClientConfiguration)} until the first connection + * attempt is made. After that point, that method will throw an exception.
+ * {@link #hasConnected()} lets users check whether such a connection attempt + * has already been made. + * + *

Regarding types

+ * + * This interface must necessarily translate between two distinct type systems. + * There is the {@link ValueType BaSyx type system} on the one hand, itself a + * mapping of XML Schema types to standard JDK types with some additional custom + * classes. And on the other hand, there is + * OPC + * UA's type system. The two aren't fully compatible, meaning that there + * isn't a simple one-to-one mapping of types. + * + *

+ * This implementation makes no attempt at complete coverage of all OPC UA + * types. Only a subset of the most common data types are supported. Below table + * shows which Java types can be used and what OPC UA type they map to. Callers + * can pass these types to any of the interface methods and expect these types + * to be returned. + * + *

+ * Please note that if the OPC UA server returns a value of a different type + * than those listed in the table, e.g. as the result of a read operation or + * method invocation, then that type will be returned from the API as is. It + * would likely be a class from the underlying OPC UA library and the caller + * would have to know how to handle that type. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Java / OPC UA type mapping
Java typeOPC UA type
boolean / {@link Boolean}Boolean
byte / {@link Byte}SByte
short / {@link Short}Int16
int / {@link Integer}Int32
long / {@link Long}Int64
float / {@link Float}Float
double / {@link Double}Double
{@link UnsignedByte}Byte
{@link UnsignedShort}UInt16
{@link UnsignedInteger}UInt32
{@link UnsignedLong}UInt64
{@link XMLGregorianCalendar}DateTime
{@link String}String
{@link UUID}GUID
Array of the aforementioned types
+ * (Single- or multi-dimensional)
Array of equivalent OPC UA type
+ * + *

Date & time types

+ * + * Special care must be taken when dealing with the {@link XMLGregorianCalendar} + * type. It allows for incomplete date or time specifications, such as March + * 13, without providing a year. Or 5 minutes without any information + * on the hour or seconds. Such date/time specifications are not supported by + * the OPC UA DateTime type. It functions like the {@link java.time.Instant} + * type and must always specify a precise moment in time. + */ +public interface IOpcUaClient { + /** + * Static factory method for creating a client using the default implementation + * based on eclipse Milo. + * + * @param endpointUrl + * The server endpoint to which the client connects. + * + * @return The new {@link MiloOpcUaClient}. + */ + static IOpcUaClient create(String endpointUrl) { + return new MiloOpcUaClient(endpointUrl); + } + + /** + * Gets the current client configuration. + * + *

+ * A copy of the configuration is made and returned. Subsequent changes to the + * returned object won't be reflected on this {@link IOpcUaClient} until the + * changed configuration is applied with + * {@link #setConfiguration(ClientConfiguration)}. + * + * @return A copy of the current client configuration. + */ + ClientConfiguration getConfiguration(); + + /** + * Sets the client configuration. + * + *

+ * A copy of the configuration is made and stored. Modifications done to the + * original object after invoking this method have no effect on this + * {@link IOpcUaClient}. + * + * @param configuration + * The configuration to set or null to use a default + * configuration. + * + * @throws IllegalStateException + * if this method is called after a connection has been established. + */ + void setConfiguration(ClientConfiguration configuration); + + /** + * Gets the endpoint URL that this client connects to. + * + * @return The endpoint URL to connect to. + */ + String getEndpointUrl(); + + /** + * Gets a value signifying whether this client has already attempted to + * establish a connection to the server endpoint. + * + *

+ * Note that the returned value does not say whether there is currently an + * active connection to the server. Only whether a connection attempt has been + * made. This is significant because changes to client configuration are no + * longer possible once this method returns true. + * + * @return true if a connection attempt has been made, + * false otherwise. + */ + boolean hasConnected(); + + /** + * Gets the id of the node pointed to by when resolving the given path against + * the starting node. + * + *

+ * Browse paths in OPC UA are comprised of a starting node (identified by it's + * node id) and a relative path to the target. This relative path is a sequence + * of pairs of a reference type and a browse name.
+ * The relative path must be formatted according to the + * BNF + * format of relative paths. + * + *

+ * The relative path is resolved against the starting node by following a + * reference of the type specified in the first pair from the starting node to a + * target node with the browse name from that same pair. From the target node + * thus reached the second pair is resolved and so on until the end of the path. + * The node id of the final node reached this way is returned. + * + *

+ * Unfortunately, browse paths can be ambiguous in that they can lead to more + * than one final target. That's because browse names of nodes are not required + * to be unique, even within the same namespace. So from any given node, several + * references of the same type can lead to several other nodes with the same + * browse name. + * + *

+ * This is a blocking call which returns only after the request to the server + * has been completed. For a non-blocking variant, see + * {@link #translateBrowsePathToNodeIdAsync(NodeId, String)}. + * + * @param startingNode + * The starting node from where to start resolving + * relativePath. + * @param relativePath + * The string representation of the relative path to resolve against + * startingNode. + * + * @return The id of the node matching the browse path. + * + * @throws ResourceNotFoundException + * if the path doesn't lead to a node. + * @throws AmbiguousBrowsePathException + * if the path cannot be unambiguously resolved. + * @throws OpcUaException + * if an OPC UA related error occurs. This is a generic wrapper type + * for exceptions thrown by the client library. + * @throws IllegalArgumentException + * if startingNode or relativePath is + * null or if relativePath is an empty + * string. + */ + NodeId translateBrowsePathToNodeId(NodeId startingNode, String relativePath); + + /** + * Gets the id of the node matching the given browse path when resolved against + * the root node. + * + *

+ * See {@link #translateBrowsePathToNodeId(NodeId, String)} for details on how + * browse paths are resolved. + * + *

+ * This overload doesn't take an explicit starting node. It implicitly starts at + * the root node. Use {@link #translateBrowsePathToNodeId(NodeId, String)} to + * specify a different starting node. + * + *

+ * This is a blocking call which returns only after the request to the server + * has been completed. For a non-blocking variant, see + * {@link #translateBrowsePathToNodeIdAsync(String)}. + * + * @param browsePath + * The string representation of the browse path. + * + * @return The id of the node matching the browse path. + * + * @throws ResourceNotFoundException + * if the path doesn't lead to a node. + * @throws AmbiguousBrowsePathException + * if the path cannot be unambiguously resolved. + * @throws OpcUaException + * if an OPC UA related error occurs. This is a generic wrapper type + * for exceptions thrown by the client library. + * @throws IllegalArgumentException + * if browsePath is null or an empty + * string. + */ + NodeId translateBrowsePathToNodeId(String browsePath); + + /** + * Gets the id of the node pointed to by when resolving the given path against + * the starting node. + * + *

+ * See {@link #translateBrowsePathToNodeId(NodeId, String)} for details on how + * browse paths are resolved. + * + *

+ * This is an asynchronous call returning a {@link CompletableFuture}. For more + * details about the parameter, the value returned by the future and possible + * exceptions, see {@link #translateBrowsePathToNodeId(NodeId, String)}. + * + * @param startingNode + * The starting node from where to start resolving + * relativePath. + * @param relativePath + * The string representation of the relative path to resolve against + * startingNode. + * + * @return A {@link CompletableFuture} for the target node's id. + * + * @throws IllegalArgumentException + * if startingNode or relativePath is + * null or if relativePath is an empty + * string. + */ + CompletableFuture translateBrowsePathToNodeIdAsync(NodeId startingNode, String relativePath); + + /** + * Gets the id of the node matching the given browse path when resolved against + * the root node. + * + *

+ * See {@link #translateBrowsePathToNodeId(NodeId, String)} for details on how + * browse paths are resolved. + * + *

+ * This overload doesn't take an explicit starting node. It implicitly starts at + * the root node. Use {@link #translateBrowsePathToNodeIdAsync(NodeId, String)} + * to specify a different starting node. + * + *

+ * This is an asynchronous call returning a {@link CompletableFuture}. For more + * details about the parameter, the value returned by the future and possible + * exceptions, see {@link #translateBrowsePathToNodeId(String)}. + * + * @param browsePath + * The string representation of the browse path. + * + * @return A {@link CompletableFuture} for the target node's id. + * + * @throws IllegalArgumentException + * if browsePath is null or an empty + * string. + */ + CompletableFuture translateBrowsePathToNodeIdAsync(String browsePath); + + /** + * Gets the id of the last two nodes pointed to by when resolving the given path + * against the starting node. + * + *

+ * This is not a typical use case for OPC UA applications but it is a useful + * helper for invoking BaSyx operations through OPC UA. That's because BaSyx + * identifies all elements in its information model only through a single path, + * represented as a string. These strings map directly to OPC UA browse paths in + * the case of {@link OpcUaConnector}). + * + *

+ * For BaSyx properties (i.e., variable nodes in OPC UA) that's all well and + * good. But for BaSyx operations (which correspond to OPC UA methods) it poses + * a problem.
+ * OPC UA methods must be invoked using their own node id as well as that of the + * owner object on which to invoke the method. See + * {@link #invokeMethod(NodeId, NodeId, Object...)} for more information.
+ * That's two independent identifiers necessary, while BaSyx only provides the + * one string. + * + *

+ * BaSyx solves this conundrum by assuming that the final node targeted by a + * browse path is the method node itself, while the second to last node in the + * path is the owner.
+ * For any BaSyx model directly mapped to OPC UA this assumption is guaranteed + * to hold true. The same can not be said for general purpose OPC UA servers. + * This should be kept in mind when utilizing this method with a server not + * provided by a BaSyx application. + * + *

+ * For general information on how browse paths are resolved, please refer to + * {@link #translateBrowsePathToNodeId(NodeId, String)}. + * + *

+ * Note that this method has no overload accepting an explicit starting node. + * That's because it's use case is specific to the {@link OpcUaConnector} which + * has no way of ever specifying an starting node. + * + *

+ * This is a blocking call which returns only after the request to the server + * has been completed. For a non-blocking variant, see + * {@link #translateBrowsePathToParentAndTargetNodeIdAsync(String)}. + * + * @param browsePath + * The string representation of the browse path. + * + * @return A list of two node ids, where the first is the method node and the + * second is its parent. + * + * @throws ResourceNotFoundException + * if the path doesn't lead to a node. + * @throws AmbiguousBrowsePathException + * if the path cannot be unambiguously resolved. + * @throws OpcUaException + * if an OPC UA related error occurs. This is a generic wrapper type + * for exceptions thrown by the client library. + * @throws IllegalArgumentException + * if browsePath is null or an empty + * string. + */ + List translateBrowsePathToParentAndTargetNodeId(String browsePath); + + /** + * Gets the id of the last two nodes pointed to by when resolving the given path + * against the starting node. + * + *

+ * This is an asynchronous call returning a {@link CompletableFuture}. For more + * details on this method's purpose, returned value and possible exceptions, see + * {@link #translateBrowsePathToParentAndTargetNodeId(String)}. + * + * @param browsePath + * The string representation of the browse path. + * + * @return A {@link CompletableFuture} for a list of parent and method node id. + * + * @throws IllegalArgumentException + * if browsePath is null or an empty + * string. + */ + CompletableFuture> translateBrowsePathToParentAndTargetNodeIdAsync(String browsePath); + + /** + * Invokes an OPC UA method on an object. + * + *

+ * OPC UA methods must always be invoked on an owner object which acts as the + * method's scope. That's because the same method (with the same node id) can be + * assigned to multiple objects or even object types.
+ * The owner must have a HasComponent reference to the method. For + * more details refer to the + * + * specification (part 4). + * + *

+ * The type of the input parameters and returned values depends on the method + * configuration on the server and the caller is expected to know these types. + * {@link IOpcUaClient} gives more information on types. + * + *

+ * This is a blocking call which returns only after the request to the server + * has been completed. For a non-blocking variant, see + * {@link #invokeMethodAsync(NodeId, NodeId, Object...)}. + * + * @param ownerId + * The node id of the object (or object type) on which to invoke the + * method. + * @param methodId + * The node id of the method to invoke. + * @param parameters + * The input parameters of the operation. + * + * @return The outputs from the operation. + * + * @throws OpcUaException + * if an OPC UA related error occurs. This is a generic wrapper type + * for exceptions thrown by the client library. + * @throws IllegalArgumentException + * if ownerId or methodId is + * null. + */ + List invokeMethod(NodeId ownerId, NodeId methodId, Object... parameters) throws OpcUaException; + + /** + * Invokes an OPC UA method on an object. + * + *

+ * OPC UA methods must always be invoked on an owner object which acts as the + * method's scope. That's because the same method (with the same node id) can be + * assigned to multiple objects or even object types.
+ * The owner must have a HasComponent reference to the method. For + * more details refer to the + * + * specification (part 4). + * + *

+ * This is an asynchronous call returning a {@link CompletableFuture} for the + * value returned by the method. For more details about possible exceptions, see + * {@link #invokeMethod(NodeId, NodeId, Object...)}. + * + * @param ownerId + * The node id of the object (or object type) on which to invoke the + * method. + * @param methodId + * The node id of the method to invoke. + * @param parameters + * The input parameters of the operation. + * + * @return A {@link CompletableFuture} for the method's outputs. + * + * @throws IllegalArgumentException + * if ownerId or methodId is + * null. + */ + CompletableFuture> invokeMethodAsync(NodeId ownerId, NodeId methodId, Object... parameters); + + /** + * Reads the current value from an OPC UA node. + * + *

+ * The returned type depends on the node's data type on the server and the + * caller is expected to know which type to expect. {@link IOpcUaClient} gives + * more information on types. + * + *

+ * This is a blocking call which returns only after the request to the server + * has been completed. For a non-blocking variant, see + * {@link #readValueAsync(NodeId)}. + * + * @param nodeId + * The id of the node to read. + * + * @return The node's current value. + * + * + * @throws OpcUaException + * if an OPC UA related error occurs or if the server can't provide + * a valid value at this time. This is a generic wrapper type for + * exceptions thrown by the client library. + * @throws IllegalArgumentException + * if nodeId is null. + */ + Object readValue(NodeId nodeId) throws OpcUaException; + + /** + * Reads the current value from an OPC UA node. + * + *

+ * This is an asynchronous call returning a {@link CompletableFuture}. For more + * details about the value returned by the future and possible exceptions, see + * {@link #readValue(NodeId)}. + * + * @param nodeId + * The id of the node to read. + * + * @return A {@link CompletableFuture} for the node's current value. + * + * @throws IllegalArgumentException + * if nodeId is null. + */ + CompletableFuture readValueAsync(NodeId nodeId); + + /** + * Writes the value of an OPC UA node. + * + *

+ * The type of the value to write depends on the node's data type on the server + * and the caller is expected to know which type to pass. {@link IOpcUaClient} + * gives more information on types. + * + *

+ * This is a blocking call which returns only after the request to the server + * has been completed. For a non-blocking variant, see + * {@link #writeValueAsync(NodeId, Object)}. + * + * @param nodeId + * The id of the node to write. + * @param value + * The new value to write. Can be null. + * + * @throws OpcUaException + * if an OPC UA related error occurs. This is a generic wrapper type + * for exceptions thrown by the client library. + * @throws IllegalArgumentException + * if nodeId is null. + */ + void writeValue(NodeId nodeId, Object value) throws OpcUaException; + + /** + * Writes the value of an OPC UA node. + * + *

+ * This is an asynchronous call returning a {@link CompletableFuture}. The + * future doesn't supply a value but can be used to wait for completion and to + * receive exceptions thrown during the write procedure. For more details about + * possible exceptions, see {@link #writeValue(NodeId, Object)}. + * + * @param nodeId + * The id of the node to write. + * @param value + * The new value to write. Can be null. + * + * @return A {@link CompletableFuture}. + * + * @throws IllegalArgumentException + * if MiloNodeIdWrapper is null. + */ + CompletableFuture writeValueAsync(NodeId nodeId, Object value); +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java index b6fa2bf1..7154a362 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnector.java @@ -1,238 +1,243 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2021 Festo Didactic SE + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.opcua.connector; -import java.util.ArrayList; +import java.time.Duration; import java.util.List; -import java.util.concurrent.CompletableFuture; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; -import org.eclipse.basyx.vab.protocol.opcua.server.BaSyxOpcUaClientRunner; -import org.eclipse.milo.opcua.stack.core.Identifiers; -import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; -import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; -import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; -import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; -import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; -import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; -import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort; -import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePath; -import org.eclipse.milo.opcua.stack.core.types.structured.CallResponse; -import org.eclipse.milo.opcua.stack.core.types.structured.RelativePath; -import org.eclipse.milo.opcua.stack.core.types.structured.RelativePathElement; -import org.eclipse.milo.opcua.stack.core.types.structured.TranslateBrowsePathsToNodeIdsResponse; +import org.eclipse.basyx.vab.protocol.opcua.exception.OpcUaException; +import org.eclipse.basyx.vab.protocol.opcua.types.NodeId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * OPC UA connector class - * - * @author kdorofeev + * The OpcUaConnector can be used to connect to remote models over OPC UA. + * + *

+ * When this class is instantiated with an endpoint URL, an {@link IOpcUaClient} + * is automatically created with a default configuration. The default is an + * insecure, anonymous connection without a client certificate. + * + *

+ * The configuration can be changed as long as no connection has been + * established. A connection is established automatically the first time a node + * is read or written or an operation is invoked, either through this connector + * or directly through the associated {@link IOpcUaClient}.
+ * To change the configuration, do the following: + * + *

+ * ClientConfiguration config = opcUaConnector.getClient().getConfiguration();
+ * // Modify configuration
+ * opcUaConnector.getClient().setConfiguration(config);
+ * 
+ * + *

Using browse paths

+ * + * This class uses browses paths to identify OPC UA nodes for read, write and + * invoke requests. That has two noteworthy caveats: + *
    + *
  1. Browse paths aren't necessarily unambiguous. In other words, a browse + * path might match more than one node. This would lead to an exception being + * returned from this connector.
    + * It is up to the user to make sure their server's address space doesn't have + * that problem. + *
  2. The connector must translate the browse path to a unique node id in the + * background. That necessitates an additional network request to the server, + * every time a read, write or invoke request is made.
    + * To address this issue, this class contains a cache for translated browse + * paths. + *
* + *

Node id cache

+ * + * Using the cache is entirely optional and it is disabled be default. It can be + * enabled using {@link #setNodeIdCacheDuration(Duration)}. + * + *

+ * If it is enabled, it will cache any browse path passed to + * {@link #getValue(String)}, {@link #setValue(String, Object)} or + * {@link #invokeOperation(String, Object...)} and the matching node id for the + * specified duration. Subsequent requests using the same browse path within the + * configured timespan would omit the additional network request for browse path + * resolution. + * + *

+ * Caution: An OPC UA server can dynamically reconfigure their address + * space during runtime. This could even be done remotely from clients, if the + * server allows it.
+ * Such changes would render this cache invalid, but there is no way for this + * connector to get notified of them. Only use the cache with servers where you + * can be sure the address space doesn't change. */ public class OpcUaConnector implements IModelProvider { - - private Logger logger = LoggerFactory.getLogger(OpcUaConnector.class); - - private String address; - private BaSyxOpcUaClientRunner clientRunner; - - /** - * Invoke a BaSys get operation via OPC UA - * - * @param servicePath - * requested node path - * @return the requested value - */ - @Override - public String getValue(String servicePath) { - try { - clientRunner = new BaSyxOpcUaClientRunner(address); - clientRunner.run(); - } catch (Exception e) { - logger.error("Exception in getModelPropertyValue", e); - throw new RuntimeException(e); - } - return opcUaRead(translateBrowsePathToNodeId(servicePath)[1]); - } - - @Override - public void setValue(String servicePath, Object newValue) throws ProviderException { - try { - clientRunner = new BaSyxOpcUaClientRunner(address); - clientRunner.run(); - } catch (Exception e) { - logger.error("Exception in setModelPropertyValue", e); - throw new RuntimeException(e); - } - opcUaWrite(translateBrowsePathToNodeId(servicePath)[1], newValue); - } - - @Override + /** + * {@link TimerTask} which removes an entry from a map. + */ + private static class RemoveEntryFromMapTimerTask extends TimerTask { + Map map; + TKey key; + + public RemoveEntryFromMapTimerTask(Map map, TKey key) { + this.map = map; + this.key = key; + } + + @Override + public void run() { + map.remove(key); + } + } + + private static final Timer cacheTimer = new Timer(true); + private final Logger logger = LoggerFactory.getLogger(getClass()); + private Duration cacheDuration = Duration.ZERO; + private IOpcUaClient client; + private Map nodeIdCache = new ConcurrentHashMap<>(); + private Map> operationNodeIdsCache = new ConcurrentHashMap<>(); + + public OpcUaConnector(String endpointUrl) { + client = IOpcUaClient.create(endpointUrl); + } + + /** + * Gets the OPC UA client used for communication to the server. + * + * @return The OPC UA client object. + */ + public IOpcUaClient getClient() { + return client; + } + + /** + * Sets the duration for the NodeId cache. + * + *

+ * When a {@link OpcUaConnector} resolves a browse path to a NodeId, it can + * cache the result to make future access to that same browse path more + * efficient.
+ * This setting controls how long looked up NodeIds remain cached. A value of + * {@link Duration#ZERO} disables the cache. + * + *

+ * See {@link OpcUaConnector} for more information on the caching feature. + * + * @param cacheDuration + * The cache duration. {@link Duration#ZERO} disable the cache. + * + * @throws IllegalArgumentException + * if cacheDuration is null or negative. + */ + public void setNodeIdCacheDuration(Duration cacheDuration) { + if (cacheDuration == null || cacheDuration.isNegative()) { + throw new IllegalArgumentException("cacheDuration must not be negative."); + } + + this.cacheDuration = cacheDuration; + } + + @Override + public Object getValue(String path) throws OpcUaException { + try { + NodeId nodeId = getNodeIdForBrowsePath(path); + return client.readValue(nodeId); + } catch (OpcUaException e) { + logger.error("Failed to get node value."); + throw e; + } + } + + @Override + public void setValue(String path, Object newValue) throws OpcUaException { + try { + NodeId nodeId = getNodeIdForBrowsePath(path); + client.writeValue(nodeId, newValue); + } catch (OpcUaException e) { + logger.error("Failed to set node value."); + throw e; + } + } + + @Override public void createValue(String path, Object newEntity) throws ProviderException { + throw new UnsupportedOperationException("Cannot create values through OPC UA."); + } - } - - @Override + @Override public void deleteValue(String path) throws ProviderException { + throw new UnsupportedOperationException("Cannot delete values through OPC UA."); + } - } - - @Override + @Override public void deleteValue(String path, Object obj) throws ProviderException { - - } - - @Override - public Object invokeOperation(String servicePath, Object... parameters) throws ProviderException { - try { - clientRunner = new BaSyxOpcUaClientRunner(address); - clientRunner.run(); - } catch (Exception e) { - logger.error("Exception in invokeOperation", e); - throw new RuntimeException(e); - } - return opcUaMethodCall(translateBrowsePathToNodeId(servicePath), parameters); - } - - public OpcUaConnector(String address) { - this.address = address; - } - - /** - * Perform a OPC UA read request - * - * @param servicePath - * @return - */ - private String opcUaRead(NodeId servicePath) { - try { - List nodes = new ArrayList(); - nodes.add(servicePath); - CompletableFuture> result = clientRunner.read(nodes); - - return result.get().get(0).getValue().getValue().toString(); - - } catch (Exception e) { - logger.error("Exception in opcUaRead", e); - } - return null; - } - - private String opcUaMethodCall(NodeId[] methodNodes, Object[] inputParameters) { - try { - Variant[] inputs = new Variant[inputParameters.length]; - for (int i = 0; i < inputParameters.length; i++) { - inputs[i] = new Variant(inputParameters[i]); - } - CompletableFuture result = clientRunner.callMethod(methodNodes[0], methodNodes[1], inputs); - Variant[] outputs = result.get().getResults()[0].getOutputArguments(); - String ret = ""; - for (Variant var : outputs) { - ret += var.getValue() + " "; - } - return ret; - } catch (Exception e) { - logger.error("Exception in opcUaMethodCall", e); - } - return null; - } - - private String opcUaWrite(NodeId servicePath, Object parameter) throws ProviderException { - try { - List nodes = new ArrayList(); - nodes.add(servicePath); - List parameters = new ArrayList(); - parameters.add(new DataValue(new Variant(parameter), null, null, null)); - CompletableFuture> result = clientRunner.write(nodes, parameters); - - return result.get().get(0).toString(); - } catch (Exception e) { - logger.error("Exception in opcUaWrite", e); - } - return null; - } - - private NodeId[] translateBrowsePathToNodeId(String path) { - String[] nodes = path.split("/"); - List rpe_list = new ArrayList(); - for (String node : nodes) { - if (node.split(":").length != 2) { - logger.warn("OpcUaName should be in form namespaceIdx:identifier"); - } - int nsIdx = Integer.valueOf(node.split(":")[0]); - String name = node.split(":")[1]; - rpe_list.add(new RelativePathElement(Identifiers.HierarchicalReferences, false, true, - new QualifiedName(nsIdx, name))); - } - RelativePathElement[] rpe_node_arr = new RelativePathElement[rpe_list.size()]; - RelativePathElement[] rpe_parent_arr = new RelativePathElement[rpe_list.size() - 1]; - rpe_node_arr = rpe_list.toArray(rpe_node_arr); - - // get list for parent (all but the last one) - rpe_list.remove(rpe_list.size() - 1); - rpe_parent_arr = rpe_list.toArray(rpe_parent_arr); - - BrowsePath bp_node = new BrowsePath(Identifiers.RootFolder, new RelativePath(rpe_node_arr)); - BrowsePath bp_parent = new BrowsePath(Identifiers.RootFolder, new RelativePath(rpe_parent_arr)); - List bp_node_list = new ArrayList(); - List bp_parent_list = new ArrayList(); - bp_node_list.add(bp_node); - bp_parent_list.add(bp_parent); - try { - CompletableFuture result_node = clientRunner.translate(bp_node_list); - CompletableFuture result_parent = clientRunner - .translate(bp_parent_list); - if (result_node.get().getResults().length == 0) { - logger.warn("TranslateBrowsePathsToNodeIdsResponse result size = 0, check the browse path!"); - return null; - } - if (result_node.get().getResults().length > 1) { - logger.warn("TranslateBrowsePathsToNodeIdsResponse result size > 1, the method returns only the first one!"); - } - if (result_node.get().getResults()[0].getTargets() == null || result_node.get().getResults()[0].getTargets().length == 0) { - logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size = 0, check the browse path!"); - logger.trace(result_node.get().getResults()[0].getStatusCode().toString()); - return null; - } - if (result_node.get().getResults()[0].getTargets().length > 1) { - logger.warn("TranslateBrowsePathsToNodeIdsResponse targets size > 1, the method returns only the first one!"); - } - Object nodeIdentifier = result_node.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier(); - Object parentIdentifier = result_parent.get().getResults()[0].getTargets()[0].getTargetId().getIdentifier(); - UShort nodeNsIdx = result_node.get().getResults()[0].getTargets()[0].getTargetId().getNamespaceIndex(); - UShort parentNsIdx = result_parent.get().getResults()[0].getTargets()[0].getTargetId().getNamespaceIndex(); - if (nodeIdentifier instanceof String && parentIdentifier instanceof String) { - return new NodeId[] { new NodeId(parentNsIdx, (String) parentIdentifier), - new NodeId(nodeNsIdx, (String) nodeIdentifier) }; - } - if (nodeIdentifier instanceof UInteger && parentIdentifier instanceof UInteger) { - return new NodeId[] { new NodeId(parentNsIdx, (UInteger) parentIdentifier), - new NodeId(nodeNsIdx, (UInteger) nodeIdentifier) }; - } - if (nodeIdentifier instanceof UInteger && parentIdentifier instanceof String) { - return new NodeId[] { new NodeId(parentNsIdx, (String) parentIdentifier), - new NodeId(nodeNsIdx, (UInteger) nodeIdentifier) }; - } - if (nodeIdentifier instanceof String && parentIdentifier instanceof UInteger) { - return new NodeId[] { new NodeId(parentNsIdx, (UInteger) parentIdentifier), - new NodeId(nodeNsIdx, (String) nodeIdentifier) }; - } else { - logger.error("NodeId identifier is not neither String, nor int"); - return null; - } - } catch (Exception e) { - logger.error("Exception in translateBrowsePathToNodeId", e); - } - return null; - } - + throw new UnsupportedOperationException("Cannot delete values through OPC UA."); + } + + @Override + public Object invokeOperation(String path, Object... parameters) throws OpcUaException { + try { + List nodeIds = getNodeIdsForOperationBrowsePath(path); + return client.invokeMethod(nodeIds.get(1), nodeIds.get(0), parameters); + } catch (OpcUaException e) { + logger.error("Failed to invoke operation."); + throw e; + } + } + + private NodeId getNodeIdForBrowsePath(String browsePath) { + if (nodeIdCache.containsKey(browsePath)) { + logger.debug("Using cached NodeId for browse path '{}'.", browsePath); + return nodeIdCache.get(browsePath); + } + + NodeId nodeId = client.translateBrowsePathToNodeId(browsePath); + + if (!cacheDuration.isZero()) { + nodeIdCache.put(browsePath, nodeId); + cacheTimer.schedule(new RemoveEntryFromMapTimerTask<>(nodeIdCache, browsePath), cacheDuration.toMillis()); + } + return nodeId; + } + + private List getNodeIdsForOperationBrowsePath(String browsePath) { + if (operationNodeIdsCache.containsKey(browsePath)) { + logger.debug("Using cached NodeIds for operation at browse path '{}'.", browsePath); + return operationNodeIdsCache.get(browsePath); + } + + List nodeIds = client.translateBrowsePathToParentAndTargetNodeId(browsePath); + + if (!cacheDuration.isZero()) { + operationNodeIdsCache.put(browsePath, nodeIds); + cacheTimer.schedule(new RemoveEntryFromMapTimerTask<>(operationNodeIdsCache, browsePath), cacheDuration.toMillis()); + } + return nodeIds; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorFactory.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorFactory.java new file mode 100644 index 00000000..3df87fd1 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorFactory.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.connector; + +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.eclipse.basyx.vab.protocol.api.ConnectorFactory; + +/** + * OPC UA connector factory. + */ +public class OpcUaConnectorFactory extends ConnectorFactory { + + private final ClientConfiguration defaultConfiguration; + + /** + * Creates a new connector factory. + */ + public OpcUaConnectorFactory() { + super(); + defaultConfiguration = null; + } + + /** + * Creates a new connector factory which applies a default client configuration + * to connectors. + * + *

+ * Note, that the configuration is copied internally, so changes made to the + * object after creating the factory do not apply to connectors created by it. + * + * @param defaultConfiguration + * The default connector configuration. + */ + public OpcUaConnectorFactory(ClientConfiguration defaultConfiguration) { + super(); + this.defaultConfiguration = defaultConfiguration; + } + + /** + * Creates a new {@link OpcUaConnector} for the given endpoint URL. + * + *

+ * If a default configuration has been set, it will be applied to the connector + * before it is returned. + * + * @return A new {@link OpcUaConnector} for the given endpoint URL. + */ + @Override + protected IModelProvider createProvider(String addr) { + OpcUaConnector c = new OpcUaConnector(addr); + + if (defaultConfiguration != null) { + c.getClient().setConfiguration(defaultConfiguration); + } + + return c; + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java index c5c64770..2068edf3 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/OpcUaConnectorProvider.java @@ -1,33 +1,35 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2021 Festo Didactic SE + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.opcua.connector; -import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; -import org.eclipse.basyx.vab.protocol.api.ConnectorFactory; - /** - * OPC UA connector provider class - * - * @author kdorofeev + * OPC UA connector factory class. * + * @deprecated As of version 1.1. Replaced by {@link OpcUaConnectorFactory}. */ -public class OpcUaConnectorProvider extends ConnectorFactory { - - /** - * returns HTTPConnetor wrapped with ConnectedHashmapProvider that handles - * message header information - */ - @Override - protected IModelProvider createProvider(String addr) { - - return new OpcUaConnector(addr); - } +@Deprecated +public class OpcUaConnectorProvider extends OpcUaConnectorFactory { } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/milo/BrowsePathHelper.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/milo/BrowsePathHelper.java new file mode 100644 index 00000000..5a239366 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/milo/BrowsePathHelper.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.connector.milo; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.basyx.vab.protocol.opcua.exception.OpcUaException; +import org.eclipse.basyx.vab.protocol.opcua.types.NodeId; +import org.eclipse.milo.opcua.stack.core.BuiltinReferenceType; +import org.eclipse.milo.opcua.stack.core.Identifiers; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePath; +import org.eclipse.milo.opcua.stack.core.types.structured.RelativePath; +import org.eclipse.milo.opcua.stack.core.types.structured.RelativePathElement; + +/** + * Converts between string-formatted browse path and a {@link BrowsePath} + * object. + * + *

+ * The string must be formatted according to the + * BNF + * format of relative paths. + * + *

+ * Note that this helper doesn't currently support browse paths which directly + * specify a reference type to follow, using the <...> + * syntax. Only the more general hierarchical (/) and aggregate + * (.) reference types are supported. + */ +public final class BrowsePathHelper { + private static final String REFERENCE_TYPE_SPLIT = "(?<...> syntax. + * @throws IllegalArgumentException + * if s is null or an empty string. + */ + public static BrowsePath parse(String s) throws OpcUaException { + NodeId root = new NodeId(Identifiers.RootFolder); + return parse(root, s); + } + + /** + * Creates a browse path starting at the given node from the given string. + * + * @param startingNode + * The node from where to resolve the browse path. + * @param s + * The relative browse path starting at the root node. + * + * @return The {@link BrowsePath} object represented by the given string. + * + * @throws OpcUaException + * if the browse path is not valid. + * @throws UnsupportedOperationException + * if the browse path contains directly specified reference types + * using the <...> syntax. + * @throws IllegalArgumentException + * if startingNode or s are null or if s is an empty + * string. + */ + public static BrowsePath parse(NodeId startingNode, String s) throws OpcUaException { + if (startingNode == null || s == null) { + throw new IllegalArgumentException("startingNode and s must not be null."); + } + if (s.isEmpty()) { + throw new IllegalArgumentException("s must not be empty."); + } + + BrowsePathHelper helper = new BrowsePathHelper(s); + + List elements = new LinkedList<>(); + RelativePathElement elem; + while ((elem = helper.next()) != null) { + elements.add(elem); + } + + RelativePathElement[] arr = elements.toArray(new RelativePathElement[0]); + RelativePath relativePath = new RelativePath(arr); + + return new BrowsePath(startingNode.getInternalId(), relativePath); + } + + /** + * Creates a new browse path pointing to the second to last element of the given + * path. + * + * @param browsePath + * The original browse path. + * + * @return A new browse path which points to the second to last node in + * browsePath. + * + * @throws IllegalArgumentException + * if browsePath is null or it's relative + * path is empty. + */ + public static BrowsePath getParent(BrowsePath browsePath) { + if (browsePath == null) { + throw new IllegalArgumentException("browsePath must not be null."); + } + + RelativePathElement[] targetElements = browsePath.getRelativePath().getElements(); + + if (targetElements.length == 0) { + throw new IllegalArgumentException("Can't generate browse path to parent of an empty path."); + } + + // Copy all but the last element from the original relative path to a new array + // and + // create a new relative path from that. + RelativePathElement[] parentElements = Arrays.copyOf(targetElements, targetElements.length - 1); + RelativePath parentPath = new RelativePath(parentElements); + + return new BrowsePath(browsePath.getStartingNode(), parentPath); + } + + /** + * Returns a string representation of the given relative path. + * + * @param relativePath + * The relative path of a browse path. + * + * @return The string representation in accordance with the BNF + * format of relative paths. + * + * @throws IllegalArgumentException + * if relativePath contains references, which don't map to either + * '/' or '.' or if it is invalid. + */ + public static String toString(RelativePath relativePath) { + StringBuilder sb = new StringBuilder(); + + RelativePathElement[] elems = relativePath.getElements(); + + for (int i = 0; i < elems.length; i++) { + if (isAllHierarchicalReferences(elems[i])) { + sb.append('/'); + } else if (isAllAggregatesReferences(elems[i])) { + sb.append('.'); + } else { + throw new IllegalArgumentException("relativePath contains directly specified references which aren't supported."); + } + + if (elems[i].getTargetName() != null) { + sb.append(qualifiedNameToString(elems[i].getTargetName())); + } else if (i != elems.length - 1) { + throw new IllegalArgumentException("Only the last element in a relative path is allowed to have no name."); + } + } + + return sb.toString(); + } + + private static boolean isAllHierarchicalReferences(RelativePathElement rpe) { + return rpe.getReferenceTypeId().equals(BuiltinReferenceType.HierarchicalReferences.getNodeId()) && !rpe.getIsInverse() && rpe.getIncludeSubtypes(); + } + + private static boolean isAllAggregatesReferences(RelativePathElement rpe) { + return rpe.getReferenceTypeId().equals(BuiltinReferenceType.Aggregates.getNodeId()) && !rpe.getIsInverse() && rpe.getIncludeSubtypes(); + } + + private static String qualifiedNameToString(QualifiedName qn) { + return qn.getNamespaceIndex().toString() + ':' + qn.getName(); + } + + private RelativePathElement next() { + if (index >= path.length()) { + return null; + } + + org.eclipse.milo.opcua.stack.core.types.builtin.NodeId referenceType = parseReferenceType(); + QualifiedName qualifiedName = parseQualifiedName(); + return new RelativePathElement(referenceType, false, true, qualifiedName); + } + + private org.eclipse.milo.opcua.stack.core.types.builtin.NodeId parseReferenceType() { + switch (path.charAt(index)) { + case '/': + index++; + return BuiltinReferenceType.HierarchicalReferences.getNodeId(); + + case '.': + index++; + return BuiltinReferenceType.Aggregates.getNodeId(); + + case '<': + throw new IllegalArgumentException("This helper doesn't supported directly specified reference types."); + + default: + throw new OpcUaException(String.format("Invalid browse path at index %d: %s", index, path)); + } + } + + private QualifiedName parseQualifiedName() { + if (index == path.length()) { + // The last element in a browse path is allowed to have no qualified name. + return null; + } + + // Returns only the part of the path between the current index and the next + // separator. + String pathElement = path.substring(index).split(REFERENCE_TYPE_SPLIT, 2)[0]; + + String[] s = pathElement.split(NAMESPACE_SPLIT, 3); + QualifiedName qn; + if (s.length == 1) { + // RelativePathElement has no namespace index -> Uses default namespace '0'. + qn = parseQualifiedName(s[0]); + } else if (s.length == 2) { + // RelativePathElement has a namespace index. + qn = parseQualifiedName(s[0], s[1]); + } else { + // RelativePathElement contains more than one colon. + throw new OpcUaException(String.format("Not a valid relative path element starting at index %d: %s", index, path)); + } + + index += pathElement.length(); + return qn; + } + + private QualifiedName parseQualifiedName(String browseName) { + String unescaped = unescape(browseName); + if (unescaped.isEmpty()) { + throw new OpcUaException(String.format("Browse path contains invalid browse name at index %d: %s", index, path)); + } + + return new QualifiedName(0, unescaped); + } + + private QualifiedName parseQualifiedName(String namespaceIndex, String browseName) { + int ns; + try { + ns = Integer.parseUnsignedInt(namespaceIndex); + } catch (NumberFormatException e) { + throw new OpcUaException(String.format("Browse path contains invalid namespace index at index %d: %s", index, path)); + } + + String escaped = unescape(browseName); + if (escaped.isEmpty()) { + throw new OpcUaException(String.format("Browse path contains invalid browse name at index %d: %s", index, path)); + } + return new QualifiedName(ns, escaped); + } + + private String unescape(String s) { + return s.replace("&", ""); + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/milo/MiloOpcUaClient.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/milo/MiloOpcUaClient.java new file mode 100644 index 00000000..33ebf4ba --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/connector/milo/MiloOpcUaClient.java @@ -0,0 +1,834 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.connector.milo; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutionException; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeConstants; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.protocol.opcua.connector.ClientConfiguration; +import org.eclipse.basyx.vab.protocol.opcua.connector.IOpcUaClient; +import org.eclipse.basyx.vab.protocol.opcua.exception.AmbiguousBrowsePathException; +import org.eclipse.basyx.vab.protocol.opcua.exception.OpcUaException; +import org.eclipse.basyx.vab.protocol.opcua.types.MessageSecurityMode; +import org.eclipse.basyx.vab.protocol.opcua.types.NodeId; +import org.eclipse.basyx.vab.protocol.opcua.types.SecurityPolicy; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedByte; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedInteger; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedLong; +import org.eclipse.basyx.vab.protocol.opcua.types.UnsignedShort; +import org.eclipse.milo.opcua.sdk.client.AddressSpace; +import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +import org.eclipse.milo.opcua.sdk.client.api.UaClient; +import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; +import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder; +import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider; +import org.eclipse.milo.opcua.stack.client.DiscoveryClient; +import org.eclipse.milo.opcua.stack.core.UaException; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime; +import org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId; +import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText; +import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.ULong; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort; +import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePath; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePathResult; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePathTarget; +import org.eclipse.milo.opcua.stack.core.types.structured.CallMethodRequest; +import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription; +import org.eclipse.milo.opcua.stack.core.types.structured.TranslateBrowsePathsToNodeIdsResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides a wrapper around the eclipse Milo OPC UA client that works in the + * BaSyx environment. + */ +public class MiloOpcUaClient implements IOpcUaClient { + private static final Logger logger = LoggerFactory.getLogger(MiloOpcUaClient.class); + private static DatatypeFactory xmlDatatypeFactory; + + private ClientConfiguration configuration = new ClientConfiguration(); + private OpcUaClientConfigBuilder miloConfiguration; + private CompletableFuture futureClient; + private String endpointUrl; + + static { + try { + xmlDatatypeFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + logger.error("Failed to instantiate XML DatatypeFactory. This will lead to NullPointerExceptions, if DateTime values are received from the OPC UA server.", e); + } + } + + /** + * Creates a new OPC UA client for the given endpoint URL with a default + * configuration. + * + *

+ * The client will attempt to discover available endpoint at this URL. The one + * to use will be selected by looking at the security policy and message + * security mode. These can be configured using + * {@link #setConfiguration(ClientConfiguration)}. + * + * @param endpointUrl + * The client will attempt to discover available endpoints at this + * URL. Among all of these the one that matches the configured + * security policy and message security mode will be selected. + * + * @throws IllegalArgumentException + * if endpointUrl is null. + */ + public MiloOpcUaClient(String endpointUrl) { + if (endpointUrl == null || endpointUrl.isEmpty()) { + throw new IllegalArgumentException("endpointUrl must not be null."); + } + + this.endpointUrl = endpointUrl; + } + + /** + * Gets the current client configuration. + * + *

+ * See the documentation of {@link IOpcUaClient#getConfiguration()} for more + * information. + * + * @return A copy of the current configuration. + */ + @Override + public synchronized ClientConfiguration getConfiguration() { + // Return a copy to protect from external changes. + return configuration.clone(); + } + + /** + * Sets the client configuration. + * + *

+ * See the documentation of + * {@link IOpcUaClient#setConfiguration(ClientConfiguration)} for more + * information. + */ + @Override + public synchronized void setConfiguration(ClientConfiguration configuration) { + if (hasConnected()) { + throw new IllegalStateException("Cannot change security configuration after opening the connection."); + } + + // Create a local copy to protect from external changes. + this.configuration = (configuration != null) ? configuration.clone() : new ClientConfiguration(); + } + + /** + * Sets advanced configuration settings not available in + * {@link ClientConfiguration}. + * + *

+ * This method allows setting a Milo-specific configuration object which gives + * access to the full range of options that Milo supports as opposed to the + * limited selection in {@link ClientConfiguration}. + * + *

+ * Be aware, that the security policy and message security mode + * for endpoint selection can only be set using + * {@link #setConfiguration(ClientConfiguration)}.
+ * Additionally, for settings which are available in both configuration objects, + * {@link ClientConfiguration} will take precedence over + * {@link OpcUaClientConfigBuilder}. + * + *

+ * The order in which you call {@link #setConfiguration(ClientConfiguration)} + * and {@link #setConfiguration(OpcUaClientConfigBuilder)} is not important. + * + * Caution: Use this method at your own risk. Your code might break if + * BaSyx switches to a newer version of Milo or a different OPC UA + * implementation altogether. + * + * @param configuration + * The Milo client configuration object. + * + * @throws IllegalStateException + * if this method is called after a connection has been established. + */ + public synchronized void setConfiguration(OpcUaClientConfigBuilder configuration) { + if (hasConnected()) { + throw new IllegalStateException("Cannot change security configuration after opening the connection."); + } + + miloConfiguration = configuration; + } + + /** + * Gets the endpoint URL that this client connects to. + * + * @return The endpoint URL of the server to connect to. + */ + @Override + public String getEndpointUrl() { + return endpointUrl; + } + + /** + * Gets a value signifying whether this client has already attempted to + * establish a connection to the server endpoint. + * + *

+ * See the documentation of {@link IOpcUaClient#hasConnected()} for more + * information. + */ + @Override + public boolean hasConnected() { + synchronized (this) { + return futureClient != null; + } + } + + /** + * Gets the client object from the underlying OPC UA library. + * + *

+ * If the client hasn't been created, yet, it will be created automatically, + * making any subsequent changes to the configuration impossible. + * + * Caution: Use this method at your own risk. The underlying client API + * might change without notice, making any user code relying on this method + * fragile. + * + * @return The underlying client object. + */ + public synchronized CompletableFuture getClient() { + if (futureClient != null) { + return futureClient; + } else { + OpcUaClient client = createClient(); + futureClient = client.connect(); + return futureClient; + } + } + + /** + * Creates an instance of the underlying client using the current configuration. + * + * @return The created client. + * + * @throws OpcUaException + * as a wrapper exception around any Milo exceptions thrown during + * client creation. + */ + private OpcUaClient createClient() { + // Set up a filter which determines the correct endpoint by its security + // settings. + SecurityPolicy securityPolicy = configuration.getSecurityPolicy(); + MessageSecurityMode messageSecurityMode = configuration.getMessageSecurityMode(); + Predicate endpointFilter = ep -> { + boolean securityPolicyMatches = ep.getSecurityPolicyUri().equals(mapSecurityPolicy(securityPolicy).getUri()); + boolean messageSecurityModeMatches = (ep.getSecurityMode() == mapMessageSecurityMode(messageSecurityMode)); + return securityPolicyMatches && messageSecurityModeMatches; + }; + + EndpointDescription endpoint = discoverEndpoint(endpointUrl, endpointFilter); + + logger.debug("Using endpoint: {} [{}/{}]", endpoint.getEndpointUrl(), securityPolicy, messageSecurityMode); + + try { + OpcUaClientConfig config = buildMiloConfiguration(endpoint); + return OpcUaClient.create(config); + } catch (UaException e) { + throw new OpcUaException(e); + } + } + + private OpcUaClientConfig buildMiloConfiguration(EndpointDescription endpoint) { + OpcUaClientConfigBuilder builder = (miloConfiguration != null) ? miloConfiguration : createDefaultMiloConfigBuilder(); + builder.setApplicationName(LocalizedText.english(configuration.getApplicationName())).setApplicationUri(configuration.getApplicationUri()).setCertificate(configuration.getCertificate()).setKeyPair(configuration.getKeyPair()) + .setEndpoint(endpoint); + + return builder.build(); + } + + private OpcUaClientConfigBuilder createDefaultMiloConfigBuilder() { + return OpcUaClientConfig.builder().setIdentityProvider(new AnonymousProvider()); + } + + /** + * Returns the first endpoint matching the filter predicate discovered at the + * endpointUrl. + * + * @param endpointUrl + * The discovery endpoint to query. + * @param filter + * A predicate that returns 'true' for any endpoint that can be used. + * + * @return The first endpoint at the URL which matches the filter. + * + * @throws OpcUaException + * if no endpoint matching the filter can be found at the url or if + * the discovery thread is interrupted. + */ + private EndpointDescription discoverEndpoint(String endpointUrl, Predicate filter) throws OpcUaException { + try { + return discoverEndpoints(endpointUrl).thenApply(list -> list.stream().filter(filter).findFirst().orElseThrow(() -> new OpcUaException("No endpoint found at " + endpointUrl))).get(); + } catch (ExecutionException e) { + throw (OpcUaException) e.getCause(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException("Endpoint discovery interrupted", e); + } + } + + /** + * Discovers all OPC UA endpoints at the given URL. + * + * @param endpointUrl + * The URL where to discover endpoints. + * + * @return A future which will either result in a list of endpoints or completes + * with an {@link OpcUaException}. + */ + private CompletableFuture> discoverEndpoints(String endpointUrl) { + return DiscoveryClient.getEndpoints(endpointUrl).handleAsync((list, ex) -> { + if (ex != null) { + return retryDiscovery(endpointUrl); + } else { + return list; + } + }); + } + + private List retryDiscovery(String endpointUrl) { + String discoveryUrl = createExplicitDiscoveryUrl(endpointUrl); + logger.debug("Discovery failed at original endpoint URL. Trying with explicit discovery URL: {}", discoveryUrl); + + try { + return DiscoveryClient.getEndpoints(discoveryUrl).get(); + } catch (InterruptedException e) { + logger.error("Endpoint discovery failed because thread was interrupted."); + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + logger.error("Endpoint discovery failed."); + throw makeOpcUaExceptionFromCause(e); + } + } + + private String createExplicitDiscoveryUrl(String discoveryUrl) { + discoveryUrl = discoveryUrl.endsWith("/") ? discoveryUrl : discoveryUrl + "/"; + return discoveryUrl + "discovery"; + } + + /** Maps the BaSyx SecurityPolicy enum to the matching Milo enum */ + private org.eclipse.milo.opcua.stack.core.security.SecurityPolicy mapSecurityPolicy(SecurityPolicy securityPolicy) { + return org.eclipse.milo.opcua.stack.core.security.SecurityPolicy.valueOf(securityPolicy.toString()); + } + + /** Maps the BaSyx MessageSecurityMode enum to the matching Milo enum */ + private org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode mapMessageSecurityMode(MessageSecurityMode messageSecurityMode) { + return org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode.valueOf(messageSecurityMode.toString()); + } + + /** + * Gets the id of the node matching the given browse path when resolved against + * the root node. + * + *

+ * See the documentation of + * {@link IOpcUaClient#translateBrowsePathToNodeId(String)} for more + * information. + */ + @Override + public NodeId translateBrowsePathToNodeId(String browsePath) { + try { + return translateBrowsePathToNodeIdAsync(browsePath).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + throw makeOpcUaExceptionFromCause(e); + } + } + + /** + * Gets the id of the node matching the given browse path when resolved against + * the root node. + * + *

+ * See the documentation of + * {@link IOpcUaClient#translateBrowsePathToNodeIdAsync(String)} for more + * information. + */ + @Override + public CompletableFuture translateBrowsePathToNodeIdAsync(String browsePath) { + BrowsePath bp = BrowsePathHelper.parse(browsePath); + return translateBrowsePathToNodeId(bp); + } + + /** + * Gets the id of the node pointed to by when resolving the given path against + * the starting node. + * + *

+ * See the documentation of + * {@link IOpcUaClient#translateBrowsePathToNodeId(NodeId, String)} for more + * information. + */ + @Override + public NodeId translateBrowsePathToNodeId(NodeId startingNode, String relativePath) { + try { + return translateBrowsePathToNodeIdAsync(startingNode, relativePath).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + throw makeOpcUaExceptionFromCause(e); + } + } + + /** + * Gets the id of the node pointed to by when resolving the given path against + * the starting node. + * + *

+ * See the documentation of + * {@link IOpcUaClient#translateBrowsePathToNodeId(NodeId, String)} for more + * information. + */ + @Override + public CompletableFuture translateBrowsePathToNodeIdAsync(NodeId startingNode, String relativePath) { + if (!(startingNode instanceof NodeId)) { + throw new IllegalArgumentException(); + } + + BrowsePath bp = BrowsePathHelper.parse(startingNode, relativePath); + return translateBrowsePathToNodeId(bp); + } + + /** + * Gets the id of the last two nodes pointed to by when resolving the given path + * against the starting node. + * + *

+ * See the documentation of + * {@link IOpcUaClient#translateBrowsePathToParentAndTargetNodeId(String)} for + * more information. + */ + @Override + public List translateBrowsePathToParentAndTargetNodeId(String browsePath) { + try { + return translateBrowsePathToParentAndTargetNodeIdAsync(browsePath).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + throw makeOpcUaExceptionFromCause(e); + } + } + + /** + * Gets the id of the last two nodes pointed to by when resolving the given path + * against the starting node. + * + *

+ * See the documentation of + * {@link IOpcUaClient#translateBrowsePathToParentAndTargetNodeIdAsync(String)} + * for more information. + */ + @Override + public CompletableFuture> translateBrowsePathToParentAndTargetNodeIdAsync(String browsePath) { + BrowsePath targetPath = BrowsePathHelper.parse(browsePath); + BrowsePath parentPath = BrowsePathHelper.getParent(targetPath); + + List browsePaths = new ArrayList<>(2); + browsePaths.add(0, targetPath); + browsePaths.add(1, parentPath); + + return translateBrowsePathsToNodeIds(browsePaths); + } + + /** + * Translates a list of browse paths to a list of associated node ids. + * + * @param browsePaths + * A list of browse paths to resolve. + * + * @return A future for a list of node ids. Ids are ordered in the same way as + * their matching browse paths. + * + * @throws ResourceNotFoundException + * if any of the browse paths doesn't lead to any node at all. + * @throws AmbiguousBrowsePathException + * if any of the browse paths is ambiguous, i.e., it leads to + * multiple nodes. + * @throws OpcUaException + * if any other OPC UA related error occurs. This is a generic + * wrapper type for exceptions thrown by the client library. + */ + private CompletableFuture> translateBrowsePathsToNodeIds(List browsePaths) { + // Prepare this 'address space' for later when we need to convert an expanded + // node id + // to a regular one. That requires a round-trip with the server. + CompletableFuture futureAddressSpace = getClient().thenApplyAsync(UaClient::getAddressSpace); + + // This function gets the results from the response, unless the service failed + // in some way. + Function getResults = response -> { + if (!response.getResponseHeader().getServiceResult().isGood()) { + throw new OpcUaException("TranslateBrowsePaths failed with status code: " + response.getResponseHeader().getServiceResult()); + } else { + return response.getResults(); + } + }; + + // This function gets the expanded node id matching each browse path, unless at + // least one + // of them failed to resolve or was ambiguous. + Function> extractExpandedNodeIds = results -> { + List exNodeIds = new ArrayList<>(results.length); + for (int i = 0; i < results.length; i++) { + BrowsePathResult r = results[i]; + + if (!r.getStatusCode().isGood()) { + String exceptionMessage = String.format("Browse path [%s] failed to resolve with status code: %s", browsePaths.get(i), r.getStatusCode()); + throw new ResourceNotFoundException(exceptionMessage); + } else { + BrowsePathTarget[] targets = r.getTargets(); + if (targets.length > 1) { + String exceptionMessage = String.format("Browse path [%s] leads to multiple targets.", browsePaths.get(i)); + throw new AmbiguousBrowsePathException(exceptionMessage); + } + exNodeIds.add(i, targets[0].getTargetId()); + } + } + return exNodeIds; + }; + + // This function maps the expanded node ids to regular node ids, using a + // provided + // address space object. + BiFunction, AddressSpace, List> mapToNodeIds = (expandedNodeIds, addressSpace) -> expandedNodeIds.stream().map(addressSpace::toNodeId).map(NodeId::new).collect(Collectors.toList()); + + // This function logs the result and returns it without any changes. + UnaryOperator> log = nodeIds -> { + List bpStrings = browsePaths.stream().map(bp -> BrowsePathHelper.toString(bp.getRelativePath())).collect(Collectors.toList()); + logger.debug("Translated browse paths {} to node ids {}", bpStrings, nodeIds); + + return nodeIds; + }; + + // Prepare the future which returns the node ids. + CompletableFuture> future = getClient().thenCompose(client -> client.translateBrowsePaths(browsePaths)).thenApply(getResults).thenApply(extractExpandedNodeIds).thenCombine(futureAddressSpace, mapToNodeIds); + + // Add the logger stage only if required because it is computationally rather + // expensive. + return logger.isDebugEnabled() ? future.thenApply(log) : future; + } + + private CompletableFuture translateBrowsePathToNodeId(BrowsePath browsePath) { + List browsePaths = Collections.singletonList(browsePath); + + return translateBrowsePathsToNodeIds(browsePaths).thenApply(nodeIds -> nodeIds.get(0)); + } + + /** + * Reads the current value from an OPC UA node. + * + *

+ * See the documentation of {@link IOpcUaClient#readValue(NodeId)} for more + * information. + */ + @Override + public Object readValue(NodeId nodeId) throws OpcUaException { + try { + return readValueAsync(nodeId).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + throw makeOpcUaExceptionFromCause(e); + } + } + + /** + * Reads the current value from an OPC UA node. + * + *

+ * See the documentation of {@link IOpcUaClient#readValueAsync(NodeId)} for more + * information. + */ + @Override + public CompletableFuture readValueAsync(NodeId nodeId) { + if (nodeId == null) { + throw new IllegalArgumentException("nodeId must not be null."); + } + + logger.debug("Reading node '{}'.", nodeId); + + return getClient().thenCompose(client -> client.readValue(0, TimestampsToReturn.Neither, nodeId.getInternalId())).thenApply(dv -> { + if (dv.getStatusCode().isGood()) { + return dv.getValue(); + } else { + throw new OpcUaException("Read failed with: " + dv.getStatusCode()); + } + }).thenApply(this::unwrapVariant).exceptionally(e -> { + if (e instanceof CompletionException) { + throw makeOpcUaExceptionFromCause(e); + } else { + throw ensureOpcUaException(e); + } + }); + } + + /** + * Writes the value of an OPC UA node. + * + *

+ * See the documentation of {@link IOpcUaClient#writeValue(NodeId, Object)} for + * more information. + */ + @Override + public void writeValue(NodeId nodeId, Object value) throws OpcUaException { + try { + writeValueAsync(nodeId, value).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + throw makeOpcUaExceptionFromCause(e); + } + } + + /** + * Writes the value of an OPC UA node. + * + *

+ * See the documentation of {@link IOpcUaClient#writeValueAsync(NodeId, Object)} + * for more information. + */ + @Override + public CompletableFuture writeValueAsync(NodeId nodeId, Object value) { + if (nodeId == null) { + throw new IllegalArgumentException("nodeId must not be null."); + } + + logger.debug("Writing node '{}' with value {}.", nodeId, value); + + DataValue dv = new DataValue(wrapVariant(value)); + + return getClient().thenCompose(client -> client.writeValue(nodeId.getInternalId(), dv)).thenAccept(status -> { + if (!status.isGood()) { + throw new OpcUaException("Write failed with: " + status); + } + }).exceptionally(e -> { + if (e instanceof CompletionException) { + throw makeOpcUaExceptionFromCause(e); + } else { + throw ensureOpcUaException(e); + } + }); + } + + /** + * Invokes an OPC UA method on an object. + * + *

+ * See the documentation of + * {@link IOpcUaClient#invokeMethod(NodeId, NodeId, Object...)} for more + * information. + */ + @Override + public List invokeMethod(NodeId ownerId, NodeId methodId, Object... parameters) throws OpcUaException { + try { + return invokeMethodAsync(ownerId, methodId, parameters).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OpcUaException(e); + } catch (ExecutionException e) { + throw makeOpcUaExceptionFromCause(e); + } + } + + /** + * Invokes an OPC UA method on an object. + * + *

+ * See the documentation of + * {@link IOpcUaClient#invokeMethodAsync(NodeId, NodeId, Object...)} for more + * information. + */ + @Override + public CompletableFuture> invokeMethodAsync(NodeId ownerId, NodeId methodId, Object... parameters) { + if (ownerId == null || methodId == null) { + throw new IllegalArgumentException("ownerId and methodId must not be null."); + } + + logger.debug("Invoking method '{}' on node '{}' with arguments {}.", methodId, ownerId, parameters); + + Variant[] inputs = new Variant[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + inputs[i] = wrapVariant(parameters[i]); + } + + CallMethodRequest req = new CallMethodRequest(ownerId.getInternalId(), methodId.getInternalId(), inputs); + + return getClient().thenCompose(client -> client.call(req)).thenApply(result -> { + if (!result.getStatusCode().isGood()) { + throw new OpcUaException("Method invocation failed with: " + result.getStatusCode()); + } + return Arrays.stream(result.getOutputArguments()).map(this::unwrapVariant).collect(Collectors.toList()); + }).exceptionally(e -> { + if (e instanceof CompletionException) { + throw makeOpcUaExceptionFromCause(e); + } else { + throw ensureOpcUaException(e); + } + }); + } + + /** + * Wraps a data value in a {@link Variant}. + * + *

+ * While wrapping, value types for which equivalent types exist in Milo's type + * system are automatically converted. + * + * @param value + * The value to wrap in a Variant. + * + * @return A new Variant wrapping value. + */ + private Variant wrapVariant(Object value) { + return new Variant(mapBaSyxToMiloTypes(value)); + } + + /** + * Unwraps a data value from a {@link Variant}. + * + *

+ * While unwrapping, data values with Milo-specific types will be converted to + * their respective BaSyx equivalents. + * + * @param variant + * The Variant to unwrap. + * + * @return The raw data value contained in variant. + */ + private Object unwrapVariant(Variant variant) { + if (variant == null || variant.getValue() == null) { + return null; + } + + ExpandedNodeId typeId = variant.getDataType().orElse(null); + if (typeId == null) { + return null; + } + + return mapMiloToBaSyxTypes(variant.getValue()); + } + + /** + * Converts from OPC UA data types implemented in Milo to types used in BaSyx. + * + * @param value + * The data value coming from Milo. + * + * @return The corresponding BaSyx object. + */ + private Object mapMiloToBaSyxTypes(Object value) { + if (value instanceof DateTime) { + long millis = ((DateTime) value).getJavaTime(); + GregorianCalendar cal = new GregorianCalendar(); + cal.setTimeInMillis(millis); + return xmlDatatypeFactory.newXMLGregorianCalendar(cal); + } else if (value instanceof UByte) { + return new UnsignedByte((UByte) value); + } else if (value instanceof UShort) { + return new UnsignedShort((UShort) value); + } else if (value instanceof UInteger) { + return new UnsignedInteger((UInteger) value); + } else if (value instanceof ULong) { + return new UnsignedLong((ULong) value); + } else { + return value; + } + } + + /** + * Converts from BaSyx types to OPC UA data types implemented in Milo. + * + * @param value + * The value coming from BaSyx. + * + * @return The corresponding Milo object. + */ + private Object mapBaSyxToMiloTypes(Object value) { + if (value instanceof XMLGregorianCalendar) { + XMLGregorianCalendar v = (XMLGregorianCalendar) value; + if (v.getXMLSchemaType() != DatatypeConstants.DATETIME) { + throw new OpcUaException("The OPC UA DateTime type doesn't support incomplete date/time specifications. Illegal value: " + v); + } + Instant i = Instant.ofEpochMilli(v.toGregorianCalendar().getTimeInMillis()); + return new DateTime(i); + } else if (value instanceof UnsignedByte) { + return ((UnsignedByte) value).getInternalValue(); + } else if (value instanceof UnsignedShort) { + return ((UnsignedShort) value).getInternalValue(); + } else if (value instanceof UnsignedInteger) { + return ((UnsignedInteger) value).getInternalValue(); + } else if (value instanceof UnsignedLong) { + return ((UnsignedLong) value).getInternalValue(); + } else { + return value; + } + } + + private OpcUaException makeOpcUaExceptionFromCause(Throwable e) { + return ensureOpcUaException(e.getCause()); + } + + private OpcUaException ensureOpcUaException(Throwable e) { + return (e instanceof OpcUaException) ? (OpcUaException) e : new OpcUaException(e); + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/exception/AmbiguousBrowsePathException.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/exception/AmbiguousBrowsePathException.java new file mode 100644 index 00000000..113a4f95 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/exception/AmbiguousBrowsePathException.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.exception; + +/** + * Indicates that a browse path was used which matches for than one node on the + * server. + * + *

+ * While it is perfectly valid in OPC UA to have browse paths which match more + * than one single node, BaSyx doesn't deal well with these cases. That's why + * this exception is thrown whenever such a browse path is encountered. + */ +public final class AmbiguousBrowsePathException extends OpcUaException { + private static final long serialVersionUID = 1L; + + public AmbiguousBrowsePathException(String msg) { + super(msg); + } + + public AmbiguousBrowsePathException(Throwable cause) { + super(cause); + } + + public AmbiguousBrowsePathException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/exception/OpcUaException.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/exception/OpcUaException.java new file mode 100644 index 00000000..f06e8f7b --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/exception/OpcUaException.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.exception; + +import org.eclipse.basyx.vab.exception.provider.ProviderException; + +/** + * Generic wrapper type for exceptions from the underlying client library. + * + *

+ * User code can catch this exception type to handle all OPC UA related + * exceptions uniformly. If more fine-grained handling of different failure + * modes is required, calling code must inspect the cause through + * {@link #getCause()} and deal with exception types of the underlying library. + */ +public class OpcUaException extends ProviderException { + + private static final long serialVersionUID = 1L; + + public OpcUaException(String msg) { + super(msg); + } + + public OpcUaException(Throwable cause) { + super(cause); + } + + public OpcUaException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java index f08a4531..b34bf178 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClient.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.opcua.server; @@ -13,8 +28,13 @@ import org.eclipse.milo.opcua.sdk.client.OpcUaClient; +/** + * @deprecated As of version 1.1. Was never actually used, so no direct + * replacement available. + */ +@Deprecated public interface BaSyxOpcUaClient { - void run(OpcUaClient client, CompletableFuture future) throws Exception; + void run(OpcUaClient client, CompletableFuture future) throws Exception; } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java index 8c38c1f8..8d591b24 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/BaSyxOpcUaClientRunner.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.opcua.server; @@ -21,6 +36,8 @@ import java.util.concurrent.ExecutionException; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.eclipse.basyx.vab.protocol.opcua.connector.IOpcUaClient; +import org.eclipse.basyx.vab.protocol.opcua.connector.milo.MiloOpcUaClient; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider; @@ -42,124 +59,123 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * @deprecated As of version 1.1. Replaced by {@link IOpcUaClient} and + * {@link MiloOpcUaClient}. + */ +@Deprecated public class BaSyxOpcUaClientRunner { - private static Logger logger = LoggerFactory.getLogger(BaSyxOpcUaClientRunner.class); - - static { - // Required for SecurityPolicy.Aes256_Sha256_RsaPss - Security.addProvider(new BouncyCastleProvider()); - } - - private final CompletableFuture future = new CompletableFuture<>(); - - private OpcUaClient client; - - private String endpointUrl; - - public BaSyxOpcUaClientRunner(String endpointUrl) throws Exception { - this.endpointUrl = endpointUrl; - } - - private OpcUaClient createClient() throws Exception { - Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security"); - Files.createDirectories(securityTempDir); - if (!Files.exists(securityTempDir)) { - throw new Exception("unable to create security dir: " + securityTempDir); - } - logger.trace("security temp dir: {}", securityTempDir.toAbsolutePath()); - - KeyStoreLoaderClient loader = new KeyStoreLoaderClient().load(securityTempDir); - - SecurityPolicy securityPolicy = SecurityPolicy.None; - - List endpoints; - - try { - endpoints = DiscoveryClient.getEndpoints(endpointUrl).get(); - } catch (Throwable ex) { - // try the explicit discovery endpoint as well - String discoveryUrl = endpointUrl; - - if (!discoveryUrl.endsWith("/")) { - discoveryUrl += "/"; - } - discoveryUrl += "discovery"; - - logger.trace("Trying explicit discovery URL: {}", discoveryUrl); - endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get(); - } - - EndpointDescription endpoint = endpoints.stream() - .filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getUri())).filter(e -> true).findFirst() - .orElseThrow(() -> new Exception("no desired endpoints returned")); - - logger.trace("Using endpoint: {} [{}/{}]", endpoint.getEndpointUrl(), securityPolicy, - endpoint.getSecurityMode()); - - OpcUaClientConfig config = OpcUaClientConfig.builder() - .setApplicationName(LocalizedText.english("eclipse milo opc-ua client")) - .setApplicationUri("urn:eclipse:milo:examples:client").setCertificate(loader.getClientCertificate()) - .setKeyPair(loader.getClientKeyPair()).setEndpoint(endpoint) - .setIdentityProvider(new AnonymousProvider()).setRequestTimeout(uint(5000)).build(); - - return OpcUaClient.create(config); - } - - public void run() { - try { - client = createClient(); - - future.whenCompleteAsync((c, ex) -> { - if (ex != null) { - logger.error("Error running example: {}", ex.getMessage(), ex); - } - - try { - client.disconnect().get(); - Stack.releaseSharedResources(); - } catch (InterruptedException | ExecutionException e) { - logger.error("Error disconnecting:", e.getMessage(), e); - } - - try { - Thread.sleep(1000); - throw new RuntimeException("Could not disconnect from server '" + endpointUrl + "'"); - } catch (InterruptedException e) { - logger.error("Exception in run", e); - } - }); - client.connect().get(); - } catch (Throwable t) { - logger.error("Error getting client: {}", t.getMessage(), t); - - future.completeExceptionally(t); - - try { - Thread.sleep(1000); - throw new RuntimeException("Could not connect to server '" + endpointUrl + "'"); - } catch (InterruptedException e) { - logger.error("Exception in run", e); - } - } - } - - public CompletableFuture> read(List nodeIds) { - return client.readValues(0, TimestampsToReturn.Both, nodeIds); - } - - public CompletableFuture> write(List nodeIds, List values) { - return client.writeValues(nodeIds, values); - } - - public CompletableFuture callMethod(NodeId objectId, NodeId methodId, Variant[] inputArguments) { - List cmr = new ArrayList(); - cmr.add(new CallMethodRequest(objectId, methodId, inputArguments)); - return client.call(cmr); - } - - public CompletableFuture translate(List browsePaths) { - return client.translateBrowsePaths(browsePaths); - } + private static Logger logger = LoggerFactory.getLogger(BaSyxOpcUaClientRunner.class); + + static { + // Required for SecurityPolicy.Aes256_Sha256_RsaPss + Security.addProvider(new BouncyCastleProvider()); + } + + private final CompletableFuture future = new CompletableFuture<>(); + + private OpcUaClient client; + + private String endpointUrl; + + public BaSyxOpcUaClientRunner(String endpointUrl) throws Exception { + this.endpointUrl = endpointUrl; + } + + private OpcUaClient createClient() throws Exception { + Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security"); + Files.createDirectories(securityTempDir); + if (!Files.exists(securityTempDir)) { + throw new Exception("unable to create security dir: " + securityTempDir); + } + logger.trace("security temp dir: {}", securityTempDir.toAbsolutePath()); + + KeyStoreLoaderClient loader = new KeyStoreLoaderClient().load(securityTempDir); + + SecurityPolicy securityPolicy = SecurityPolicy.None; + + List endpoints; + + try { + endpoints = DiscoveryClient.getEndpoints(endpointUrl).get(); + } catch (Throwable ex) { + // try the explicit discovery endpoint as well + String discoveryUrl = endpointUrl; + + if (!discoveryUrl.endsWith("/")) { + discoveryUrl += "/"; + } + discoveryUrl += "discovery"; + + logger.trace("Trying explicit discovery URL: {}", discoveryUrl); + endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get(); + } + + EndpointDescription endpoint = endpoints.stream().filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getUri())).filter(e -> true).findFirst().orElseThrow(() -> new Exception("no desired endpoints returned")); + + logger.trace("Using endpoint: {} [{}/{}]", endpoint.getEndpointUrl(), securityPolicy, endpoint.getSecurityMode()); + + OpcUaClientConfig config = OpcUaClientConfig.builder().setApplicationName(LocalizedText.english("eclipse milo opc-ua client")).setApplicationUri("urn:eclipse:milo:examples:client").setCertificate(loader.getClientCertificate()) + .setKeyPair(loader.getClientKeyPair()).setEndpoint(endpoint).setIdentityProvider(new AnonymousProvider()).setRequestTimeout(uint(5000)).build(); + + return OpcUaClient.create(config); + } + + public void run() { + try { + client = createClient(); + + future.whenCompleteAsync((c, ex) -> { + if (ex != null) { + logger.error("Error running example: {}", ex.getMessage(), ex); + } + + try { + client.disconnect().get(); + Stack.releaseSharedResources(); + } catch (InterruptedException | ExecutionException e) { + logger.error("Error disconnecting:", e.getMessage(), e); + } + + try { + Thread.sleep(1000); + throw new RuntimeException("Could not disconnect from server '" + endpointUrl + "'"); + } catch (InterruptedException e) { + logger.error("Exception in run", e); + } + }); + client.connect().get(); + } catch (Throwable t) { + logger.error("Error getting client: {}", t.getMessage(), t); + + future.completeExceptionally(t); + + try { + Thread.sleep(1000); + throw new RuntimeException("Could not connect to server '" + endpointUrl + "'"); + } catch (InterruptedException e) { + logger.error("Exception in run", e); + } + } + } + + public CompletableFuture> read(List nodeIds) { + return client.readValues(0, TimestampsToReturn.Both, nodeIds); + } + + public CompletableFuture> write(List nodeIds, List values) { + return client.writeValues(nodeIds, values); + } + + public CompletableFuture callMethod(NodeId objectId, NodeId methodId, Variant[] inputArguments) { + List cmr = new ArrayList(); + cmr.add(new CallMethodRequest(objectId, methodId, inputArguments)); + return client.call(cmr); + } + + public CompletableFuture translate(List browsePaths) { + return client.translateBrowsePaths(browsePaths); + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java index 535c9942..d32f6a5a 100644 --- a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/server/KeyStoreLoaderClient.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.protocol.opcua.server; @@ -21,80 +36,88 @@ import java.security.cert.X509Certificate; import java.util.regex.Pattern; +import org.eclipse.basyx.vab.protocol.opcua.CertificateHelper; +import org.eclipse.basyx.vab.protocol.opcua.connector.ClientConfiguration; import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil; import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder; import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * @deprecated As of version 1.1. No full replacement planned.
+ * A limited replacement is available in {@link CertificateHelper} + * which creates self-signed certificates in memory to be passed to + * {@link ClientConfiguration#setKeyPairAndCertificate(KeyPair, X509Certificate)}. + * But it is the user's responsibility to persist these in a + * {@link KeyStore}, if they wish. + * + */ +@Deprecated public class KeyStoreLoaderClient { - private static final Pattern IP_ADDR_PATTERN = Pattern - .compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); + private static final Pattern IP_ADDR_PATTERN = Pattern.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); - private static final String CLIENT_ALIAS = "client-ai"; - private static final char[] PASSWORD = "password".toCharArray(); + private static final String CLIENT_ALIAS = "client-ai"; + private static final char[] PASSWORD = "password".toCharArray(); - private final Logger logger = LoggerFactory.getLogger(getClass()); + private final Logger logger = LoggerFactory.getLogger(getClass()); - private X509Certificate clientCertificate; - private KeyPair clientKeyPair; + private X509Certificate clientCertificate; + private KeyPair clientKeyPair; - KeyStoreLoaderClient load(Path baseDir) throws Exception { - KeyStore keyStore = KeyStore.getInstance("PKCS12"); + KeyStoreLoaderClient load(Path baseDir) throws Exception { + KeyStore keyStore = KeyStore.getInstance("PKCS12"); - Path serverKeyStore = baseDir.resolve("example-client.pfx"); + Path serverKeyStore = baseDir.resolve("example-client.pfx"); - logger.info("Loading KeyStore at {}", serverKeyStore); + logger.info("Loading KeyStore at {}", serverKeyStore); - if (!Files.exists(serverKeyStore)) { - keyStore.load(null, PASSWORD); + if (!Files.exists(serverKeyStore)) { + keyStore.load(null, PASSWORD); - KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048); + KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048); - SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair) - .setCommonName("Eclipse Milo Example Client").setOrganization("digitalpetri") - .setOrganizationalUnit("dev").setLocalityName("Folsom").setStateName("CA").setCountryCode("US") - .setApplicationUri("urn:eclipse:milo:examples:client").addDnsName("localhost") - .addIpAddress("127.0.0.1"); + SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair).setCommonName("Eclipse Milo Example Client").setOrganization("digitalpetri").setOrganizationalUnit("dev").setLocalityName("Folsom") + .setStateName("CA").setCountryCode("US").setApplicationUri("urn:eclipse:milo:examples:client").addDnsName("localhost").addIpAddress("127.0.0.1"); - // Get as many hostnames and IP addresses as we can listed in the certificate. - for (String hostname : HostnameUtil.getHostnames("0.0.0.0")) { - if (IP_ADDR_PATTERN.matcher(hostname).matches()) { - builder.addIpAddress(hostname); - } else { - builder.addDnsName(hostname); - } - } + // Get as many hostnames and IP addresses as we can listed in the certificate. + for (String hostname : HostnameUtil.getHostnames("0.0.0.0")) { + if (IP_ADDR_PATTERN.matcher(hostname).matches()) { + builder.addIpAddress(hostname); + } else { + builder.addDnsName(hostname); + } + } - X509Certificate certificate = builder.build(); + X509Certificate certificate = builder.build(); - keyStore.setKeyEntry(CLIENT_ALIAS, keyPair.getPrivate(), PASSWORD, new X509Certificate[] { certificate }); - try (OutputStream out = Files.newOutputStream(serverKeyStore)) { - keyStore.store(out, PASSWORD); - } - } else { - try (InputStream in = Files.newInputStream(serverKeyStore)) { - keyStore.load(in, PASSWORD); - } - } + keyStore.setKeyEntry(CLIENT_ALIAS, keyPair.getPrivate(), PASSWORD, new X509Certificate[] { certificate }); + try (OutputStream out = Files.newOutputStream(serverKeyStore)) { + keyStore.store(out, PASSWORD); + } + } else { + try (InputStream in = Files.newInputStream(serverKeyStore)) { + keyStore.load(in, PASSWORD); + } + } - Key serverPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD); - if (serverPrivateKey instanceof PrivateKey) { - clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS); - PublicKey serverPublicKey = clientCertificate.getPublicKey(); - clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey); - } + Key serverPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD); + if (serverPrivateKey instanceof PrivateKey) { + clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS); + PublicKey serverPublicKey = clientCertificate.getPublicKey(); + clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey); + } - return this; - } + return this; + } - X509Certificate getClientCertificate() { - return clientCertificate; - } + X509Certificate getClientCertificate() { + return clientCertificate; + } - KeyPair getClientKeyPair() { - return clientKeyPair; - } + KeyPair getClientKeyPair() { + return clientKeyPair; + } } diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/MessageSecurityMode.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/MessageSecurityMode.java new file mode 100644 index 00000000..d2df683f --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/MessageSecurityMode.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +/** + * Available message security modes for OPC UA connections. + */ +public enum MessageSecurityMode { + None, Sign, SignAndEncrypt +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/NodeId.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/NodeId.java new file mode 100644 index 00000000..bbeed613 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/NodeId.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.basyx.vab.protocol.opcua.exception.OpcUaException; +import org.eclipse.milo.opcua.stack.core.UaRuntimeException; +import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString; +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; + +/** + * A node id unique identifies a node within an OPC UA server's address space. + */ +public final class NodeId { + private final org.eclipse.milo.opcua.stack.core.types.builtin.NodeId internalId; + private String cachedStringRepresentation; + + /** + * Creates a numeric node id with the given namespace. + * + *

+ * Numeric node ids technically use an unsigned 32 bit integer type. Since that + * type doesn't exist in Java, this method accepts a long, instead. The + * identifier is, however, not allowed to be negative. + * + * @param namespaceIndex + * The index of the node's namespace. + * @param identifier + * The numeric id. Must be greater or equal 0. + * + * @throws IllegalArgumentException + * if the identifier is negative. + */ + public NodeId(int namespaceIndex, long identifier) { + if (identifier < 0) { + throw new IllegalArgumentException("Numeric identifier must not be negative."); + } + + internalId = new org.eclipse.milo.opcua.stack.core.types.builtin.NodeId(namespaceIndex, UInteger.valueOf(identifier)); + } + + /** + * Creates a string node id with the given namespace. + * + * @param namespaceIndex + * The index of the node's namespace. + * @param identifier + * The string id. Maximum length is 4096 characters. + * + * @throws IllegalArgumentException + * if identifier is null or exceeds the maximum length. + */ + public NodeId(int namespaceIndex, String identifier) { + Objects.requireNonNull(identifier); + + if (identifier.length() > 4096) { + throw new IllegalArgumentException("String identifier must not be longer than 4096 characters."); + } + + internalId = new org.eclipse.milo.opcua.stack.core.types.builtin.NodeId(namespaceIndex, identifier); + } + + /** + * Creates a GUID node id with the given namespace. + * + * @param namespaceIndex + * The index of the node's namespace. + * @param identifier + * The GUID id. + * + * @throws IllegalArgumentException + * if identifier is null. + */ + public NodeId(int namespaceIndex, UUID identifier) { + Objects.requireNonNull(identifier); + + internalId = new org.eclipse.milo.opcua.stack.core.types.builtin.NodeId(namespaceIndex, identifier); + } + + /** + * Creates a ByteString node id with the given namespace. + * + *

+ * ByteString is a special OPC UA type that loosely corresponds to a Java array + * of bytes. + * + * @param namespaceIndex + * The index of the node's namespace. + * @param identifier + * The ByteString id. Maximum length is 4096 bytes. + * + * @throws IllegalArgumentException + * if identifier is null or exceeds the maximum length. + */ + public NodeId(int namespaceIndex, byte[] identifier) { + Objects.requireNonNull(identifier); + + if (identifier.length > 4096) { + throw new IllegalArgumentException("ByteString identifier must not be longer than 4096 bytes."); + } + + internalId = new org.eclipse.milo.opcua.stack.core.types.builtin.NodeId(namespaceIndex, ByteString.of(identifier)); + } + + public NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId miloId) { + internalId = miloId; + } + + /** + * Creates a node id from a string representation in the standard string format + * (e.g. ns=1;i=1234). + * + *

+ * For a variant of this method which doesn't throw exceptions, see + * {@link #tryParse(String)}. + * + * @param s + * String representation of the NodeId. + * + * @return The created node id. + * + * @throws OpcUaException + * if the string doesn't represent a valid node id. + */ + public static NodeId parse(String s) { + try { + org.eclipse.milo.opcua.stack.core.types.builtin.NodeId miloId; + miloId = org.eclipse.milo.opcua.stack.core.types.builtin.NodeId.parse(s); + return new NodeId(miloId); + } catch (UaRuntimeException e) { + throw new OpcUaException(e); + } + } + + /** + * Creates a node id from a string representation in the standard string format + * (e.g. ns=1;i=1234). + * + *

+ * This method is similar to {@link #parse(String)} but returns + * null instead of throwing an exception if the given string + * doesn't represent a node id. + * + * @param s + * String representation of the NodeId. + * + * @return The created node id or null if s doesn't represent a + * node id. + */ + public static NodeId tryParse(String s) { + org.eclipse.milo.opcua.stack.core.types.builtin.NodeId miloId; + miloId = org.eclipse.milo.opcua.stack.core.types.builtin.NodeId.parseOrNull(s); + return (miloId != null) ? new NodeId(miloId) : null; + } + + /** + * Gets the wrapped Milo NodeId. + * + * @return The wrapped + * {@link org.eclipse.milo.opcua.stack.core.types.builtin.NodeId}. + */ + public org.eclipse.milo.opcua.stack.core.types.builtin.NodeId getInternalId() { + return internalId; + } + + /** + * Gets the namespace index of this node id. + * + * @return The namespace part of this node id. + */ + public int getNamespaceIndex() { + return internalId.getNamespaceIndex().intValue(); + } + + /** + * Gets the identifier of this node id. + * + *

+ * The returned type depends on the type of the node id. + *

    + *
  • Numeric id: {@link Long} + *
  • String id: {@link String} + *
  • GUID id: {@link UUID} + *
  • Opaque id: byte[] + *
+ * + * @return The identifier part of the node id. + */ + public Object getIdentifier() { + switch (internalId.getType()) { + case Opaque: + return ((ByteString) internalId.getIdentifier()).bytes(); + case Numeric: + return ((UInteger) internalId.getIdentifier()).longValue(); + default: + return internalId.getIdentifier(); + } + } + + /** + * Returns a machine-parseable string representation of this node id. + * + *

+ * The returned string is formatted according to the machine-parseable + * formatting rules outlined in part + * 6 of the specification. + * + *

+ * During the first call to this method the string is initially generated and + * cached. Subsequent calls come at no additional computation cost. + * + * @return A machine-parseable string representation of the node id. + */ + @Override + public String toString() { + if (cachedStringRepresentation == null) { + cachedStringRepresentation = internalId.toParseableString(); + } + + return cachedStringRepresentation; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof NodeId)) { + return false; + } + + NodeId other = (NodeId) obj; + return internalId.equals(other.internalId); + } + + @Override + public int hashCode() { + return internalId.hashCode(); + } +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/SecurityPolicy.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/SecurityPolicy.java new file mode 100644 index 00000000..b30cdb7a --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/SecurityPolicy.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +/** + * Available security policies for OPC UA connections. + */ +public enum SecurityPolicy { + None, Basic128Rsa15, Basic256, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss +} diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedByte.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedByte.java new file mode 100644 index 00000000..dc14d7bf --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedByte.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +import java.math.BigInteger; + +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte; + +/** An unsigned 8-bit integer, matching the UInt8 type from OPC UA. */ +public final class UnsignedByte { + /** The lowest possible value of an unsigned 8-bit integer. */ + public static final short MIN_VALUE = UByte.MIN_VALUE; + /** The highest possible value of an unsigned 8-bit integer. */ + public static final short MAX_VALUE = UByte.MAX_VALUE; + /** + * A constant instance holding the lowest possible value of an unsigned 8-bit + * integer. + */ + public static final UnsignedByte MIN = new UnsignedByte(UByte.MIN); + /** + * A constant instance holding the highest possible value of an unsigned 8-bit + * integer. + */ + public static final UnsignedByte MAX = new UnsignedByte(UByte.MAX); + + private final UByte value; + + /** + * Creates a new instance from the given byte. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte(byte value) throws NumberFormatException { + this.value = UByte.valueOf(value); + } + + /** + * Creates a new instance from the given short integer. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte(short value) throws NumberFormatException { + this.value = UByte.valueOf(value); + } + + /** + * Creates a new instance from the given integer. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte(int value) throws NumberFormatException { + this.value = UByte.valueOf(value); + } + + /** + * Creates a new instance by parsing the given string. + * + * @param value + * A decimal string representation of the value. + * + * @throws NumberFormatException + * if the string doesn't contain a decimal integer or the value is + * outside the allowed range of an unsigned 64 bit integer. + */ + public UnsignedByte(String value) throws NumberFormatException { + this.value = UByte.valueOf(value); + } + + /** + * Creates a new instance with the given internal value. Client code should + * normally not need to use this. + * + * @param value + * The internal value. + */ + public UnsignedByte(UByte value) { + this.value = value; + } + + /** + * Gets the internal representation of this value. Client code should not + * normally use this. + * + * @return The internal representation of this value. + */ + public UByte getInternalValue() { + return value; + } + + /** + * Adds another {@link UnsignedByte} to this one. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte add(UnsignedByte other) throws NumberFormatException { + return new UnsignedByte(value.add(other.toByte())); + } + + /** + * Adds a byte to this {@link UnsignedByte}. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte add(short other) throws NumberFormatException { + return new UnsignedByte(value.add(other)); + } + + /** + * Subtracts another {@link UnsignedByte} from this one. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte subtract(UnsignedByte other) throws NumberFormatException { + return new UnsignedByte(value.subtract(other.toByte())); + } + + /** + * Subtracts a byte from this {@link UnsignedByte}. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedByte subtract(short other) throws NumberFormatException { + return new UnsignedByte(value.subtract(other)); + } + + /** + * Gets a byte with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A byte with this object's value. + */ + public short toByte() { + return value.byteValue(); + } + + /** + * Gets a short integer with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A short integer with this object's value. + */ + public short toShort() { + return value.shortValue(); + } + + /** + * Gets an integer with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return An integer with this object's value. + */ + public int toInt() { + return value.intValue(); + } + + /** + * Gets a long with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A long with this object's value. + */ + public long toLong() { + return value.longValue(); + } + + /** + * Gets a {@link BigInteger} with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A {@link BigInteger} with this object's value. + */ + public BigInteger toBigInteger() { + return value.toBigInteger(); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedInteger.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedInteger.java new file mode 100644 index 00000000..420ca30c --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedInteger.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +import java.math.BigInteger; + +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; + +/** An unsigned 32-bit integer, matching the UInt32 type from OPC UA. */ +public final class UnsignedInteger { + /** The lowest possible value of an unsigned 32-bit integer. */ + public static final long MIN_VALUE = UInteger.MIN_VALUE; + + /** The highest possible value of an unsigned 32-bit integer. */ + public static final long MAX_VALUE = UInteger.MAX_VALUE; + + /** + * A constant instance holding the lowest possible value of an unsigned 32-bit + * integer. + */ + public static final UnsignedInteger MIN = new UnsignedInteger(UInteger.MIN); + + /** + * A constant instance holding the highest possible value of an unsigned 32-bit + * integer. + */ + public static final UnsignedInteger MAX = new UnsignedInteger(UInteger.MAX); + + private final UInteger value; + + /** + * Creates a new instance from the given int value. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedInteger(int value) throws NumberFormatException { + this.value = UInteger.valueOf(value); + } + + /** + * Creates a new instance from the given long value. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedInteger(long value) throws NumberFormatException { + this.value = UInteger.valueOf(value); + } + + /** + * Creates a new instance by parsing the given string. + * + * @param value + * A decimal string representation of the value. + * + * @throws NumberFormatException + * if the string doesn't contain a decimal integer or the value is + * outside the allowed range of {@link #MIN_VALUE} to + * {@link #MAX_VALUE}. + */ + public UnsignedInteger(String value) throws NumberFormatException { + this.value = UInteger.valueOf(value); + } + + /** + * Creates a new instance with the given internal value. Client code should + * normally not need to use this. + * + * @param value + * The internal value. + */ + public UnsignedInteger(UInteger value) { + this.value = value; + } + + /** + * Gets the internal representation of this value. Client code should not + * normally use this. + * + * @return The internal representation of this value. + */ + public UInteger getInternalValue() { + return value; + } + + /** + * Adds another {@link UnsignedInteger} to this one. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedInteger add(UnsignedInteger other) throws NumberFormatException { + return new UnsignedInteger(value.add(other.toInt())); + } + + /** + * Adds an integer to this {@link UnsignedInteger}. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedInteger add(int other) throws NumberFormatException { + return new UnsignedInteger(value.add(other)); + } + + /** + * Subtracts another {@link UnsignedInteger} from this one. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedInteger subtract(UnsignedInteger other) throws NumberFormatException { + return new UnsignedInteger(value.subtract(other.toInt())); + } + + /** + * Subtracts an integer from this {@link UnsignedInteger}. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedInteger subtract(int other) throws NumberFormatException { + return new UnsignedInteger(value.subtract(other)); + } + + /** + * Gets an integer with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return An integer with this object's value. + */ + public int toInt() { + return value.intValue(); + } + + /** + * Gets a long with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A long with this object's value. + */ + public long toLong() { + return value.longValue(); + } + + /** + * Gets a {@link BigInteger} with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A {@link BigInteger} with this object's value. + */ + public BigInteger toBigInteger() { + return value.toBigInteger(); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedLong.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedLong.java new file mode 100644 index 00000000..2350db56 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedLong.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +import java.math.BigInteger; + +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.ULong; + +/** An unsigned 64-bit integer, matching the UInt64 type from OPC UA. */ +public final class UnsignedLong { + /** The lowest possible value of an unsigned 64-bit integer. */ + public static final BigInteger MIN_VALUE = ULong.MIN_VALUE; + + /** The highest possible value of an unsigned 64-bit integer. */ + public static final BigInteger MAX_VALUE = ULong.MAX_VALUE; + + /** + * A constant instance holding the lowest possible value of an unsigned 64-bit + * integer. + */ + public static final UnsignedLong MIN = new UnsignedLong(ULong.MIN); + + /** + * A constant instance holding the highest possible value of an unsigned 64-bit + * integer. + */ + public static final UnsignedLong MAX = new UnsignedLong(ULong.MAX); + + private final ULong value; + + /** + * Creates a new instance from the given long value. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedLong(long value) throws NumberFormatException { + this.value = ULong.valueOf(value); + } + + /** + * Creates a new instance from the given {@link BigInteger}. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedLong(BigInteger value) throws NumberFormatException { + this.value = ULong.valueOf(value); + } + + /** + * Creates a new instance by parsing the given string. + * + * @param value + * A decimal string representation of the value. + * + * @throws NumberFormatException + * if the string doesn't contain a decimal integer or the value is + * outside the allowed range of an unsigned 64 bit integer. + */ + public UnsignedLong(String value) throws NumberFormatException { + this.value = ULong.valueOf(value); + } + + /** + * Creates a new instance with the given internal value. Client code should + * normally not need to use this. + * + * @param value + * The internal value. + */ + public UnsignedLong(ULong value) { + this.value = value; + } + + /** + * Gets the internal representation of this value. Client code should not + * normally use this. + * + * @return The internal representation of this value. + */ + public ULong getInternalValue() { + return value; + } + + /** + * Adds another {@link UnsignedLong} to this one. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedLong add(UnsignedLong other) throws NumberFormatException { + return new UnsignedLong(value.add(other.toLong())); + } + + /** + * Adds a long integer to this {@link UnsignedLong}. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedLong add(long other) throws NumberFormatException { + return new UnsignedLong(value.add(other)); + } + + /** + * Subtracts another {@link UnsignedLong} from this one. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedLong subtract(UnsignedLong other) throws NumberFormatException { + return new UnsignedLong(value.subtract(other.toLong())); + } + + /** + * Subtracts a long integer from this {@link UnsignedLong}. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedLong subtract(long other) throws NumberFormatException { + return new UnsignedLong(value.subtract(other)); + } + + /** + * Gets a long with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A long with this object's value. + */ + public long toLong() { + return value.longValue(); + } + + /** + * Gets a {@link BigInteger} with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A {@link BigInteger} with this object's value. + */ + public BigInteger toBigInteger() { + return value.toBigInteger(); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedShort.java b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedShort.java new file mode 100644 index 00000000..52098aa9 --- /dev/null +++ b/src/main/java/org/eclipse/basyx/vab/protocol/opcua/types/UnsignedShort.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.vab.protocol.opcua.types; + +import java.math.BigInteger; + +import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort; + +/** An unsigned 16-bit integer, matching the UInt16 type from OPC UA. */ +public final class UnsignedShort { + /** The lowest possible value of an unsigned 16-bit integer. */ + public static final int MIN_VALUE = UShort.MIN_VALUE; + + /** The highest possible value of an unsigned 16-bit integer. */ + public static final int MAX_VALUE = UShort.MAX_VALUE; + + /** + * A constant instance holding the lowest possible value of an unsigned 16-bit + * integer. + */ + public static final UnsignedShort MIN = new UnsignedShort(UShort.MIN); + + /** + * A constant instance holding the highest possible value of an unsigned 16-bit + * integer. + */ + public static final UnsignedShort MAX = new UnsignedShort(UShort.MAX); + + private final UShort value; + + /** + * Creates a new instance from the given short integer. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedShort(short value) throws NumberFormatException { + this.value = UShort.valueOf(value); + } + + /** + * Creates a new instance from the given integer. + * + * @param value + * The value. + * + * @throws NumberFormatException + * if the value is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedShort(int value) throws NumberFormatException { + this.value = UShort.valueOf(value); + } + + /** + * Creates a new instance by parsing the given string. + * + * @param value + * A decimal string representation of the value. + * + * @throws NumberFormatException + * if the string doesn't contain a decimal integer or the value is + * outside the allowed range of an unsigned 64 bit integer. + */ + public UnsignedShort(String value) throws NumberFormatException { + this.value = UShort.valueOf(value); + } + + /** + * Creates a new instance with the given internal value. Client code should + * normally not need to use this. + * + * @param value + * The internal value. + */ + public UnsignedShort(UShort value) { + this.value = value; + } + + /** + * Gets the internal representation of this value. Client code should not + * normally use this. + * + * @return The internal representation of this value. + */ + public UShort getInternalValue() { + return value; + } + + /** + * Adds another {@link UnsignedShort} to this one. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedShort add(UnsignedShort other) throws NumberFormatException { + return new UnsignedShort(value.add(other.toShort())); + } + + /** + * Adds a short integer to this {@link UnsignedShort}. + * + * @param other + * The value to add. + * + * @return A new instance holding the sum of this one and other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedShort add(short other) throws NumberFormatException { + return new UnsignedShort(value.add(other)); + } + + /** + * Subtracts another {@link UnsignedShort} from this one. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedShort subtract(UnsignedShort other) throws NumberFormatException { + return new UnsignedShort(value.subtract(other.toShort())); + } + + /** + * Subtracts a short integer from this {@link UnsignedShort}. + * + * @param other + * The value to subtract. + * + * @return A new instance holding the difference between this one and + * other. + * + * @throws NumberFormatException + * if the result is outside the allowed range of {@link #MIN_VALUE} + * to {@link #MAX_VALUE}. + */ + public UnsignedShort subtract(short other) throws NumberFormatException { + return new UnsignedShort(value.subtract(other)); + } + + /** + * Gets a short integer with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A short integer with this object's value. + */ + public short toShort() { + return value.shortValue(); + } + + /** + * Gets an integer with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return An integer with this object's value. + */ + public int toInt() { + return value.intValue(); + } + + /** + * Gets a long with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A long with this object's value. + */ + public long toLong() { + return value.longValue(); + } + + /** + * Gets a {@link BigInteger} with this object's value. + * + *

+ * The returned value is signed. Calling code needs to take care to stick to + * unsigned semantics when dealing with it. + * + * @return A {@link BigInteger} with this object's value. + */ + public BigInteger toBigInteger() { + return value.toBigInteger(); + } +} \ No newline at end of file diff --git a/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java b/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java index dccdfd0b..3db7fe14 100644 --- a/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java +++ b/src/main/java/org/eclipse/basyx/vab/registry/api/IVABRegistryService.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.registry.api; @@ -17,18 +32,15 @@ */ public interface IVABRegistryService { - /** * Add a mapping to directory */ public IVABRegistryService addMapping(String key, String value); - /** * Remove a mapping from directory */ public void removeMapping(String key); - /** * Lookup method maps key "id" to value diff --git a/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java b/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java index 08bc30e2..1fef61dc 100644 --- a/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java +++ b/src/main/java/org/eclipse/basyx/vab/registry/memory/VABInMemoryRegistry.java @@ -1,22 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.registry.memory; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.registry.api.IVABRegistryService; - - /** * Implement a in memory directory * @@ -25,39 +38,32 @@ */ public class VABInMemoryRegistry implements IVABRegistryService { - /** * Map that stores key/value mappings */ - protected Map keyToValue = new HashMap<>(); - - - - + protected Map keyToValue = new LinkedHashMap<>(); + /** * Default constructor */ public VABInMemoryRegistry() { // Do nothing } - - + /** * Constructor that accepts initial entries */ public VABInMemoryRegistry(Map addedValues) { keyToValue.putAll(addedValues); } - - - + /** * Add a mapping to directory */ @Override public IVABRegistryService addMapping(String key, String value) { keyToValue.put(key, value); - + // Return 'this' instance return this; } @@ -68,7 +74,7 @@ public IVABRegistryService addMapping(String key, String value) { public void addMappings(Map mappings) { keyToValue.putAll(mappings); } - + /** * Remove a mapping from directory */ @@ -76,13 +82,13 @@ public void addMappings(Map mappings) { public void removeMapping(String key) { keyToValue.remove(key); } - + /** * Lookup method */ @Override public String lookup(String id) { - if(keyToValue.containsKey(id)) { + if (keyToValue.containsKey(id)) { return (String) keyToValue.get(id); } else { throw new ResourceNotFoundException("No entry exists for key " + id); diff --git a/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java b/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java index 16cdb08e..ddbde512 100644 --- a/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java +++ b/src/main/java/org/eclipse/basyx/vab/registry/proxy/VABRegistryProxy.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.registry.proxy; @@ -14,6 +29,7 @@ import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector; +import org.eclipse.basyx.vab.protocol.https.HTTPSConnector; import org.eclipse.basyx.vab.registry.api.IVABRegistryService; public class VABRegistryProxy implements IVABRegistryService { @@ -24,17 +40,28 @@ public class VABRegistryProxy implements IVABRegistryService { /** * Constructor for a generic VAB directory proxy based on a HTTP connection - * + * * @param directoryUrl * The endpoint of the registry with a HTTP-REST interface */ public VABRegistryProxy(String directoryUrl) { - this(new VABElementProxy("", new JSONConnector(new HTTPConnector(directoryUrl)))); + this(getJSONConnectorWithProtocol(directoryUrl)); } - + + protected static boolean isHTTPSUrl(String url) { + return url.toLowerCase().startsWith("https"); + } + + private static VABElementProxy getJSONConnectorWithProtocol(String directoryUrl) { + if (isHTTPSUrl(directoryUrl)) { + return new VABElementProxy("", new JSONConnector(new HTTPSConnector(directoryUrl))); + } + return new VABElementProxy("", new JSONConnector(new HTTPConnector(directoryUrl))); + } + /** * Constructor for a generic VAB directory based on the registry model provider - * + * * @param provider * A model provider for the actual registry */ @@ -65,7 +92,7 @@ public void removeMapping(String key) { @Override public String lookup(String id) { Object response = provider.getValue(id); - + if (response instanceof String) { return (String) response; } else { diff --git a/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java b/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java index 15405700..f15276a4 100644 --- a/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/registry/restapi/VABRegistryModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.registry.restapi; diff --git a/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java b/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java index 5e08d68c..30f554a2 100644 --- a/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java +++ b/src/main/java/org/eclipse/basyx/vab/service/api/BaSyxService.java @@ -1,16 +1,29 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.service.api; - - /** * Runnable BaSyx service * @@ -19,37 +32,31 @@ */ public interface BaSyxService { - /** * Start the runnable */ public void start(); - - + /** * Stop the runnable */ public void stop(); - - + /** * Wait for end of runnable */ - public void waitFor(); - - + public void waitFor(); + /** * Change the runnable name */ public BaSyxService setName(String newName); - - + /** * Get runnable name */ public String getName(); - - + /** * Indicate if this service has ended */ diff --git a/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java b/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java index 0e3c2fdb..f03072c1 100644 --- a/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java +++ b/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyer.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.support; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -25,10 +40,10 @@ * */ public class TypeDestroyer { - + /** * Removes type information of all objects within the map, i.e. every subclass - * of HashMap is reduced to HashMap + * of LinkedHashMap is reduced to LinkedHashMap * * @param map * @return @@ -37,10 +52,10 @@ public class TypeDestroyer { public static Map destroyType(Map map) { return (Map) handle(map); } - + @SuppressWarnings("unchecked") public static Object handle(Object o) { - if(o instanceof Map) { + if (o instanceof Map) { return handleMap((Map) o); } else if (o instanceof Set) { return handleSet((Set) o); @@ -50,7 +65,7 @@ public static Object handle(Object o) { return o; } } - + private static List handleSet(Set set) { List ret = new ArrayList<>(); for (Object o : set) { @@ -68,7 +83,7 @@ private static List handleList(List list) { } private static Map handleMap(Map map) { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); for (Entry entry : map.entrySet()) { ret.put(entry.getKey(), handle(entry.getValue())); } diff --git a/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java b/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java index aacab264..16265c22 100644 --- a/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java +++ b/src/main/java/org/eclipse/basyx/vab/support/TypeDestroyingProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.vab.support; @@ -22,11 +37,11 @@ public class TypeDestroyingProvider implements IModelProvider { private IModelProvider provider; - + public TypeDestroyingProvider(IModelProvider provider) { this.provider = provider; } - + @Override public Object getValue(String path) throws ProviderException { return TypeDestroyer.handle(provider.getValue(path)); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java index db54503d..68b9b5fb 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/AASAggregatorSuite.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.aggregator; @@ -16,20 +31,25 @@ import java.util.Collection; import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager; import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; - /** * Testsuite for implementations of the IAASAggregator interface * @@ -45,119 +65,155 @@ public abstract class AASAggregatorSuite { private static final LangStrings description1 = new LangStrings("en", "This is test AAS 1"); private static final String aas1Category = "TestCategory1"; private static final String aas1AltCategory = "OtherTestCategory1"; - + protected AssetAdministrationShell aas2; private static final String aas2Id = "aas2"; private static final LangStrings description2 = new LangStrings("en", "This is test AAS 2"); private static final String aas2Category = "TestCategory2"; - + // initializing dummy test data @Before public void initAASDummies() { aas1 = new AssetAdministrationShell(aas1Id, new Identifier(IdentifierType.CUSTOM, aas1Id), new Asset("asset1IdShort", new Identifier(IdentifierType.CUSTOM, "asset1"), AssetKind.INSTANCE)); aas1.setDescription(description1); aas1.setCategory(aas1Category); - + aas2 = new AssetAdministrationShell(aas2Id, new Identifier(IdentifierType.CUSTOM, aas2Id), new Asset("asset2IdShort", new Identifier(IdentifierType.CUSTOM, "asset2"), AssetKind.INSTANCE)); aas2.setDescription(description2); aas2.setCategory(aas2Category); } - + protected abstract IAASAggregator getAggregator(); - + @Before public void clearAASAggregator() { IAASAggregator aggregator = getAggregator(); aggregator.getAASList().stream().map(a -> a.getIdentification()).forEach(id -> aggregator.deleteAAS(id)); } - + @Test public void testCreateAndGetAAS() { IAASAggregator aggregator = getAggregator(); - - //create a new AAS + + // create a new AAS aggregator.createAAS(aas1); - - //get and check the created AAS + + // get and check the created AAS IAssetAdministrationShell retrieved = aggregator.getAAS(aas1.getIdentification()); checkAAS1(retrieved); } - + @Test public void testGetAASList() throws Exception { IAASAggregator aggregator = getAggregator(); - + // Create two AASs aggregator.createAAS(aas1); aggregator.createAAS(aas2); - + // get the collection of all AASs Collection coll = aggregator.getAASList(); assertEquals(2, coll.size()); - + // check the AAS collection for (IAssetAdministrationShell aas : coll) { - if(aas.getIdShort().equals(aas1Id)) { + if (aas.getIdShort().equals(aas1Id)) { checkAAS1(aas); - } else if(aas.getIdShort().equals(aas2Id)) { + } else if (aas.getIdShort().equals(aas2Id)) { checkAAS2(aas); } else { fail(); } } } - + @Test public void testUpdate() throws Exception { IAASAggregator aggregator = getAggregator(); - + + ModelUrn aasUrn = new ModelUrn(aas1Id); + // Create a new AAS aggregator.createAAS(aas1); - + // Get and check the unchanged AAS - checkAAS1(aggregator.getAAS(new ModelUrn(aas1Id))); + checkAAS1(aggregator.getAAS(aasUrn)); // Change category of AAS locally aas1.setCategory(aas1AltCategory); - + // Update the changed AAS aggregator.updateAAS(aas1); - + // Get the updated AAS and check its category - IAssetAdministrationShell aas = aggregator.getAAS(new ModelUrn(aas1Id)); + IAssetAdministrationShell aas = aggregator.getAAS(aasUrn); assertEquals(aas1AltCategory, aas.getCategory()); } - + + @Test + public void submodelReferencesPresentAfterUpdate() { + IAASAggregator aggregator = getAggregator(); + + ModelUrn aasUrn = new ModelUrn(aas1Id); + + ConnectedAssetAdministrationShellManager manager = createConnectedAASManager(aggregator); + manager.createAAS(aas1, ""); + + Submodel submodel = createSubmodel("testSm", "testSmIdentifier"); + manager.createSubmodel(aasUrn, submodel); + + aggregator.updateAAS(aas1); + + assertEquals(submodel.getIdShort(), manager.retrieveSubmodel(aasUrn, submodel.getIdentification()).getIdShort()); + } + + private Submodel createSubmodel(String idShort, String customId) { + String submodelId = idShort; + Identifier submodelIdentifier = new Identifier(IdentifierType.CUSTOM, customId); + Submodel submodel = new Submodel(submodelId, submodelIdentifier); + return submodel; + } + + private ConnectedAssetAdministrationShellManager createConnectedAASManager(IAASAggregator aggregator) { + return new ConnectedAssetAdministrationShellManager(new InMemoryRegistry(), new IConnectorFactory() { + + @Override + public IModelProvider getConnector(String addr) { + return new AASAggregatorProvider(aggregator); + } + }); + } + @Test public void testDelete() throws Exception { IAASAggregator aggregator = getAggregator(); - + // Create two new AASs aggregator.createAAS(aas1); aggregator.createAAS(aas2); - + // Get AAS collection and check, that both are present Collection coll = aggregator.getAASList(); assertEquals(2, coll.size()); - + // Delete one of the AASs aggregator.deleteAAS(new ModelUrn(aas1Id)); - + // Get AAS collection and check, that one of them is deleted coll = aggregator.getAASList(); assertEquals(1, coll.size()); - + for (IAssetAdministrationShell aas : coll) { - if(aas.getIdShort().equals(aas1Id)) { //aas1 should be deleted + if (aas.getIdShort().equals(aas1Id)) { // aas1 should be deleted fail(); - } else if(aas.getIdShort().equals(aas2Id)) { + } else if (aas.getIdShort().equals(aas2Id)) { checkAAS2(aas); } else { fail(); } } } - + @Test(expected = ResourceNotFoundException.class) public void deleteNotExistingAAS() { getAggregator().getAAS(new Identifier(IdentifierType.CUSTOM, "IDontExist")); @@ -186,21 +242,21 @@ public void deleteExistingAAS() { private void checkAAS1(Object o) { assertTrue(o instanceof IAssetAdministrationShell); IAssetAdministrationShell aas = (IAssetAdministrationShell) o; - + assertEquals(aas1Id, aas.getIdShort()); assertEquals(aas1Id, aas.getIdentification().getId()); assertEquals(description1.get("en"), aas.getDescription().get("en")); assertEquals(aas1Category, aas.getCategory()); } - + private void checkAAS2(Object o) { assertTrue(o instanceof IAssetAdministrationShell); IAssetAdministrationShell aas = (IAssetAdministrationShell) o; - + assertEquals(aas2Id, aas.getIdShort()); assertEquals(aas2Id, aas.getIdentification().getId()); assertEquals(description2.get("en"), aas.getDescription().get("en")); assertEquals(aas2Category, aas.getCategory()); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java index 3e838b11..8977727e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregator.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.aggregator; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java index 00a6fc58..8e43540a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/TestAASAggregatorProxy.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.aggregator; @@ -38,7 +53,7 @@ public class TestAASAggregatorProxy extends AASAggregatorSuite { @Override protected IAASAggregator getAggregator() { - return new AASAggregatorProxy(new VABElementProxy("/shells", new AASAggregatorProvider(new AASAggregator()))); + return new AASAggregatorProxy(new VABElementProxy("", new AASAggregatorProvider(new AASAggregator()))); } /** @@ -82,8 +97,9 @@ public void testFeedThrough() throws Exception { assertEquals(expectedPropValue, connectedProp.getValue()); // Test feedthrough of INVOKE - // Use short form of invoke with operation variable matching and no parameters (empty object array) - assertTrue((boolean) ((IOperation) sm.getSubmodelElement(op.getIdShort())).invoke(new Object[0])); + // Use short form of invoke with operation variable matching and no parameters + // (empty object array) + assertTrue((boolean) ((IOperation) sm.getSubmodelElement(op.getIdShort())).invokeSimple(new Object[0])); // Test feedthrough of DELETE retrievedAAS.removeSubmodel(sm.getIdentification()); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/observing/ObservableAASAggregatorTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/observing/ObservableAASAggregatorTest.java new file mode 100644 index 00000000..c234e18f --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/aggregator/observing/ObservableAASAggregatorTest.java @@ -0,0 +1,134 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.aggregator.observing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.basyx.aas.aggregator.AASAggregator; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.observing.IAASAggregatorObserver; +import org.eclipse.basyx.aas.aggregator.observing.ObservableAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.junit.Before; +import org.junit.Test; + +public class ObservableAASAggregatorTest { + protected AssetAdministrationShell shell; + private static final String AASID = "aasid1"; + private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID); + + private ObservableAASAggregator observerdAASAggregator; + private MockObserver observer; + + @Before + public void setup() { + IAASAggregator aggregator = new AASAggregator(); + shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset(AASID, AASIDENTIFIER, AssetKind.INSTANCE)); + aggregator.createAAS(shell); + + observerdAASAggregator = new ObservableAASAggregator(aggregator); + + // Create an Observer + observer = new MockObserver(); + + // Register the observer at the API + observerdAASAggregator.addObserver(observer); + } + + @Test + public void testCreateAAS() { + String aasId2 = "aas2"; + Identifier identifier2 = new Identifier(IdentifierType.IRDI, aasId2); + AssetAdministrationShell shell2 = new AssetAdministrationShell(aasId2, identifier2, new Asset("assetid2", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE)); + observerdAASAggregator.createAAS(shell2); + + assertEquals(aasId2, observer.aasId); + assertTrue(observer.createdNotified); + } + + @Test + public void testUpdateAAS() { + shell.setCategory("newCategory"); + observerdAASAggregator.updateAAS(shell); + + assertTrue(observer.updatedNotified); + assertEquals(AASID, observer.aasId); + } + + @Test + public void testDeleteAAS() { + observerdAASAggregator.deleteAAS(AASIDENTIFIER); + assertTrue(observer.deletedNotified); + assertEquals(AASID, observer.aasId); + } + + @Test + public void testRemoveObserver() { + assertTrue(observerdAASAggregator.removeObserver(observer)); + observerdAASAggregator.deleteAAS(AASIDENTIFIER); + assertFalse(observer.deletedNotified); + } + + private class MockObserver implements IAASAggregatorObserver { + + public boolean createdNotified = false; + public boolean deletedNotified = false; + public boolean updatedNotified = false; + + public String aasId = ""; + + @Override + public void aasCreated(String aasId) { + createdNotified = true; + deletedNotified = false; + updatedNotified = false; + this.aasId = aasId; + } + + @Override + public void aasUpdated(String aasId) { + createdNotified = false; + deletedNotified = false; + updatedNotified = true; + this.aasId = aasId; + } + + @Override + public void aasDeleted(String aasId) { + createdNotified = false; + deletedNotified = true; + updatedNotified = false; + this.aasId = aasId; + } + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleDescriptorFactory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleDescriptorFactory.java new file mode 100644 index 00000000..b2918a99 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleDescriptorFactory.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.aas.bundle; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.bundle.AASBundleDescriptorFactory; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.junit.Test; + +/** + * Tests the methods of AASBundleDescriptorFactory for their correctness + * + * @author schnicke + * + */ +public class TestAASBundleDescriptorFactory { + @Test + public void testDescriptorCreation() { + String aasId = "aasId"; + AssetAdministrationShell shell = new AssetAdministrationShell(); + shell.setIdentification(new Identifier(IdentifierType.CUSTOM, aasId)); + + String smId = "smId"; + Submodel sm = new Submodel(); + sm.setIdShort(smId); + sm.setIdentification(IdentifierType.IRI, "aasIdIRI"); + + AASBundle bundle = new AASBundle(shell, Collections.singleton(sm)); + + String basePath = "http://localhost:4040/test"; + AASDescriptor desc = AASBundleDescriptorFactory.createAASDescriptor(bundle, basePath); + + String aasPath = VABPathTools.concatenatePaths(basePath, AASAggregatorProvider.PREFIX, aasId, "aas"); + String smPath = VABPathTools.concatenatePaths(aasPath, "submodels", sm.getIdShort(), "submodel"); + assertEquals(aasPath, desc.getFirstEndpoint()); + assertEquals(smPath, desc.getSubmodelDescriptorFromIdShort(smId).getFirstEndpoint()); + + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleFactory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleFactory.java new file mode 100644 index 00000000..dd7d4c6f --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleFactory.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.bundle; + +import java.util.Collections; + +import org.eclipse.basyx.aas.bundle.AASBundleFactory; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.junit.Test; + +/** + * Tests AASBundleFactory + * + * @author schnicke + * + */ +public class TestAASBundleFactory { + + @Test + public void testBundleCreationAssetAlreadySetInAAS() { + Asset asset = new Asset("assetIdShort", new CustomId("assetId"), AssetKind.INSTANCE); + + AssetAdministrationShell shell = new AssetAdministrationShell("aasIdShort", new CustomId("aasId"), asset); + new AASBundleFactory().create(Collections.singleton(shell), Collections.emptySet(), Collections.singleton(asset)); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleHelper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleHelper.java new file mode 100644 index 00000000..13a9bb29 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/bundle/TestAASBundleHelper.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.aas.bundle; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.basyx.aas.aggregator.AASAggregator; +import org.eclipse.basyx.aas.aggregator.proxy.AASAggregatorProxy; +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.bundle.AASBundleHelper; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; +import org.eclipse.basyx.aas.restapi.MultiSubmodelProvider; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.restapi.SubmodelProvider; +import org.eclipse.basyx.vab.modelprovider.VABElementProxy; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.junit.Before; +import org.junit.Test; + +/** + * Test for the AASBundelIntegrator + * + * @author conradi + * + */ +public class TestAASBundleHelper { + + private static final String AAS_ID = "TestAAS"; + private static final String SM_ID = "TestSM"; + + private AASAggregatorProxy aggregator; + private List bundles; + private AASAggregatorProvider provider; + + @Before + public void init() { + provider = new AASAggregatorProvider(new AASAggregator()); + aggregator = new AASAggregatorProxy(new VABElementProxy("", provider)); + bundles = new ArrayList<>(); + } + + /** + * This test tests whether the endpoint of a submodel contains the prefix + * "/shells". It register an aas-bundle in the registry, then retrieves a + * SubmodelDescriptor from the registered AasDescriptor. Finally, it checks + * whether the endpoint in the SubmodelDescriptor is correct. + */ + @Test + public void testAASBundleRegister() { + AASBundle bundle = getTestBundle(); + bundles.add(bundle); + InMemoryRegistry registry = new InMemoryRegistry(); + String serverPath = "http://localhost:4001/aasServer/"; + AASBundleHelper.register(registry, bundles, serverPath); + + Identifier smIdentifier = new Identifier(IdentifierType.CUSTOM, SM_ID); + Identifier aasIdentifier = new Identifier(IdentifierType.CUSTOM, AAS_ID); + SubmodelDescriptor smDescriptor = registry.lookupSubmodel(aasIdentifier, smIdentifier); + String actualEndpoint = smDescriptor.getFirstEndpoint(); + + String expectedEndpoint = VABPathTools.concatenatePaths(serverPath, AASAggregatorProvider.PREFIX, AAS_ID, MultiSubmodelProvider.SUBMODELS_PREFIX, SM_ID, SubmodelProvider.SUBMODEL); + assertEquals(expectedEndpoint, actualEndpoint); + } + + /** + * This test loads an AAS and its two Submodels into the Aggregator, runs the + * integration with AAS and Submodels with the same IDs, but different content, + * checks if integration does NOT replace the models in the Aggregator. + */ + @Test + public void testIntegrationOfExistingAASAndSM() { + AASBundle bundle = getTestBundle(); + bundles.add(bundle); + + // Load AAS and SM AASAggregator + AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS(); + Set submodels = bundle.getSubmodels(); + Submodel sm = (Submodel) submodels.iterator().next(); + pushAAS(aas); + pushSubmodel(sm, aas.getIdentification()); + + assertFalse(AASBundleHelper.integrate(aggregator, bundles)); + checkAggregatorContent(); + } + + /** + * This test loads an AAS into the Aggregator, runs the integration with the AAS + * and a SM, checks if both is present in Aggregator afterwards. + */ + @Test + public void testIntegrationOfExistingAASAndNonexistingSM() { + AASBundle bundle = getTestBundle(); + bundles.add(bundle); + + // Load only AAS into AASAggregator + AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS(); + pushAAS(aas); + + assertTrue(AASBundleHelper.integrate(aggregator, bundles)); + checkAggregatorContent(); + } + + /** + * This test loads nothing into the Aggregator, runs the integration with the + * AAS and a SM, checks if both is present in Aggregator afterwards. + */ + @Test + public void testIntegrationOfNonexistingAASAndSM() { + AASBundle bundle = getTestBundle(); + bundles.add(bundle); + + assertTrue(AASBundleHelper.integrate(aggregator, bundles)); + checkAggregatorContent(); + } + + /** + * This test loads nothing into the Aggregator, runs the integration with the + * AAS and a SM, checks if both is present in Aggregator afterwards. + * Furthermore, the AASAggregator has a registry for registering and resolving + * potential submodels. + */ + @Test + public void testIntegrationOfNonexistingAASAndSMWithRegistry() { + IAASRegistry registry = new InMemoryRegistry(); + provider = new AASAggregatorProvider(new AASAggregator(registry)); + aggregator = new AASAggregatorProxy(new VABElementProxy("", provider)); + + AASBundle bundle = getTestBundle(); + bundles.add(bundle); + + assertTrue(AASBundleHelper.integrate(aggregator, bundles)); + checkAggregatorContent(); + } + + @SuppressWarnings("unchecked") + private void checkAggregatorContent() { + IAssetAdministrationShell aas = aggregator.getAAS(new Identifier(IdentifierType.CUSTOM, AAS_ID)); + assertEquals(AAS_ID, aas.getIdShort()); + IModelProvider provider = aggregator.getAASProvider(new Identifier(IdentifierType.CUSTOM, AAS_ID)); + + Submodel sm = SubmodelElementMapCollectionConverter.mapToSM((Map) provider.getValue("/aas/submodels/" + SM_ID + "/" + SubmodelProvider.SUBMODEL)); + + assertEquals(SM_ID, sm.getIdentification().getId()); + } + + private void pushAAS(AssetAdministrationShell aas) { + aggregator.createAAS(aas); + } + + private void pushSubmodel(Submodel sm, IIdentifier aasIdentifier) { + provider.setValue("/" + AASAggregatorProvider.PREFIX + "/" + aasIdentifier.getId() + "/aas/submodels/" + sm.getIdShort(), sm); + } + + private AASBundle getTestBundle() { + Submodel sm = new Submodel(); + sm.setIdShort(SM_ID); + sm.setIdentification(IdentifierType.CUSTOM, SM_ID); + + AssetAdministrationShell aas = new AssetAdministrationShell(); + aas.setIdentification(IdentifierType.CUSTOM, AAS_ID); + aas.setIdShort(AAS_ID); + aas.addSubmodel(sm); + + return new AASBundle(aas, new HashSet<>(Arrays.asList(sm))); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java deleted file mode 100644 index 2939e979..00000000 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/AASXFactoryTest.java +++ /dev/null @@ -1,162 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - ******************************************************************************/ -package org.eclipse.basyx.testsuite.regression.aas.factory.aasx; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.eclipse.basyx.aas.factory.aasx.AASXFactory; -import org.eclipse.basyx.aas.factory.aasx.InMemoryFile; -import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; -import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; -import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; -import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; -import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; -import org.eclipse.basyx.aas.metamodel.map.parts.Asset; -import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; -import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription; -import org.eclipse.basyx.submodel.metamodel.map.Submodel; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; -import org.eclipse.basyx.vab.modelprovider.VABPathTools; -import org.junit.Before; -import org.junit.Test; - -/** - * Test for the AASXFactory - * - * @author conradi - * - */ -public class AASXFactoryTest { - - private static final String XML_PATH = "aasx/xml/content.xml"; - private static final String ORIGIN_PATH = "aasx/aasx-origin"; - private static final String EXTERNAL_FILE_URL = "http://localhost:8080/image.png"; - - - private AssetAdministrationShell aas; - private Submodel sm1; - private Submodel sm2; - - private List aasList = new ArrayList<>(); - private List submodelList = new ArrayList<>(); - private List assetList = new ArrayList<>(); - private List conceptDescriptionList = new ArrayList<>(); - - private List fileList = new ArrayList<>(); - - - - @Before - public void setup() throws IOException { - Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.TYPE); - aas = new AssetAdministrationShell("aas-id", new ModelUrn("AAS_IDENTIFICATION"), asset); - - sm1 = new Submodel("sm1", new ModelUrn("SM1_ID")); - sm2 = new Submodel("sm2", new ModelUrn("SM2_ID")); - - File file1 = new File(EXTERNAL_FILE_URL, "image/png"); - file1.setIdShort("file1"); - File file2 = new File("aasx/Document/docu.pdf", "application/pdf"); - file2.setIdShort("file2"); - File file3 = new File("/aasx/Document/docu2.pdf", "application/pdf"); - file3.setIdShort("file3"); - - - - SubmodelElementCollection collection = new SubmodelElementCollection("collection"); - collection.addSubmodelElement(file2); - - sm1.addSubmodelElement(file1); - sm1.addSubmodelElement(collection); - sm2.addSubmodelElement(file3); - - aas.addSubmodel(sm1); - aas.addSubmodel(sm2); - - aasList.add(aas); - submodelList.add(sm1); - submodelList.add(sm2); - assetList.add(asset); - - - byte[] content1 = {5,6,7,8,9}; - InMemoryFile file = new InMemoryFile(content1, "/aasx/Document/docu.pdf"); - fileList.add(file); - - byte[] content2 = {10,11,12,13,14}; - file = new InMemoryFile(content2, "aasx/Document/docu2.pdf"); - fileList.add(file); - } - - - @Test - public void testBuildAASX() throws IOException, TransformerException, ParserConfigurationException { - - // This stream can be used to write the .aasx directly to a file - // FileOutputStream out = new FileOutputStream("path/to/test.aasx"); - - // This stream keeps the output of the AASXFactory only in memory - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - AASXFactory.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out); - - validateAASX(out); - - } - - - private void validateAASX(ByteArrayOutputStream byteStream) throws IOException { - ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(byteStream.toByteArray())); - ZipEntry zipEntry = null; - - ArrayList filePaths = new ArrayList<>(); - - while((zipEntry = in.getNextEntry()) != null) { - if(zipEntry.getName().equals(XML_PATH)) { - - // Read the first 5 bytes of the XML file to make sure it is in fact XML file - // No further test of XML file necessary as XML-Converter is tested separately - byte[] buf = new byte[5]; - in.read(buf); - assertEquals(" listOfAssetAdministrationShell = Arrays.asList(assetAdministrationShell); - - AASXPackageExplorerConformantHelper.adapt(listOfAssetAdministrationShell, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList()); - AASXPackageExplorerConformantHelper.adapt(listOfAssetAdministrationShell, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList()); + + AASXPackageExplorerConformantHelper.adapt(listOfAssetAdministrationShell, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + AASXPackageExplorerConformantHelper.adapt(listOfAssetAdministrationShell, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java new file mode 100644 index 00000000..63c0ccb5 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java @@ -0,0 +1,497 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.factory.aasx; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.commons.io.FileUtils; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.factory.aasx.AASXToMetamodelConverter; +import org.eclipse.basyx.aas.factory.aasx.InMemoryFile; +import org.eclipse.basyx.aas.factory.aasx.MetamodelToAASXConverter; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; + +/** + * J-Unit tests AASX-Files created by the BaSyx middleware itself. + * + * @author zhangzai, conradi, fischer, jungjan + * + */ +public class TestAASXToMetamodelConverterFromBaSyx { + private static final String CREATED_AASX_FILE_PATH = "test.aasx"; + + private static final String AAS_IDSHORT = "assIdShort"; + private static final String AAS_IDENTIFICATION = "assIdentification"; + private static final String ASSET_IDSHORT = "assetIdShort"; + private static final String ASSET_IDENTIFICATION = "assetIdentification"; + private static final String SUBMODEL_IDSHORT = "submodelIdShort"; + private static final String SUBMODEL_IDENTIFICATION = "submodelIdentification"; + private static final String SUBMODEL_COLLECTION_IDSHORT = "submodelCollectionIdShort"; + + private static final String BOOLEAN_PROPERTY_IDSHORT = "bool"; + private static final String INTEGER_PROPERTY_IDSHORT = "int"; + private static final String DOUBLE_PROPERTY_IDSHORT = "decimal"; + private static final String STRING_PROPERTY_IDSHORT = "string"; + private static final Boolean EXPECTED_BOOLEAN_VALUE = true; + private static final int EXPECTED_INTEGER_VALUE = 42; + private static final double EXPECTED_DOUBLE_VALUE = 3.14159265359; + private static final String EXPECTED_STRING_VALUE = "test"; + + private static final String IMAGE_PATH = "/icon.png"; + private static final String IMAGE_MIMETYPE = "image/png"; + private static final String IMAGE_IDSHORT = "image"; + private static final String PDF_PATH = "/aasx/Document/docu.pdf"; + private static final String PDF_MIMETYPE = "application/pdf"; + private static final String PDF_IDSHORT = "pdf"; + private static final String TARGET_PATH = "target/files"; // gets set by BaSyx + private static final String[] EXPECTED_UNZIPPED_FILES = { TARGET_PATH + PDF_PATH, TARGET_PATH + IMAGE_PATH }; + + private static final String REL_PATH = "_rels/.rels"; + private static final String ORIGIN_REL_PATH = "aasx/_rels/aasx-origin.rels"; + + private static final String ID_REGEX_START = "Id=.*"; + // only letters or underscore as start of id allowed + // https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-qualnames + private static final String ID_REGEX_FULL = "Id=\"([A-z]|_).*"; + + private static final String TARGET_PATH_REGEX_START = "Target=.*"; + private static final String TARGET_PATH_REGEX_FULL = "Target=\"/.*"; + private static final String DOCPROPS_PATH_REGEX = "Target=\"docProps.*"; + + private int bundleSize; + private int submodelSize; + private int submodelElementsSize; + + private AASXToMetamodelConverter packageManager; + + @Before + public void setup() throws IOException, TransformerException, ParserConfigurationException { + createAASXFile(CREATED_AASX_FILE_PATH); + + packageManager = new AASXToMetamodelConverter(CREATED_AASX_FILE_PATH); + } + + /** + * Tests the AAS and its submodels of the parsed AASX file + * + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + * @throws InvalidFormatException + */ + @Test + public void testLoadGeneratedAASX() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException { + Set bundles = packageManager.retrieveAASBundles(); + + assertEquals(bundleSize, bundles.size()); + AASBundle bundle = bundles.stream().findFirst().get(); + + IAssetAdministrationShell parsedAAS = bundle.getAAS(); + assertEquals(AAS_IDSHORT, parsedAAS.getIdShort()); + assertEquals(AAS_IDENTIFICATION, parsedAAS.getIdentification().getId()); + + assertEquals(submodelSize, bundle.getSubmodels().size()); + + ISubmodel parsedSubmodel = bundle.getSubmodels().stream().findFirst().get(); + assertEquals(SUBMODEL_IDSHORT, parsedSubmodel.getIdShort()); + assertEquals(SUBMODEL_IDENTIFICATION, parsedSubmodel.getIdentification().getId()); + assertEquals(submodelElementsSize, parsedSubmodel.getSubmodelElements().size()); + } + + /** + * Check if the values and value types of Property submodelElements a parsed + * *.aasx file are returned correctly + * + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + * @throws InvalidFormatException + */ + @Test + public void submodelElementPropertyValues() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException { + Set bundles = packageManager.retrieveAASBundles(); + AASBundle bundle = bundles.stream().findFirst().get(); + + ISubmodel parsedSubmodel = bundle.getSubmodels().stream().findFirst().get(); + Map submodelElements = parsedSubmodel.getSubmodelElements(); + + ISubmodelElement boolProperty = submodelElements.get(BOOLEAN_PROPERTY_IDSHORT); + ISubmodelElement intProperty = submodelElements.get(INTEGER_PROPERTY_IDSHORT); + ISubmodelElement doubleProperty = submodelElements.get(DOUBLE_PROPERTY_IDSHORT); + ISubmodelElement stringProperty = submodelElements.get(STRING_PROPERTY_IDSHORT); + + assertEquals(EXPECTED_BOOLEAN_VALUE, boolProperty.getValue()); + assertEquals(EXPECTED_INTEGER_VALUE, intProperty.getValue()); + assertEquals(EXPECTED_DOUBLE_VALUE, doubleProperty.getValue()); + assertEquals(EXPECTED_STRING_VALUE, stringProperty.getValue()); + } + + /** + * Tests the connected files of the parsed AASX file. + * + * @throws InvalidFormatException + * @throws IOException + * @throws ParserConfigurationException + * @throws SAXException + * @throws URISyntaxException + */ + @Test + public void testFilesOfGeneratedAASX() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { + // Unzip files from the .aasx + packageManager.unzipRelatedFiles(); + + // Check if all expected files are present + for (String path : EXPECTED_UNZIPPED_FILES) { + assertTrue(new java.io.File(path).exists()); + } + } + + /** + * Tests if the ids start with a letter or underscore and if the paths are + * absolute. + * + * @throws IOException + * @throws ParserConfigurationException + * @throws SAXException + */ + @Test + public void testRelationshipsOfGeneratedAASX() throws IOException { + ZipInputStream in = unzipFromPath(CREATED_AASX_FILE_PATH); + + String relString = getFileContentFromZipInputStream(REL_PATH, in); + String originRelString = getFileContentFromZipInputStream(ORIGIN_REL_PATH, in); + + List relStringIds = findIdCandidates(relString); + List originRelStringIds = findIdCandidates(originRelString); + + assertIdsBeginWithLetterOrUnderscore(relStringIds); + assertIdsBeginWithLetterOrUnderscore(originRelStringIds); + + // this step is necessary for compatibility reasons with AASXPackageExplorer + List relStringPaths = findPathCandidates(relString); + List originRelStringPaths = findPathCandidates(originRelString); + + assertPathsAreAbsolute(relStringPaths); + assertPathsAreAbsolute(originRelStringPaths); + } + + /** + * Check if elements of the given path list adhere to the target path regEx. + * This step is necessary for compatibility reasons with AASXPackageExplorer. + * + * @param pathStringList + */ + private void assertPathsAreAbsolute(List pathStringList) { + assertStringListRegExCheck(pathStringList, TARGET_PATH_REGEX_FULL); + } + + /** + * Split the given string at every whitespace and returns all elements that + * start with "Target=". This step is necessary for compatibility reasons with + * AASXPackageExplorer. + * + * @param stringToCheck + * @return List + */ + private List findPathCandidates(String stringToCheck) { + List potentialPaths = findRegExParts(stringToCheck, TARGET_PATH_REGEX_START); + + // remove docProps path, because docProps is not relevant for + // AASXPackageExplorer + return removeDocPropsPath(potentialPaths); + } + + /** + * Remove every target path that matches with the docProps path, because + * docProps is not relevant for AASXPackageExplorer. + * + * @param givenPathList + * @return List + */ + private List removeDocPropsPath(List givenPathList) { + for (int i = 0; i < givenPathList.size(); i++) { + if (givenPathList.get(i).matches(DOCPROPS_PATH_REGEX)) { + givenPathList.remove(i); + } + } + + return givenPathList; + } + + /** + * Check if elements of the given id list adhere to the id regEx. + * + * @param idStringList + */ + private void assertIdsBeginWithLetterOrUnderscore(List idStringList) { + assertStringListRegExCheck(idStringList, ID_REGEX_FULL); + } + + /** + * Split the given string at every whitespace and returns all elements that + * start with "Id=" + * + * @param stringToCheck + * @return List + */ + private List findIdCandidates(String stringToCheck) { + return findRegExParts(stringToCheck, ID_REGEX_START); + } + + /** + * Check if elements of the given list adhere to the given regEx. + * + * @param stringToCheck + * @param regEx + */ + private void assertStringListRegExCheck(List stringToCheck, String regEx) { + for (String part : stringToCheck) { + assertTrue(part.matches(regEx)); + } + } + + /** + * Split the given string at every whitespace and returns a list of all + * remaining elements that adhere to the given regEx. + * + * @param stringToCheck + * @param regEx + * @return List + */ + private List findRegExParts(String stringToCheck, String regEx) { + String[] stringParts = stringToCheck.split(" "); + List regExParts = new ArrayList(); + + for (String part : stringParts) { + if (part.matches(regEx)) { + regExParts.add(part); + } + } + + return regExParts; + } + + /** + * Get the content of a file with a given path from a ZipInputStream as String + * + * @param filePath + * @param in + * @return String of the file contents + * @throws IOException + */ + private String getFileContentFromZipInputStream(String filePath, ZipInputStream in) throws IOException { + ZipEntry zipEntry = null; + String contentString = ""; + + while ((zipEntry = in.getNextEntry()) != null) { + if (zipEntry.getName().equals(filePath)) { + byte[] buf = new byte[1]; + + while (in.read(buf) > 0) { + contentString += new String(buf); + } + } + } + return contentString; + } + + /** + * Unzip a file from path using a ByteArrayInputStream + * + * @param path + * @return ZipInputStream + * @throws IOException + */ + private ZipInputStream unzipFromPath(String path) throws IOException { + return new ZipInputStream(new ByteArrayInputStream(FileUtils.readFileToByteArray(new java.io.File(path)))); + } + + /** + * Create an AASX file with default values. + * + * @param filePath + * @throws IOException + * @throws TransformerException + * @throws ParserConfigurationException + */ + private void createAASXFile(String filePath) throws IOException, TransformerException, ParserConfigurationException { + List aasList = new ArrayList<>(); + List submodelList = new ArrayList<>(); + List assetList = new ArrayList<>(); + List conceptDescriptionList = new ArrayList<>(); + + List fileList = new ArrayList<>(); + + Asset asset = new Asset(ASSET_IDSHORT, new ModelUrn(ASSET_IDENTIFICATION), AssetKind.INSTANCE); + AssetAdministrationShell aas = new AssetAdministrationShell(AAS_IDSHORT, new ModelUrn(AAS_IDENTIFICATION), asset); + aas.setAssetReference((Reference) asset.getReference()); + + Submodel sm = new Submodel(SUBMODEL_IDSHORT, new ModelUrn(SUBMODEL_IDENTIFICATION)); + + // Create SubmodelElements + SubmodelElementCollection collection = new SubmodelElementCollection(SUBMODEL_COLLECTION_IDSHORT); + collection.addSubmodelElement(createBaSyxFile(IMAGE_PATH, IMAGE_MIMETYPE, IMAGE_IDSHORT)); + + sm.addSubmodelElement(collection); + sm.addSubmodelElement(createBooleanProperty()); + sm.addSubmodelElement(createIntegerProperty()); + sm.addSubmodelElement(createDoubleProperty()); + sm.addSubmodelElement(createStringProperty()); + sm.addSubmodelElement(createBaSyxFile(PDF_PATH, PDF_MIMETYPE, PDF_IDSHORT)); + aas.addSubmodel(sm); + + // Add all AASs to the list that will be converted and set the size for the test + // comparison + aasList.add(aas); + bundleSize = 1; + + // Add all Submodels to the list that will be converted and set the size for the + // test comparison + submodelList.add(sm); + submodelSize = 1; + + assetList.add(asset); + + // Build InMemoryFiles, add them to the list that will be converted and set the + // size for the test comparison + fileList.add(createInMemoryFile(IMAGE_PATH)); + fileList.add(createInMemoryFile(PDF_PATH)); + submodelElementsSize = 6; + + try (FileOutputStream out = new FileOutputStream(filePath)) { + MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out); + } + } + + private ISubmodelElement createBooleanProperty() { + Property booleanProperty = new Property(); + booleanProperty.setIdShort(BOOLEAN_PROPERTY_IDSHORT); + booleanProperty.setCategory("CONSTANT"); + booleanProperty.setValueType(ValueType.Boolean); + booleanProperty.setValue(EXPECTED_BOOLEAN_VALUE); + return booleanProperty; + } + + private ISubmodelElement createIntegerProperty() { + Property intProperty = new Property(); + intProperty.setIdShort(INTEGER_PROPERTY_IDSHORT); + intProperty.setCategory("CONSTANT"); + intProperty.setValueType(ValueType.Integer); + intProperty.setValue(EXPECTED_INTEGER_VALUE); + return intProperty; + } + + private ISubmodelElement createDoubleProperty() { + Property doubleProperty = new Property(); + doubleProperty.setIdShort(DOUBLE_PROPERTY_IDSHORT); + doubleProperty.setCategory("CONSTANT"); + doubleProperty.setValueType(ValueType.Double); + doubleProperty.setValue(EXPECTED_DOUBLE_VALUE); + return doubleProperty; + } + + private ISubmodelElement createStringProperty() { + Property stringProperty = new Property(); + stringProperty.setIdShort(STRING_PROPERTY_IDSHORT); + stringProperty.setCategory("CONSTANT"); + stringProperty.setValueType(ValueType.String); + stringProperty.setValue(EXPECTED_STRING_VALUE); + return stringProperty; + } + + /** + * Delete created files + */ + @AfterClass + public static void cleanUp() { + for (String path : EXPECTED_UNZIPPED_FILES) { + new java.io.File(path).delete(); + } + new java.io.File(CREATED_AASX_FILE_PATH).delete(); + } + + /** + * Create a BaSyx File for given path, mimeType and idShort. + * + * @param filePath + * @param fileMimeType + * @param fileIdShort + * @return BaSyx File + */ + private File createBaSyxFile(String filePath, String fileMimeType, String fileIdShort) { + File file = new File(filePath, fileMimeType); + file.setIdShort(fileIdShort); + + return file; + } + + /** + * Create an inMemoryFile with default content for a given path. + * + * @param filePath + * @return InMemoryFile + */ + private InMemoryFile createInMemoryFile(String filePath) { + byte[] content = { 1, 2, 3, 4, 5 }; + InMemoryFile file = new InMemoryFile(content, filePath); + + return file; + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java new file mode 100644 index 00000000..9fc470ca --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromFile.java @@ -0,0 +1,368 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.factory.aasx; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.factory.aasx.AASXToMetamodelConverter; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xml.sax.SAXException; + +/** + * J-Unit tests for AASXPackageExplorer. This test checks the parsing of aas, + * submodels, assets and concept-descriptions. It also checks whether the AAS + * has correct references to the assets and submodels. + * + * @author zhangzai, conradi, fischer + * + */ +public class TestAASXToMetamodelConverterFromFile { + /** + * Define constants and variables for test + */ + private static final String GIVEN_AASX_FILE_PATH = "src/test/resources/aas/factory/aasx/01_Festo.aasx"; + + private static final int EXPECTED_AASBUNDLE_SIZE = 2; + private static final String EXPECTED_AAS_IDSHORT = "Festo_3S7PM0CP4BD"; + private static final String EXPECTED_AAS_CATEGORY = "CONSTANT"; + private static final String EXPECTED_AAS_IDENTIFICATION_ID = "smart.festo.com/demo/aas/1/1/454576463545648365874"; + private static final IdentifierType EXPECTED_AAS_IDENTIFICATION_ID_TYPE = IdentifierType.IRI; + + private static final int EXPECTED_SUBMODEL_REFERENCE_SIZE = 5; + private static final String EXPECTED_SUBMODEL_REFERENCE_ID_TYPE = "IRI"; + private static final String EXPECTED_SUBMODEL_REFERENCE_MODEL_TYPE = "SUBMODEL"; + private static final boolean EXPECTED_SUBMODEL_REFERENCE_LOCAL = true; + private static final String[] EXPECTED_SUBMODEL_REFERENCE_IDS = { "www.company.com/ids/sm/6053_5072_7091_5102", "smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", "www.company.com/ids/sm/4343_5072_7091_3242", + "www.company.com/ids/sm/2543_5072_7091_2660", "www.company.com/ids/sm/6563_5072_7091_4267" }; + + private static final int EXPECTED_SUBMODEL_SIZE = 5; + private static final String EXPECTED_SUBMODEL_IDSHORT = "Nameplate"; + private static final String EXPECTED_SUBMODEL_IDENTIFICATION_ID = "www.company.com/ids/sm/4343_5072_7091_3242"; + private static final IdentifierType EXPECTED_SUBMODEL_IDENTIFICATION_ID_TYPE = IdentifierType.IRI; + private static final String EXPECTED_SUBMODEL_MODELING_KIND = "Instance"; + + private static final String EXPECTED_SUBMODELELEMENT_CATEGORY = "PARAMETER"; + private static final String EXPECTED_SUBMODELELEMENT_MODELING_KIND = "Instance"; + private static final ValueType EXPECTED_SUBMODELELEMENT_PROPERTY_VALUE_TYPE = ValueType.String; + private static final String EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_TYPE = "ConceptDescription"; + private static final boolean EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_LOCAL = true; + + private static final String EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_IDSHORT = "ManufacturerName"; + private static final String EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_PROPERTY_VALUE = "Festo AG & Co. KG"; + private static final String EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_SEMANTIC_KEY_ID_TYPE = "IRDI"; + private static final String EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_SEMANTIC_KEY_VALUE = "0173-1#02-AAO677#002"; + + private static final String EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_IDSHORT = "ManufacturerProductDesignation"; + private static final String EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_PROPERTY_VALUE = "OVEL Vacuum generator"; + private static final String EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_SEMANTIC_KEY_ID_TYPE = "IRDI"; + private static final String EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_SEMANTIC_KEY_VALUE = "0173-1#02-AAW338#001"; + + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_IDSHORT = "PhysicalAddress"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_SEMANTIC_KEY_ID_TYPE = "IRI"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_SEMANTIC_KEY_VALUE = "https://www.hsu-hh.de/aut/aas/physicaladdress"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_MODEL_TYPE = "SubmodelElementCollection"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_1_IDSHORT = "CountryCode"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_1_VALUE = "DE"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_2_IDSHORT = "Street"; + private static final String EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_2_VALUE = "Ruiter Straße 82"; + + private static AASXToMetamodelConverter packageConverter; + private static Set aasBundlesFromConverter; + private static Optional specificAASBundleOptional; + private static IAssetAdministrationShell assFromConverter; + + private static Set submodelsFromConverter; + private static Optional specificSubmodelOptional; + private static ISubmodel specificSubmodel; + private static Map specificSubmodelElements; + + @BeforeClass + public static void setup() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException { + // Initialize the aasx package converter with the path to the aasx package + packageConverter = new AASXToMetamodelConverter(GIVEN_AASX_FILE_PATH); + + // retrieve all AASBundles of the given file + aasBundlesFromConverter = packageConverter.retrieveAASBundles(); + + // get the Optional of the selected AAS and the AAS itself + specificAASBundleOptional = getSpecificAASBundleAsOptional(aasBundlesFromConverter, EXPECTED_AAS_IDSHORT); + assFromConverter = getAASFromBundleOptional(specificAASBundleOptional); + + // get the Optional of the selected submodel and the submodel itself + // as well as its submodelElements + submodelsFromConverter = getFirstSubmodel(aasBundlesFromConverter, EXPECTED_AAS_IDSHORT); + specificSubmodelOptional = getSpecificSubmodelAsOptional(submodelsFromConverter, EXPECTED_SUBMODEL_IDSHORT); + specificSubmodel = specificSubmodelOptional.get(); + specificSubmodelElements = specificSubmodel.getSubmodelElements(); + } + + /** + * Test the converted AAS with expected information. + */ + @Test + public void testAASsOfConvertedAASX() { + // check bundle size + assertEquals(EXPECTED_AASBUNDLE_SIZE, aasBundlesFromConverter.size()); + + // check if Optional is present + assertTrue(specificAASBundleOptional.isPresent()); + + // check AAS specific attributes + assertEquals(EXPECTED_AAS_IDSHORT, assFromConverter.getIdShort()); + assertEquals(EXPECTED_AAS_CATEGORY, assFromConverter.getCategory()); + assertEquals(EXPECTED_AAS_IDENTIFICATION_ID, assFromConverter.getIdentification().getId()); + assertEquals(EXPECTED_AAS_IDENTIFICATION_ID_TYPE, assFromConverter.getIdentification().getIdType()); + } + + /** + * Test the converted submodel references with expected information. + */ + @Test + public void testSubmodelReferencesOfConvertedAASX() { + Collection submodelReferences = assFromConverter.getSubmodelReferences(); + assertEquals(EXPECTED_SUBMODEL_REFERENCE_SIZE, submodelReferences.size()); + + List referencelist = new ArrayList<>(); + referencelist.addAll(submodelReferences); + sortReferencelist(referencelist); + for (int i = 0; i < referencelist.size(); i++) { + IReference ref = referencelist.get(i); + List refKeys = ref.getKeys(); + + assertEquals(EXPECTED_SUBMODEL_REFERENCE_IDS[i], refKeys.get(0).getValue()); + assertEquals(EXPECTED_SUBMODEL_REFERENCE_ID_TYPE, refKeys.get(0).getIdType().name()); + assertEquals(EXPECTED_SUBMODEL_REFERENCE_MODEL_TYPE, refKeys.get(0).getType().name()); + assertEquals(EXPECTED_SUBMODEL_REFERENCE_LOCAL, refKeys.get(0).isLocal()); + } + } + + /** + * Test parsed submodels with expected information about them. + */ + @Test + public void testSubmodelsOfConvertedAASX() { + // check submodel size + assertEquals(EXPECTED_SUBMODEL_SIZE, submodelsFromConverter.size()); + + // check if Optional is present + assertTrue(specificSubmodelOptional.isPresent()); + + // check specific submodel + assertEquals(EXPECTED_SUBMODEL_IDSHORT, specificSubmodel.getIdShort()); + assertEquals(EXPECTED_SUBMODEL_IDENTIFICATION_ID, specificSubmodel.getIdentification().getId()); + assertEquals(EXPECTED_SUBMODEL_IDENTIFICATION_ID_TYPE, specificSubmodel.getIdentification().getIdType()); + assertEquals(EXPECTED_SUBMODEL_MODELING_KIND, specificSubmodel.getKind().toString()); + } + + /** + * Test the manufacturer name submodel element. + */ + @Test + public void testManufacturerNameSubmodelElementOfConvertedAASX() { + // get submodelElement + ISubmodelElement submodelElement = specificSubmodelElements.get(EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_IDSHORT); + + // check if the idShort matches + assertEquals(EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_IDSHORT, submodelElement.getIdShort()); + + // check if the category and modelingKind matches + assertEquals(EXPECTED_SUBMODELELEMENT_CATEGORY, submodelElement.getCategory()); + assertTrue(submodelElement.getKind().name().equalsIgnoreCase(EXPECTED_SUBMODELELEMENT_MODELING_KIND)); + + // check if the property matches + Property prop = (Property) submodelElement; + assertEquals(EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_PROPERTY_VALUE, prop.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_PROPERTY_VALUE_TYPE, prop.getValueType()); + + // check if the semantic matches + IReference semantic = submodelElement.getSemanticId(); + IKey semanticKey = semantic.getKeys().get(0); + assertTrue(semanticKey.getType().name().equalsIgnoreCase(EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_TYPE)); + assertEquals(EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_SEMANTIC_KEY_ID_TYPE, semanticKey.getIdType().name()); + assertEquals(EXPECTED_MANUFACTURER_NAME_SUBMODELELEMENT_SEMANTIC_KEY_VALUE, semanticKey.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_LOCAL, semanticKey.isLocal()); + } + + /** + * test the manufacturer product designation submodel element. + */ + @Test + public void testManufacturerProductDesignationSubmodelElementOfConvertedAASX() { + // get submodelElement + ISubmodelElement submodelElement = specificSubmodelElements.get(EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_IDSHORT); + + // check if the idShort matches + assertEquals(EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_IDSHORT, submodelElement.getIdShort()); + + // check if the category and modelingKind matches + assertEquals(EXPECTED_SUBMODELELEMENT_CATEGORY, submodelElement.getCategory()); + assertTrue(submodelElement.getKind().name().equalsIgnoreCase(EXPECTED_SUBMODELELEMENT_MODELING_KIND)); + + // check if the property matches + Property prop = (Property) submodelElement; + assertEquals(EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_PROPERTY_VALUE, prop.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_PROPERTY_VALUE_TYPE, prop.getValueType()); + + // check if the semantic matches + IReference semantic = submodelElement.getSemanticId(); + IKey semanticKey = semantic.getKeys().get(0); + assertTrue(semanticKey.getType().name().equalsIgnoreCase(EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_TYPE)); + assertEquals(EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_SEMANTIC_KEY_ID_TYPE, semanticKey.getIdType().name()); + assertEquals(EXPECTED_MANUFACTURER_PRODUCT_DESIGNATION_SUBMODELELEMENT_SEMANTIC_KEY_VALUE, semanticKey.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_LOCAL, semanticKey.isLocal()); + } + + /** + * test the physical address submodel element collection. + */ + @Test + public void testPhysicalAddressSubmodelElementOfConvertedAASX() { + // get submodelElement + ISubmodelElement submodelElement = specificSubmodelElements.get(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_IDSHORT); + + // check if the idShort matches + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_IDSHORT, submodelElement.getIdShort()); + + // check if the category and modelingKind matches + assertEquals(EXPECTED_SUBMODELELEMENT_CATEGORY, submodelElement.getCategory()); + assertTrue(submodelElement.getKind().name().equalsIgnoreCase(EXPECTED_SUBMODELELEMENT_MODELING_KIND)); + + // check if the semantic matches + IReference semantic = submodelElement.getSemanticId(); + IKey semanticKey = semantic.getKeys().get(0); + assertTrue(semanticKey.getType().name().equalsIgnoreCase(EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_TYPE)); + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_SEMANTIC_KEY_ID_TYPE, semanticKey.getIdType().name()); + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_SEMANTIC_KEY_VALUE, semanticKey.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_SEMANTIC_KEY_LOCAL, semanticKey.isLocal()); + + // check submodelElementColleciton + assertTrue(submodelElement.getModelType().equalsIgnoreCase(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_MODEL_TYPE)); + SubmodelElementCollection collection = (SubmodelElementCollection) submodelElement; + Map submodelElementCollectionMap = collection.getSubmodelElements(); + + // check if the properties match + assertEquals(5, submodelElementCollectionMap.size()); + Property prop1 = (Property) submodelElementCollectionMap.get(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_1_IDSHORT); + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_1_IDSHORT, prop1.getIdShort()); + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_1_VALUE, prop1.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_PROPERTY_VALUE_TYPE, prop1.getValueType()); + + Property prop2 = (Property) submodelElementCollectionMap.get(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_2_IDSHORT); + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_2_IDSHORT, prop2.getIdShort()); + assertEquals(EXPECTED_PHYSICAL_ADDRESS_SUBMODELELEMENT_PROP_2_VALUE, prop2.getValue()); + assertEquals(EXPECTED_SUBMODELELEMENT_PROPERTY_VALUE_TYPE, prop2.getValueType()); + } + + /** + * Sort a given referenceList by the last two numbers of their ids. + * + * @param referencelist + */ + private void sortReferencelist(List referencelist) { + referencelist.sort((x, y) -> { + String idx = x.getKeys().get(0).getValue(); + String idy = y.getKeys().get(0).getValue(); + + String idx_end = idx.substring(idx.length() - 2); + int idxint = Integer.parseInt(idx_end); + String idy_end = idy.substring(idy.length() - 2); + int idyint = Integer.parseInt(idy_end); + + return idxint - idyint; + }); + } + + /** + * Get the first submodel set from given set of AASBundles. + * + * @param givenBundles + * @param specificSubmodelIdShort + * @return Set + */ + private static Set getFirstSubmodel(Set givenBundles, String specificSubmodelIdShort) { + return givenBundles.stream().filter(b -> b.getAAS().getIdShort().equals(specificSubmodelIdShort)).findFirst().get().getSubmodels(); + } + + /** + * Get the Optional with a given specificAASIdShort from a set of + * AASBundles. + * + * @param aasBundles + * @param specificAASIdShort + * @return Optional + */ + private static Optional getSpecificAASBundleAsOptional(Set aasBundles, String specificAASIdShort) { + return aasBundles.stream().filter(b -> b.getAAS().getIdShort().equals(specificAASIdShort)).findFirst(); + } + + /** + * Get the Optional with a given specificSubmodelIdShort from a set + * of submodels. + * + * @param submodels + * @param specificSubmodelIdShort + * @return Optional + */ + private static Optional getSpecificSubmodelAsOptional(Set submodels, String specificSubmodelIdShort) { + return submodels.stream().filter(s -> s.getIdShort().equals(specificSubmodelIdShort)).findFirst(); + } + + /** + * Get the AAS of an optional AASBundle. + * + * @param optionalBundle + * @return IAssetAdministrationShell + */ + private static IAssetAdministrationShell getAASFromBundleOptional(Optional optionalBundle) { + AASBundle testAASBundle = optionalBundle.get(); + IAssetAdministrationShell aas = testAASBundle.getAAS(); + + return aas; + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java new file mode 100644 index 00000000..ee2e20cc --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java @@ -0,0 +1,235 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.aas.factory.aasx; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.eclipse.basyx.aas.bundle.AASBundle; +import org.eclipse.basyx.aas.factory.aasx.AASXToMetamodelConverter; +import org.eclipse.basyx.aas.factory.aasx.InMemoryFile; +import org.eclipse.basyx.aas.factory.aasx.MetamodelToAASXConverter; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; + +/** + * Test for the AASXFactory + * + * @author conradi + * + */ +public class TestMetamodelToAASXConverter { + + private static final String XML_PATH = "aasx/xml/content.xml"; + private static final String ORIGIN_PATH = "aasx/aasx-origin"; + private static final String EXTERNAL_FILE_URL = "http://localhost:8080/image.png"; + private static final String INTERNAL_FILE_PATH_1 = "aasx/Document/docu.pdf"; + private static final String INTERNAL_FILE_PATH_2 = "/aasx/Document/docu2.pdf"; + + private static final String FILE_ID_SHORT_1 = "file1"; + private static final String FILE_ID_SHORT_2 = "file2"; + private static final String FILE_ID_SHORT_3 = "file3"; + private static final String COLLECTION_ID_SHORT = "collection"; + + private AssetAdministrationShell aas; + private Submodel sm1; + private Submodel sm2; + + private List aasList = new ArrayList<>(); + private List submodelList = new ArrayList<>(); + private List assetList = new ArrayList<>(); + private List conceptDescriptionList = new ArrayList<>(); + + private List fileList = new ArrayList<>(); + + @Before + public void setup() throws IOException { + Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.TYPE); + aas = new AssetAdministrationShell("aas-id", new ModelUrn("AAS_IDENTIFICATION"), asset); + + sm1 = new Submodel("sm1", new ModelUrn("SM1_ID")); + sm2 = new Submodel("sm2", new ModelUrn("SM2_ID")); + + File file1 = new File(EXTERNAL_FILE_URL, "image/png"); + file1.setIdShort(FILE_ID_SHORT_1); + File file2 = new File(INTERNAL_FILE_PATH_1, "application/pdf"); + file2.setIdShort(FILE_ID_SHORT_2); + File file3 = new File(INTERNAL_FILE_PATH_2, "application/pdf"); + file3.setIdShort(FILE_ID_SHORT_3); + + SubmodelElementCollection collection = new SubmodelElementCollection(COLLECTION_ID_SHORT); + collection.addSubmodelElement(file2); + + sm1.addSubmodelElement(file1); + sm1.addSubmodelElement(collection); + sm2.addSubmodelElement(file3); + + aas.addSubmodel(sm1); + aas.addSubmodel(sm2); + + aasList.add(aas); + submodelList.add(sm1); + submodelList.add(sm2); + assetList.add(asset); + + byte[] content1 = { 5, 6, 7, 8, 9 }; + InMemoryFile file = new InMemoryFile(content1, "/aasx/Document/docu.pdf"); + fileList.add(file); + + byte[] content2 = { 10, 11, 12, 13, 14 }; + file = new InMemoryFile(content2, "aasx/Document/docu2.pdf"); + fileList.add(file); + } + + @Test + public void testBuildAASX() throws IOException, TransformerException, ParserConfigurationException, InvalidFormatException, SAXException { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out); + validateAASX(out); + } + + @Test + public void testFilePathsAreCorrectlyChanged() throws IOException, TransformerException, ParserConfigurationException, InvalidFormatException, SAXException { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out); + + Set aasBundle = deserializeAASX(out); + assertFilepathsAreCorrect(aasBundle); + } + + private void validateAASX(ByteArrayOutputStream byteStream) throws IOException { + ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(byteStream.toByteArray())); + ZipEntry zipEntry = null; + + ArrayList filePaths = new ArrayList<>(); + + while ((zipEntry = in.getNextEntry()) != null) { + if (isExpectedXMLPath(zipEntry)) { + assertIsXML(in); + } + filePaths.add(zipEntry.getName()); + } + + assertTrue(filePaths.contains(XML_PATH)); + assertTrue(filePaths.contains(ORIGIN_PATH)); + assertExpectedFileElementsArePresent(filePaths); + } + + private void assertExpectedFileElementsArePresent(List filePaths) { + fileList.stream().forEach(file -> assertFilePathsContainFile(filePaths, file)); + assertFilePathsDoNotContainExternalFileURL(filePaths); + } + + private void assertFilePathsDoNotContainExternalFileURL(List filePaths) { + String strippedExternalFileURL = VABPathTools.stripSlashes(EXTERNAL_FILE_URL); + assertFalse(filePaths.contains(strippedExternalFileURL)); + } + + private void assertFilePathsContainFile(List filePaths, InMemoryFile file) { + String strippedPath = VABPathTools.stripSlashes(file.getPath()); + assertTrue(filePaths.contains(strippedPath)); + } + + private boolean isExpectedXMLPath(ZipEntry zipEntry) { + return zipEntry.getName().equals(XML_PATH); + } + + private void assertIsXML(ZipInputStream in) throws IOException { + byte[] buf = new byte[5]; + in.read(buf); + assertEquals(" deserializeAASX(ByteArrayOutputStream byteStream) throws IOException, InvalidFormatException, ParserConfigurationException, SAXException { + InputStream in = new ByteArrayInputStream(byteStream.toByteArray()); + + AASXToMetamodelConverter aasxDeserializer = new AASXToMetamodelConverter(in); + return aasxDeserializer.retrieveAASBundles(); + } + + private void assertFilepathsAreCorrect(Set aasBundles) { + AASBundle aasBundle = extractedAASBundleFromAASBundleSet(aasBundles, aas.getIdentification()); + Set deserializedSubmodels = aasBundle.getSubmodels(); + + ISubmodel deserializedSm1 = extractSubmodelFromSubmodelSet(deserializedSubmodels, sm1.getIdentification()); + ISubmodel deserializedSm2 = extractSubmodelFromSubmodelSet(deserializedSubmodels, sm2.getIdentification()); + + ISubmodelElementCollection deserializedCollection = (ISubmodelElementCollection) deserializedSm1.getSubmodelElement(COLLECTION_ID_SHORT); + + IFile deserializedFile1 = (IFile) deserializedSm1.getSubmodelElement(FILE_ID_SHORT_1); + IFile deserializedFile2 = (IFile) deserializedCollection.getSubmodelElement(FILE_ID_SHORT_2); + IFile deserializedFile3 = (IFile) deserializedSm2.getSubmodelElement(FILE_ID_SHORT_3); + + assertEquals(EXTERNAL_FILE_URL, deserializedFile1.getValue()); + assertEquals(harmonizePrefixSlash(INTERNAL_FILE_PATH_1), deserializedFile2.getValue()); + assertEquals(harmonizePrefixSlash(INTERNAL_FILE_PATH_2), deserializedFile3.getValue()); + } + + private AASBundle extractedAASBundleFromAASBundleSet(Set aasBundles, IIdentifier identifier) { + return aasBundles.stream().filter(aasB -> aasB.getAAS().getIdentification().equals(identifier)).findAny().get(); + } + + private Object harmonizePrefixSlash(String path) { + return path.startsWith("/") ? path : "/" + path; + } + + private ISubmodel extractSubmodelFromSubmodelSet(Set submodelSet, IIdentifier identifier) { + return submodelSet.stream().filter(sm -> sm.getIdentification().equals(identifier)).findAny().get(); + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestSubmodelFileEndpointerLoader.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestSubmodelFileEndpointerLoader.java new file mode 100644 index 00000000..604c0779 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestSubmodelFileEndpointerLoader.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.factory.aasx; + +import static org.junit.Assert.assertEquals; + +import java.util.Map; + +import org.eclipse.basyx.aas.factory.aasx.SubmodelFileEndpointLoader; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests the SubmodelFileEndpointLoader + * + * @author espen + * + */ +public class TestSubmodelFileEndpointerLoader { + private Submodel submodel; + private static final String RELATIVE_PATH = "/file/root/text.txt"; + private static final String ABOSLUTE_PATH = "http://localhost:1234/file/root/text.txt"; + private static final String RELATIVE_TARGET_PATH = "http://localhost:4321/new/file/root/text.txt"; + + @Before + public void setup() { + File fRel = new File(RELATIVE_PATH, "application/json"); + fRel.setIdShort("fRel"); + File fAbs = new File(ABOSLUTE_PATH, "application/json"); + fAbs.setIdShort("fAbs"); + SubmodelElementCollection col = new SubmodelElementCollection(); + col.setIdShort("fileCollection"); + File fCol = new File(RELATIVE_PATH, "application/json"); + fCol.setIdShort("fInside"); + col.addSubmodelElement(fCol); + submodel = new Submodel("FileTestSubmodel", new Identifier(IdentifierType.IRDI, "FileTestSubmodel")); + submodel.addSubmodelElement(fRel); + submodel.addSubmodelElement(fAbs); + submodel.addSubmodelElement(col); + } + + /** + * Tests setting a static string endpoint (relative to the given path in the + * existing value) + */ + @Test + public void testRelativePaths1() { + SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "http://localhost:4321/new"); + checkRelativeTargetPaths(); + } + + /** + * Tests setting a endpoint via host, port and root path (relative to the given + * path in the existing value) + */ + @Test + public void testRelativePaths2() { + SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "localhost", 4321, "/new"); + checkRelativeTargetPaths(); + } + + /** + * Tests elements inside of collections + */ + @Test + public void testCollections() { + SubmodelFileEndpointLoader.setRelativeFileEndpoints(submodel, "localhost", 4321, "/new"); + + Map elements = submodel.getSubmodelElements(); + SubmodelElementCollection col = (SubmodelElementCollection) elements.get("fileCollection"); + IFile file = (IFile) col.getSubmodelElements().get("fInside"); + assertEquals(RELATIVE_TARGET_PATH, file.getValue()); + } + + private void checkRelativeTargetPaths() { + Map elements = submodel.getSubmodelElements(); + + String fromRelative = ((IFile) elements.get("fRel")).getValue(); + assertEquals(RELATIVE_TARGET_PATH, fromRelative); + + String fromAbsolute = ((IFile) elements.get("fAbs")).getValue(); + assertEquals(RELATIVE_TARGET_PATH, fromAbsolute); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java index b72744cf..99764ad8 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/json/TestJSONConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.factory.json; @@ -35,95 +50,91 @@ public class TestJSONConverter { private String jsonPath = "src/test/resources/aas/factory/json/aasJsonSchemaV2.0.1_Example.json"; - + private JSONToMetamodelConverter converter; - + @Before public void buildConverter() throws IOException { String json = new String(Files.readAllBytes(Paths.get(jsonPath))); converter = new JSONToMetamodelConverter(json); } - + @Test public void testParseAAS() { checkAASs(converter.parseAAS()); } - + @Test public void testParseSubmodels() { - checkSubmodels(converter.parseSubmodels()); + checkSubmodels(converter.parseSubmodels()); } - + @Test public void testParseAssets() { checkAssets(converter.parseAssets()); } - + @Test public void testParseConceptDescriptions() { checkConceptDescriptions(converter.parseConceptDescriptions()); } - + @Test public void testBuildJSON() { - + // Read Metamodel-Objects from JSON-File List aasList = converter.parseAAS(); List assetList = converter.parseAssets(); List conceptDescriptionList = converter.parseConceptDescriptions(); List submodelList = converter.parseSubmodels(); - + // Convert Metamodel-Objects to JSON String json = MetamodelToJSONConverter.convertToJSON(aasList, assetList, conceptDescriptionList, submodelList); - + // Convert new JSON back to Metamodel-Objects to check them JSONToMetamodelConverter converter2 = new JSONToMetamodelConverter(json); - + // Check if the Metamodel-Objects are still correct checkAASs(converter2.parseAAS()); checkAssets(converter2.parseAssets()); checkConceptDescriptions(converter2.parseConceptDescriptions()); checkSubmodels(converter2.parseSubmodels()); } - - private void checkAASs(List aasList) { assertEquals(1, aasList.size()); AssetAdministrationShell aas = aasList.get(0); - + assertEquals("ExampleMotor", aas.getIdShort()); assertEquals(3, aas.getSubmodelReferences().size()); assertEquals("http://customer.com/aas/9175_7013_7091_9168", aas.getIdentification().getId()); } - + private void checkSubmodels(List smList) { assertEquals(3, smList.size()); - + Submodel sm = smList.stream().filter(c -> c.getIdShort().equals("TechnicalData")).findAny().get(); - + assertEquals(1, sm.getSubmodelElements().size()); - + Property smElement = (Property) sm.getSubmodelElements().get("MaxRotationSpeed"); assertEquals("5000", smElement.getValue()); } - + private void checkAssets(List assetList) { assertEquals(1, assetList.size()); Asset asset = assetList.get(0); - + assertEquals("ServoDCMotor", asset.getIdShort()); assertEquals("http://customer.com/assets/KHBVZJSQKIY", asset.getIdentification().getId()); } - + private void checkConceptDescriptions(List conceptDescriptionList) { assertEquals(5, conceptDescriptionList.size()); - - ConceptDescription cd = conceptDescriptionList.stream() - .filter(c -> c.getIdShort().equals("DigitalFile")).findAny().get(); - - assertEquals("www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile", - cd.getIdentification().getId()); + + ConceptDescription cd = conceptDescriptionList.stream().filter(c -> c.getIdShort().equals("DigitalFile")).findAny().get(); + + assertEquals("www.vdi2770.com/blatt1/Entwurf/Okt18/cd/StoredDocumentRepresentation/DigitalFile", cd.getIdentification().getId()); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestAASXPackageExplorerCompatibility.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestAASXPackageExplorerCompatibility.java new file mode 100644 index 00000000..102ab719 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestAASXPackageExplorerCompatibility.java @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.aas.factory.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +import org.eclipse.basyx.aas.factory.xml.XMLToMetamodelConverter; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.junit.Test; + +/** + * This tests the workarounds implemented in XML deserialization to handle .xml + * files generated by the AASXPackageExplorer + * + * @author conradi + * + */ +public class TestAASXPackageExplorerCompatibility { + + private String xmlInWorkaroundsPath = "src/test/resources/aas/factory/xml/inWorkarounds.xml"; + + @Test + public void testAASXPackageExplorerWorkarounds() throws Exception { + String xml = new String(Files.readAllBytes(Paths.get(xmlInWorkaroundsPath))); + XMLToMetamodelConverter converter = new XMLToMetamodelConverter(xml); + List assetList = converter.parseAssets(); + List submodelList = converter.parseSubmodels(); + + assertEquals(1, assetList.size()); + IAsset asset = assetList.iterator().next(); + checkAsset(asset); + + assertEquals(1, submodelList.size()); + ISubmodel sm = submodelList.iterator().next(); + checkOperation(sm); + } + + private void checkOperation(ISubmodel sm) { + Operation op = (Operation) sm.getSubmodelElement("operation_ID"); + assertNotNull(op); + assertEquals(2, op.getInputVariables().size()); + assertEquals(1, op.getOutputVariables().size()); + } + + private void checkAsset(IAsset asset) { + assertEquals(asset.getAssetKind(), AssetKind.TYPE); + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java index 6f270534..14784f60 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/xml/TestXMLConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.factory.xml; @@ -79,9 +94,9 @@ public class TestXMLConverter { private String xmlInPath = "src/test/resources/aas/factory/xml/in.xml"; private String xmlInExternalAllowedPath = "src/test/resources/aas/factory/xml/inExternalAllowed.xml"; - + private XMLToMetamodelConverter converter; - + @Before public void buildConverter() throws Exception { String xml = new String(Files.readAllBytes(Paths.get(xmlInPath))); @@ -92,76 +107,75 @@ public void buildConverter() throws Exception { public void testParseAAS() throws Exception { checkAASs(converter.parseAAS()); } - + @Test public void testParseAssets() throws Exception { checkAssets(converter.parseAssets()); } - + @Test public void testParseConceptDescriptions() { checkConceptDescriptions(converter.parseConceptDescriptions()); } - + @Test public void testParseSubmodels() { checkSubmodels(converter.parseSubmodels()); } - + @Test public void testBuildXML() throws Exception { - //Convert the in.xml to Objects + // Convert the in.xml to Objects List assetAdministrationShellList = converter.parseAAS(); List assetList = converter.parseAssets(); List conceptDescriptionList = converter.parseConceptDescriptions(); List submodelList = converter.parseSubmodels(); - - //Build XML-File from the Objects and write it to a StringWriter + + // Build XML-File from the Objects and write it to a StringWriter StringWriter resultWithTypes = new StringWriter(); MetamodelToXMLConverter.convertToXML(assetAdministrationShellList, assetList, conceptDescriptionList, submodelList, new StreamResult(resultWithTypes)); - - - //Read the content of the StringWriter, convert it into Objects and check them + + // Read the content of the StringWriter, convert it into Objects and check them XMLToMetamodelConverter converterWithTypes = new XMLToMetamodelConverter(resultWithTypes.toString()); - + checkAASs(converterWithTypes.parseAAS()); checkAssets(converterWithTypes.parseAssets()); checkConceptDescriptions(converterWithTypes.parseConceptDescriptions()); checkSubmodels(converterWithTypes.parseSubmodels()); - - //erase the types of the Objects, that they are plain Maps as if they were transferred over the VAB + + // erase the types of the Objects, that they are plain Maps as if they were + // transferred over the VAB List iAssetAdministrationShellList = destroyAASTypes(assetAdministrationShellList); List iAssetList = destroyAssetTypes(assetList); List iConceptDescriptionList = destroyConceptDescriptionTypes(conceptDescriptionList); List iSubmodelList = destroySubmodelTypes(submodelList); - - //Build XML-File from the Objects and write it to a StringWriter + + // Build XML-File from the Objects and write it to a StringWriter StringWriter resultWithoutTypes = new StringWriter(); MetamodelToXMLConverter.convertToXML(iAssetAdministrationShellList, iAssetList, iConceptDescriptionList, iSubmodelList, new StreamResult(resultWithoutTypes)); - - - //Read the content of the StringWriter, convert it into Objects and check them + + // Read the content of the StringWriter, convert it into Objects and check them XMLToMetamodelConverter converterWithoutTypes = new XMLToMetamodelConverter(resultWithoutTypes.toString()); - + checkAASs(converterWithoutTypes.parseAAS()); checkAssets(converterWithoutTypes.parseAssets()); checkConceptDescriptions(converterWithoutTypes.parseConceptDescriptions()); checkSubmodels(converterWithoutTypes.parseSubmodels()); } - + @SuppressWarnings("unchecked") @Test public void testBuildExternalAllowedXML() throws Exception { String xml = new String(Files.readAllBytes(Paths.get(xmlInExternalAllowedPath))); converter = new XMLToMetamodelConverter(xml); - //Convert the in.xml to Objects + // Convert the in.xml to Objects List assetAdministrationShellList = converter.parseAAS(); List assetList = converter.parseAssets(); List conceptDescriptionList = converter.parseConceptDescriptions(); List submodelList = converter.parseSubmodels(); - + IAssetAdministrationShell secondShell = assetAdministrationShellList.get(1); - + assertEquals("", secondShell.getIdShort()); IIdentifier identifier = secondShell.getIdentification(); assertEquals(IdentifierType.CUSTOM, identifier.getIdType()); @@ -169,60 +183,60 @@ public void testBuildExternalAllowedXML() throws Exception { IKey key = secondShell.getAssetReference().getKeys().get(0); assertEquals(KeyElements.REFERENCEELEMENT, key.getType()); assertEquals(KeyType.IRI, key.getIdType()); - + IAsset asset = assetList.get(1); assertEquals(IdentifierType.IRI, asset.getIdentification().getIdType()); - + IProperty property1 = submodelList.get(0).getProperties().get("rotationSpeed"); assertEquals(ValueType.AnySimpleType, property1.getValueType()); IProperty property2 = submodelList.get(0).getProperties().get("emptyDouble"); assertEquals(ValueType.AnyURI, property2.getValueType()); - + IProperty property3 = submodelList.get(0).getProperties().get("emptyDouble2"); assertEquals(ValueType.DateTime, property3.getValueType()); - + IRange range = Range.createAsFacade((Map) submodelList.get(0).getSubmodelElement("range_id")); assertEquals(ValueType.Double, range.getValueType()); - + IOperation operation = Operation.createAsFacade((Map) submodelList.get(0).getSubmodelElement("operation_ID")); - assertEquals(ModelingKind.TEMPLATE, operation.getInOutputVariables().iterator().next().getValue().getModelingKind()); - + assertEquals(ModelingKind.TEMPLATE, operation.getInOutputVariables().iterator().next().getValue().getKind()); + IDataSpecificationContent content = conceptDescriptionList.get(0).getEmbeddedDataSpecifications().iterator().next().getContent(); DataSpecificationIEC61360Content parsed = DataSpecificationIEC61360Content.createAsFacade((Map) content); - assertEquals("Only Description", parsed.getShortName().get("EN")); + assertEquals("Only Description", parsed.getShortName().get("EN")); } - + private void checkAASs(List aasList) { assertEquals(2, aasList.size()); - + IAssetAdministrationShell aas = null; - - //select the AAS with a specific ID form the list - for(IAssetAdministrationShell shell: aasList) { - if(shell.getIdShort().equals("asset_admin_shell")) { + + // select the AAS with a specific ID form the list + for (IAssetAdministrationShell shell : aasList) { + if (shell.getIdShort().equals("asset_admin_shell")) { aas = shell; break; } } - + assertNotNull(aas); - + assertEquals("asset_admin_shell", aas.getIdShort()); assertEquals("test_category", aas.getCategory()); assertEquals("aas_parent_id", aas.getParent().getKeys().get(0).getValue()); - + assertEquals("aas_Description", aas.getDescription().get("EN")); assertEquals("Beschreibung Verwaltungsschale", aas.getDescription().get("DE")); - + assertEquals("www.admin-shell.io/aas-sample/1/0", aas.getIdentification().getId()); assertEquals(IdentifierType.IRI, aas.getIdentification().getIdType()); checkDefaultEmbeddedDataSpecification(aas); - + assertEquals("1", aas.getAdministration().getVersion()); assertEquals("0", aas.getAdministration().getRevision()); - + Collection conceptDictionary = aas.getConceptDictionary(); for (IConceptDictionary iConceptDictionary : conceptDictionary) { assertEquals("SampleDic", iConceptDictionary.getIdShort()); @@ -248,7 +262,7 @@ private void checkAASs(List aasList) { } // Test submodel reference retrieval - + // Select submodel reference's key IKey submodelKey = null; boolean foundFirst = false, foundSecond = false; @@ -273,12 +287,12 @@ private void checkAASs(List aasList) { assertEquals(KeyType.IRI, submodelKey.getIdType()); assertEquals(KeyElements.SUBMODEL, submodelKey.getType()); assertEquals(true, submodelKey.isLocal()); - + // Test view retrieval Object[] views = aas.getViews().toArray(); assertEquals(2, views.length); IView iView = (IView) views[0]; - if(!iView.getIdShort().equals("SampleView")) + if (!iView.getIdShort().equals("SampleView")) iView = (IView) views[1]; assertEquals("SampleView", iView.getIdShort()); checkDefaultEmbeddedDataSpecification(iView); @@ -298,7 +312,7 @@ private void checkAASs(List aasList) { assertEquals("rotationSpeed", key1.getValue()); assertEquals(true, key1.isLocal()); } - + private void checkDefaultEmbeddedDataSpecification(IHasDataSpecification hasDataSpecification) { Collection embeddedSpecs = hasDataSpecification.getEmbeddedDataSpecifications(); IEmbeddedDataSpecification embeddedSpec = embeddedSpecs.iterator().next(); @@ -308,8 +322,7 @@ private void checkDefaultEmbeddedDataSpecification(IHasDataSpecification hasData @SuppressWarnings("unchecked") private void checkDefaultDataSpecificationContent(IDataSpecificationContent content) { - DataSpecificationIEC61360Content iecContent = DataSpecificationIEC61360Content - .createAsFacade((Map) content); + DataSpecificationIEC61360Content iecContent = DataSpecificationIEC61360Content.createAsFacade((Map) content); LangStrings preferredName = iecContent.getPreferredName(); assertEquals("Drehzahl", preferredName.get("DE")); assertEquals("Rotation Speed", preferredName.get("EN")); @@ -336,15 +349,15 @@ private void checkDefaultDataSpecificationReference(IReference dataSpecRef) { private void checkAssets(List assets) { assertEquals(2, assets.size()); IAsset asset = null; - - //select the Asset with a specific ID form the list - for(IAsset a: assets) { - if(a.getIdShort().equals("3s7plfdrs35_asset1")) { + + // select the Asset with a specific ID form the list + for (IAsset a : assets) { + if (a.getIdShort().equals("3s7plfdrs35_asset1")) { asset = a; break; } } - + assertNotNull(asset); checkDefaultEmbeddedDataSpecification(asset); assertEquals("3s7plfdrs35_asset1", asset.getIdShort()); @@ -353,35 +366,35 @@ private void checkAssets(List assets) { assertEquals("Type", asset.getAssetKind().toString()); assertEquals("www.festo.com/dic/08111234", asset.getAssetIdentificationModel().getKeys().get(0).getValue()); } - + private void checkConceptDescriptions(List conceptDescriptions) { assertEquals(2, conceptDescriptions.size()); IConceptDescription conceptDescription = conceptDescriptions.get(0); - - //make sure to select the correct ConceptDescription1 from the list - //as there is no order given by the XML file - if(!conceptDescription.getIdShort().equals("conceptDescription1")) + + // make sure to select the correct ConceptDescription1 from the list + // as there is no order given by the XML file + if (!conceptDescription.getIdShort().equals("conceptDescription1")) conceptDescription = conceptDescriptions.get(1); - + assertEquals("conceptDescription1", conceptDescription.getIdShort()); assertEquals("conceptDescription_Description", conceptDescription.getDescription().get("EN")); assertEquals("www.festo.com/dic/08111234", conceptDescription.getIdentification().getId()); Collection refs = conceptDescription.getIsCaseOf(); assertEquals(1, refs.size()); } - + private void checkSubmodels(List submodels) { assertEquals(2, submodels.size()); ISubmodel submodel = null; - - //select the Submodel with a specific ID form the list - for(ISubmodel s: submodels) { - if(s.getIdShort().equals("3s7plfdrs35_submodel1")) { + + // select the Submodel with a specific ID form the list + for (ISubmodel s : submodels) { + if (s.getIdShort().equals("3s7plfdrs35_submodel1")) { submodel = s; break; } } - + assertNotNull(submodel); checkDefaultEmbeddedDataSpecification(submodel); assertEquals("3s7plfdrs35_submodel1", submodel.getIdShort()); @@ -389,13 +402,12 @@ private void checkSubmodels(List submodels) { assertEquals(4, constraints.size()); checkSubmodelElements(submodel); } - + @SuppressWarnings("unchecked") private void checkSubmodelElements(ISubmodel submodel) { - Map submodelElements = (Map) - ((Map)submodel).get(Submodel.SUBMODELELEMENT); - assertEquals(14, submodelElements.size()); - + Map submodelElements = (Map) ((Map) submodel).get(Submodel.SUBMODELELEMENT); + assertEquals(14, submodelElements.size()); + ISubmodelElement element = submodelElements.get("rotationSpeed"); assertTrue(element instanceof Property); Property property = (Property) element; @@ -406,12 +418,12 @@ private void checkSubmodelElements(ISubmodel submodel) { assertEquals(2000.0, property.getValue()); assertEquals(ValueType.Double, property.getValueType()); assertEquals("rotationSpeed", property.getIdShort()); - + element = submodelElements.get("emptyDouble"); assertTrue(element instanceof Property); property = (Property) element; assertEquals(ValueType.Double, property.getValueType()); - + element = submodelElements.get("basic_event_id"); assertTrue(element instanceof BasicEvent); BasicEvent basicEvent = (BasicEvent) element; @@ -421,7 +433,7 @@ private void checkSubmodelElements(ISubmodel submodel) { element = submodelElements.get("capability_id"); assertTrue(element instanceof Capability); - + element = submodelElements.get("entity_id"); assertTrue(element instanceof Entity); Entity entity = (Entity) element; @@ -429,7 +441,7 @@ private void checkSubmodelElements(ISubmodel submodel) { Collection statements = entity.getStatements(); assertEquals(2, statements.size()); assertTrue(statements.stream().allMatch(s -> s instanceof File || s instanceof Range)); - + element = submodelElements.get("multi_language_property_id"); assertTrue(element instanceof MultiLanguageProperty); MultiLanguageProperty mLProperty = (MultiLanguageProperty) element; @@ -440,33 +452,33 @@ private void checkSubmodelElements(ISubmodel submodel) { assertEquals(2, langStrings.size()); assertEquals("Eine Beschreibung auf deutsch", langStrings.get("de")); assertEquals("A description in english", langStrings.get("en")); - + element = submodelElements.get("range_id"); assertTrue(element instanceof Range); Range range = (Range) element; assertEquals(ValueType.Integer, range.getValueType()); assertEquals("1", range.getMin()); assertEquals("10", range.getMax()); - + element = submodelElements.get("file_id"); assertTrue(element instanceof File); File file = (File) element; assertEquals("file_mimetype", file.getMimeType()); assertEquals("file_value", file.getValue()); - + element = submodelElements.get("blob_id"); assertTrue(element instanceof Blob); Blob blob = (Blob) element; assertEquals("blob_mimetype", blob.getMimeType()); assertEquals("YmxvYit2YWx1ZQ==", blob.getValue()); - + element = submodelElements.get("reference_ELE_ID"); assertTrue(element instanceof ReferenceElement); ReferenceElement refElem = (ReferenceElement) element; keys = refElem.getValue().getKeys(); assertEquals(1, keys.size()); assertEquals("0173-1#05-AAA650#002", keys.get(0).getValue()); - + element = submodelElements.get("submodelElementCollection_ID"); assertTrue(element instanceof SubmodelElementCollection); SubmodelElementCollection smCollection = (SubmodelElementCollection) element; @@ -474,7 +486,7 @@ private void checkSubmodelElements(ISubmodel submodel) { assertEquals(2, elements.size()); assertTrue(smCollection.isAllowDuplicates()); assertFalse(smCollection.isOrdered()); - + element = submodelElements.get("relationshipElement_ID"); assertTrue(element instanceof RelationshipElement); RelationshipElement relElem = (RelationshipElement) element; @@ -484,7 +496,7 @@ private void checkSubmodelElements(ISubmodel submodel) { keys = relElem.getSecond().getKeys(); assertEquals(1, keys.size()); assertEquals("0173-1#05-AAA650#002", keys.get(0).getValue()); - + element = submodelElements.get("annotatedRelationshipElement_ID"); assertTrue(element instanceof AnnotatedRelationshipElement); AnnotatedRelationshipElement annotatedElem = (AnnotatedRelationshipElement) element; @@ -496,10 +508,10 @@ private void checkSubmodelElements(ISubmodel submodel) { assertEquals("0173-1#05-AAA650#004", keys.get(0).getValue()); Collection annotations = annotatedElem.getValue().getAnnotations(); assertEquals(2, annotations.size()); - for(IDataElement annotationElement: annotations) { + for (IDataElement annotationElement : annotations) { assertTrue(annotationElement instanceof Property); } - + element = submodelElements.get("operation_ID"); assertTrue(element instanceof Operation); Operation op = (Operation) element; @@ -514,42 +526,42 @@ private void checkSubmodelElements(ISubmodel submodel) { o = inout.iterator().next().getValue(); assertTrue(o instanceof ReferenceElement); } - + @SuppressWarnings("unchecked") private List destroyAASTypes(List aasList) { List ret = new ArrayList<>(); - for(IAssetAdministrationShell aas: aasList) { + for (IAssetAdministrationShell aas : aasList) { ret.add(AssetAdministrationShell.createAsFacade(TypeDestroyer.destroyType((Map) aas))); } return ret; } - + @SuppressWarnings("unchecked") private List destroySubmodelTypes(List submodelList) { List ret = new ArrayList<>(); - for(ISubmodel submodel: submodelList) { + for (ISubmodel submodel : submodelList) { ret.add(Submodel.createAsFacade(new VABModelMap<>(TypeDestroyer.destroyType((Map) submodel)))); } return ret; } - + @SuppressWarnings("unchecked") private List destroyAssetTypes(List assetList) { List ret = new ArrayList<>(); - for(IAsset asset: assetList) { + for (IAsset asset : assetList) { ret.add(Asset.createAsFacade(TypeDestroyer.destroyType((Map) asset))); } return ret; } - + @SuppressWarnings("unchecked") private List destroyConceptDescriptionTypes(List cdList) { List ret = new ArrayList<>(); - for(IConceptDescription cd: cdList) { + for (IConceptDescription cd : cdList) { ret.add(ConceptDescription.createAsFacade(TypeDestroyer.destroyType((Map) cd))); } return ret; } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java index a4c467ca..06328f77 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestAASHTTP.java @@ -1,17 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.manager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import java.util.List; import java.util.Map; import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager; @@ -24,7 +41,10 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.testsuite.regression.aas.restapi.StubAASServlet; +import org.eclipse.basyx.testsuite.regression.submodel.restapi.SimpleAASSubmodel; import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource; +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; +import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory; import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext; import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry; @@ -43,8 +63,7 @@ public class TestAASHTTP { // Manager used to connect to the AAS ConnectedAssetAdministrationShellManager manager; - private static BaSyxContext context = new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")) - .addServletMapping("/Testsuite/StubAAS/*", new StubAASServlet()); + private static BaSyxContext context = new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")).addServletMapping("/Testsuite/StubAAS/*", new StubAASServlet()); /** * Makes sure Tomcat Server is started @@ -60,25 +79,22 @@ public void build() { // Fill directory stub VABInMemoryRegistry directory = new VABInMemoryRegistry(); directory.addMapping(StubAASServlet.AASURN.getId(), "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas"); - directory.addMapping(StubAASServlet.SMURN.getId(), - "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel"); + directory.addMapping(StubAASServlet.SMURN.getId(), "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel"); InMemoryRegistry registry = new InMemoryRegistry(); // Create aas descriptor for the aas registry - AASDescriptor aasDescriptor = new AASDescriptor(StubAASServlet.AASURN, - "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas"); + AASDescriptor aasDescriptor = new AASDescriptor(StubAASServlet.AASURN, "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas"); // Create the submodel descriptor - SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(StubAASServlet.SMIDSHORT, StubAASServlet.SMURN, - "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel"); + SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(StubAASServlet.SMIDSHORT, StubAASServlet.SMURN, "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel"); // add submodel descriptor to the aas descriptor aasDescriptor.addSubmodelDescriptor(submodelDescriptor); // register the aas in the registry registry.register(aasDescriptor); - + // Create manager using the directory stub an the HTTPConnectorProvider manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorFactory()); } @@ -129,7 +145,29 @@ public void testSubmodel() throws Exception { assertEquals(4, operations.size()); IOperation op = operations.get("complex"); - assertEquals(1, op.invoke(2, 1)); + assertEquals(1, op.invokeSimple(2, 1)); + + op = operations.get("exception1"); + try { + op.invokeSimple(); + fail(); + } catch (ProviderException e) { + List msg = e.getMessages(); + assertEquals(2, msg.size()); + String msgText = msg.get(1).getText(); + assertTrue(msgText.contains("ProviderException: " + NullPointerException.class.getName())); + } + + op = operations.get("exception2"); + try { + op.invokeSimple(); + fail(); + } catch (ProviderException e) { + List msg = e.getMessages(); + assertEquals(2, msg.size()); + String msgText = msg.get(1).getText(); + assertTrue(msgText.contains("ProviderException: " + SimpleAASSubmodel.EXCEPTION_MESSAGE)); + } Map elements = sm.getSubmodelElements(); // 2 properties, 4 operations, 1 collection diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java index 5b9d9bfa..be6df7bd 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/manager/TestConnectedAssetAdministrationShellManager.java @@ -1,18 +1,36 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.manager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.util.Collection; + import org.eclipse.basyx.aas.aggregator.AASAggregator; import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager; @@ -37,6 +55,7 @@ import org.eclipse.basyx.testsuite.regression.vab.gateway.ConnectorProviderStub; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; +import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.junit.Before; import org.junit.Test; @@ -45,13 +64,13 @@ * Tests ConnectedAssetAdministrationShellManager class * * @author schnicke - * + * */ public class TestConnectedAssetAdministrationShellManager { ConnectedAssetAdministrationShellManager manager; ConnectorProviderStub connectorProvider; IAASRegistry registry; - + /** * Create infrastructure */ @@ -76,14 +95,14 @@ public void testCreateAAS() throws Exception { String aasIdShort = "aasName"; IModelProvider provider = new AASAggregatorProvider(new AASAggregator()); prepareConnectorProvider(provider); - + // Create an AAS containing a reference to the created Submodel AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort); - manager.createAAS(aas, "/shells"); + manager.createAAS(aas, ""); // Check descriptor for correct endpoint String endpoint = registry.lookupAAS(aasId).getFirstEndpoint(); - assertEquals(AASAggregatorProvider.PREFIX + "/" + aasId.getId() + "/aas", endpoint); + assertEquals(AASAggregatorProvider.PREFIX + "/" + aasId.getId() + "/aas", VABPathTools.stripSlashes(endpoint)); // Retrieve it ConnectedAssetAdministrationShell connectedAAS = manager.retrieveAAS(aasId); @@ -92,7 +111,6 @@ public void testCreateAAS() throws Exception { assertEquals(aasId.getIdType(), connectedAAS.getIdentification().getIdType()); } - @Test public void testCreateSubmodel() throws Exception { IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId"); @@ -143,12 +161,12 @@ public void testDeleteSubmodel() { IIdentifier smId = new Identifier(IdentifierType.CUSTOM, "smId"); String smIdShort = "smName"; - + IModelProvider provider = new AASAggregatorProvider(new AASAggregator()); prepareConnectorProvider(provider); AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort); - manager.createAAS(aas, "/shells"); + manager.createAAS(aas, ""); Submodel sm = new Submodel(smIdShort, smId); manager.createSubmodel(aasId, sm); @@ -172,7 +190,7 @@ public void testDeleteAAS() { prepareConnectorProvider(provider); AssetAdministrationShell aas = createTestAAS(aasId, aasIdShort); - manager.createAAS(aas, "/shells"); + manager.createAAS(aas, ""); manager.deleteAAS(aas.getIdentification()); try { manager.retrieveAAS(aas.getIdentification()); @@ -182,6 +200,28 @@ public void testDeleteAAS() { } } + @Test + public void testRetrieveAll() { + IIdentifier aasId1 = new Identifier(IdentifierType.CUSTOM, "aasId1"); + String aasIdShort1 = "aasName1"; + IIdentifier aasId2 = new Identifier(IdentifierType.CUSTOM, "aasId2"); + String aasIdShort2 = "aasName2"; + + IModelProvider provider = new AASAggregatorProvider(new AASAggregator()); + prepareConnectorProvider(provider); + + // Create the AASs + AssetAdministrationShell aas1 = createTestAAS(aasId1, aasIdShort1); + AssetAdministrationShell aas2 = createTestAAS(aasId2, aasIdShort2); + manager.createAAS(aas1, ""); + manager.createAAS(aas2, ""); + + // Retrieve them + Collection connectedAASs = manager.retrieveAASAll(); + assertEquals(2, connectedAASs.size()); + connectedAASs.stream().forEach(aas -> assertTrue(aas.getIdShort().equals(aasIdShort1) || aas.getIdShort().equals(aasIdShort2))); + } + /** * Tries to retrieve a nonexistent AAS */ @@ -189,9 +229,9 @@ public void testDeleteAAS() { public void testRetrieveNonexistentAAS() { IModelProvider provider = new AASAggregatorProvider(new AASAggregator()); prepareConnectorProvider(provider); - + IIdentifier nonexistentAASId = new Identifier(IdentifierType.CUSTOM, "nonexistentAAS"); - + // Try to retrieve a nonexistent AAS try { manager.retrieveAAS(nonexistentAASId); @@ -199,7 +239,7 @@ public void testRetrieveNonexistentAAS() { } catch (ResourceNotFoundException e) { } } - + /** * Tries to retrieve a nonexistent Submodel from a nonexistent AAS */ @@ -207,10 +247,10 @@ public void testRetrieveNonexistentAAS() { public void testRetrieveNonexistentSMFromNonexistentSM() { IModelProvider provider = new AASAggregatorProvider(new AASAggregator()); prepareConnectorProvider(provider); - + IIdentifier nonexistentAASId = new Identifier(IdentifierType.CUSTOM, "nonexistentAAS"); IIdentifier nonexistentSMId = new Identifier(IdentifierType.CUSTOM, "nonexistentSM"); - + // Try to retrieve a nonexistent Submodel from a nonexistent AAS try { manager.retrieveSubmodel(nonexistentAASId, nonexistentSMId); @@ -218,7 +258,7 @@ public void testRetrieveNonexistentSMFromNonexistentSM() { } catch (ResourceNotFoundException e) { } } - + /** * Tries to retrieve a nonexistent Submodel from an existing AAS */ @@ -226,10 +266,10 @@ public void testRetrieveNonexistentSMFromNonexistentSM() { public void testRetrieveNonexistentSMFromExistentAAS() { IModelProvider provider = new AASAggregatorProvider(new AASAggregator()); prepareConnectorProvider(provider); - + IIdentifier aasId = new Identifier(IdentifierType.CUSTOM, "aasId"); IIdentifier nonexistentSMId = new Identifier(IdentifierType.CUSTOM, "nonexistentSM"); - + // Try to retrieve a nonexistent Submodel from an existing AAS try { manager.retrieveSubmodel(aasId, nonexistentSMId); @@ -237,7 +277,7 @@ public void testRetrieveNonexistentSMFromExistentAAS() { } catch (ResourceNotFoundException e) { } } - + /** * @param provider */ diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java index d8aa3b32..2109099a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/AssetAdministrationShellSuite.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel; @@ -40,7 +55,6 @@ import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.junit.Test; - /** * Test suite for AAS testing.
* Can be extended to test arbitrary AAS implementations, as long as they @@ -170,7 +184,7 @@ public void testGetAdministrativeInformation() { assertEquals(EXPECTED_ADMINISTRATIVEINFORMATION.getRevision(), info.getRevision()); assertEquals(EXPECTED_ADMINISTRATIVEINFORMATION.getVersion(), info.getVersion()); } - + @Test public void testAddSubmodel() { // Create a submodel @@ -180,11 +194,11 @@ public void testAddSubmodel() { Property prop = new Property("prop1", ValueType.String); prop.setValue("testProperty"); subModel.addSubmodelElement(prop); - - //Retrieve the aas + + // Retrieve the aas IAssetAdministrationShell shell = retrieveShell(); shell.addSubmodel(subModel); - + // Create the expected reference for assertion List expected1Keys = new ArrayList<>(); expected1Keys.add(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID.getId(), AASID.getIdType())); @@ -201,5 +215,5 @@ public void testAddSubmodel() { assertTrue(smReferences.contains(expected1)); assertTrue(smReferences.contains(expected2)); assertEquals(2, smReferences.size()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java index 6c2ffca1..6b098885 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/connected/TestConnectedAssetAdministrationShell.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.connected; @@ -69,8 +84,7 @@ public void build() throws Exception { connectorProvider.addMapping("", provider); // Create connection manager using the dummy - ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry, - connectorProvider); + ConnectedAssetAdministrationShellManager manager = new ConnectedAssetAdministrationShellManager(registry, connectorProvider); // Create ConnectedAssetAdministrationShell connectedAAS = manager.retrieveAAS(AASID); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java index eb658bb2..9cf4679a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAasEnv.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map; @@ -13,7 +28,7 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; @@ -31,7 +46,6 @@ public class TestAasEnv { - @Test public void testAssetsGetSet() { AasEnv env = new AasEnv(); @@ -44,12 +58,12 @@ public void testAssetsGetSet() { @Test public void testAssetAdministrationShellGetSet() { AasEnv env = new AasEnv(); - AssetAdministrationShell ass = new AssetAdministrationShell(); - ass.setIdShort("TestAasEnv"); - env.setAssetAdministrationShells(Arrays.asList(ass)); - assertEquals(ass, env.getAssetAdministrationShells().toArray()[0]); + AssetAdministrationShell aas = new AssetAdministrationShell(); + aas.setIdShort("TestAasEnv"); + env.setAssetAdministrationShells(Arrays.asList(aas)); + assertEquals(aas, env.getAssetAdministrationShells().toArray()[0]); } - + @Test public void testConceptDescriptionsGetSet() { AasEnv env = new AasEnv(); @@ -58,7 +72,7 @@ public void testConceptDescriptionsGetSet() { env.setConceptDescriptions(Arrays.asList(conceptDescriptions)); assertEquals(conceptDescriptions, env.getConceptDescriptions().toArray()[0]); } - + @Test public void testSubmodelsGetSet() { AasEnv env = new AasEnv(); @@ -67,49 +81,47 @@ public void testSubmodelsGetSet() { env.setSubmodels(Arrays.asList(submodels)); assertEquals(submodels, env.getSubmodels().toArray()[0]); } - + @Test public void testCreateAsFacade() { - Map asset = new HashMap<>(); + Map asset = new LinkedHashMap<>(); asset.put(ModelType.MODELTYPE, Asset.MODELTYPE); asset.put(Referable.IDSHORT, "TestAsset"); asset.put(Asset.KIND, AssetKind.INSTANCE); asset.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testAssetIdShort")); - - Map assetAdministrationShell = new HashMap<>(); + + Map assetAdministrationShell = new LinkedHashMap<>(); assetAdministrationShell.put(ModelType.MODELTYPE, AssetAdministrationShell.MODELTYPE); assetAdministrationShell.put(Referable.IDSHORT, "TestAssetAdministrationShell"); assetAdministrationShell.put(AssetAdministrationShell.ASSET, asset); assetAdministrationShell.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testAASIdShort")); - - - Map submodel = new HashMap<>(); + + Map submodel = new LinkedHashMap<>(); submodel.put(ModelType.MODELTYPE, Submodel.MODELTYPE); submodel.put(Referable.IDSHORT, "TestSubmodel"); submodel.put(Submodel.SUBMODELELEMENT, new ArrayList()); submodel.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testSubmodelIdShort")); - - Map conceptDescription = new HashMap<>(); + + Map conceptDescription = new LinkedHashMap<>(); conceptDescription.put(ModelType.MODELTYPE, ConceptDescription.MODELTYPE); conceptDescription.put(Referable.IDSHORT, "TestConceptDescription"); conceptDescription.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRI, "testConceptDesIdShort")); - - - Map aasEnvAsMap = new HashMap<>(); + + Map aasEnvAsMap = new LinkedHashMap<>(); aasEnvAsMap.put(AasEnv.ASSETS, Arrays.asList(asset)); aasEnvAsMap.put(AasEnv.ASSETADMINISTRATIONSHELLS, Arrays.asList(assetAdministrationShell)); aasEnvAsMap.put(AasEnv.SUBMODELS, Arrays.asList(submodel)); aasEnvAsMap.put(AasEnv.CONCEPTDESCRIPTIONS, Arrays.asList(conceptDescription)); - + AasEnv aasEnv = AasEnv.createAsFacade(aasEnvAsMap); - - Asset assetObj = (Asset)aasEnv.getAssets().toArray()[0]; + + Asset assetObj = (Asset) aasEnv.getAssets().toArray()[0]; assertEquals(assetObj.getIdShort(), asset.get(Referable.IDSHORT)); - AssetAdministrationShell assetAdministrationShellObj = (AssetAdministrationShell)aasEnv.getAssetAdministrationShells().toArray()[0]; + AssetAdministrationShell assetAdministrationShellObj = (AssetAdministrationShell) aasEnv.getAssetAdministrationShells().toArray()[0]; assertEquals(assetAdministrationShellObj.getIdShort(), assetAdministrationShell.get(Referable.IDSHORT)); - Submodel submodelObj = (Submodel)aasEnv.getSubmodels().toArray()[0]; + Submodel submodelObj = (Submodel) aasEnv.getSubmodels().toArray()[0]; assertEquals(submodelObj.getIdShort(), submodel.get(Referable.IDSHORT)); - ConceptDescription conceptDescriptionObj = (ConceptDescription)aasEnv.getConceptDescriptions().toArray()[0]; + ConceptDescription conceptDescriptionObj = (ConceptDescription) aasEnv.getConceptDescriptions().toArray()[0]; assertEquals(conceptDescriptionObj.getIdShort(), conceptDescription.get(Referable.IDSHORT)); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java index e663d242..d7fd324d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/TestAssetAdministrationShell.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map; @@ -51,7 +66,7 @@ */ public class TestAssetAdministrationShell extends AssetAdministrationShellSuite { private static final Reference REFERENCE = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI)); - + private AssetAdministrationShell shell; /** @@ -71,14 +86,14 @@ protected AssetAdministrationShell retrieveShell() { public void testGetSubmodel() throws Exception { // Overwritten because getting submodels on local AAS is not supported } - + @Test public void testSetDataSpecificationReferences() { Collection refs = Collections.singleton(REFERENCE); shell.setDataSpecificationReferences(refs); assertEquals(refs, shell.getDataSpecificationReferences()); } - + @Test public void testSetEmbeddedDataSpecifications() { EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification(); @@ -86,20 +101,20 @@ public void testSetEmbeddedDataSpecifications() { shell.setEmbeddedDataSpecifications(specifications); assertEquals(specifications, shell.getEmbeddedDataSpecifications()); } - + @Test public void testSecurity() { Security security = new Security(); shell.setSecurity(security); assertEquals(security, shell.getSecurity()); - } - + } + @Test public void testSetParent() { shell.setParent(REFERENCE); assertEquals(REFERENCE, shell.getParent()); } - + @Test public void testAddConceptDescription() { IdentifierType idType = IdentifierType.IRI; @@ -115,7 +130,7 @@ public void testAddConceptDescription() { dictionaries.add(dictionary); assertEquals(dictionaries, shell.getConceptDictionary()); } - + @Test public void testSetSubmodels() { // Create submodels @@ -128,7 +143,7 @@ public void testSetSubmodels() { Property prop2 = new Property("prop2Id", ValueType.String); prop2.setValue("testProperty2"); subModel2.addSubmodelElement(prop2); - + // create a collection of descriptors and add the above descriptors Collection submodels = new ArrayList(); submodels.add(subModel1); @@ -150,5 +165,5 @@ public void testSetSubmodels() { assertTrue(smReferences.contains(expected1)); assertTrue(smReferences.contains(expected2)); assertEquals(2, smReferences.size()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/ModelDescriptorTestSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/ModelDescriptorTestSuite.java new file mode 100644 index 00000000..7a5f1088 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/ModelDescriptorTestSuite.java @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor; + +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelDescriptor; +import org.junit.Test; + +/** + * Test suite for Model Descriptor common method testing + * + * @author haque + * + */ +public abstract class ModelDescriptorTestSuite { + private static final String TESTENDPOINT = "dummy.com"; + private static final String TESTENDPOINT2 = "dummy2.com"; + private ModelDescriptor descriptor; + + public abstract ModelDescriptor retrieveModelDescriptor(); + + @Test + public void testAddEndpoint() { + addEndpoints(); + Collection> endpoints = descriptor.getEndpoints(); + assertTrue(endpoints.stream().anyMatch(x -> x.get(AssetAdministrationShell.ADDRESS) != null && x.get(AssetAdministrationShell.ADDRESS).equals(TESTENDPOINT))); + assertTrue(endpoints.stream().anyMatch(x -> x.get(AssetAdministrationShell.ADDRESS) != null && x.get(AssetAdministrationShell.ADDRESS).equals(TESTENDPOINT2))); + } + + @Test + public void testRemoveEndpoint() { + addEndpoints(); + descriptor.removeEndpoint(TESTENDPOINT); + Collection> endpoints = descriptor.getEndpoints(); + assertTrue(endpoints.stream().noneMatch(x -> x.get(AssetAdministrationShell.ADDRESS) != null && x.get(AssetAdministrationShell.ADDRESS).equals(TESTENDPOINT))); + } + + private void addEndpoints() { + descriptor = retrieveModelDescriptor(); + descriptor.addEndpoint(TESTENDPOINT); + descriptor.addEndpoint(TESTENDPOINT2); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java index 25782cc6..0151af3d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestAASDescriptor.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor; @@ -13,7 +28,7 @@ import static org.junit.Assert.assertNotNull; import java.util.Arrays; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.HashSet; import java.util.Map; @@ -35,16 +50,16 @@ * @author schnicke * */ -public class TestAASDescriptor { - +public class TestAASDescriptor extends ModelDescriptorTestSuite { + private Map map; - + @Before public void initialize() { - map = new HashMap(); + map = new LinkedHashMap(); map.put(Referable.IDSHORT, "123"); map.put(Identifiable.IDENTIFICATION, new Identifier(IdentifierType.IRDI, "123")); - map.put(ModelDescriptor.ENDPOINTS, Arrays.asList(new HashMap())); + map.put(ModelDescriptor.ENDPOINTS, Arrays.asList(new LinkedHashMap())); map.put(AssetAdministrationShell.SUBMODELS, new HashSet()); } @@ -67,61 +82,61 @@ public void testGetAllSubmodels() { // Assert correct retrieval assertEquals(2, descriptor.getSubmodelDescriptors().size()); } - + @Test(expected = MalformedRequestException.class) public void testValidateNoIdShort() { map.remove(Referable.IDSHORT); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateNullIdShort() { map.put(Referable.IDSHORT, null); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateWrongIdShort() { map.put(Referable.IDSHORT, 0); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateNoIdentification() { map.remove(Identifiable.IDENTIFICATION); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateNullIdentification() { map.put(Identifiable.IDENTIFICATION, null); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateWrongdentification() { map.put(Identifiable.IDENTIFICATION, "testId"); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateNoEndpoints() { map.remove(ModelDescriptor.ENDPOINTS); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateNullEndpoints() { map.put(ModelDescriptor.ENDPOINTS, null); new AASDescriptor(map); } - + @Test(expected = MalformedRequestException.class) public void testValidateWrongEndpoints() { map.put(ModelDescriptor.ENDPOINTS, "testEndpoint"); new AASDescriptor(map); } - + @Test public void testValidateNoSubmodels() { map.remove(AssetAdministrationShell.SUBMODELS); @@ -139,4 +154,9 @@ public void testValidateWrongSubmodels() { map.put(AssetAdministrationShell.SUBMODELS, "testSubmodel"); new AASDescriptor(map).getSubmodelDescriptors(); } + + @Override + public ModelDescriptor retrieveModelDescriptor() { + return new AASDescriptor(map); + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java index 044ec7d5..70045881 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestModelUrn.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor; @@ -26,13 +41,13 @@ */ public class TestModelUrn { private static final String rawURN = "testRawUrn"; - + @Test public void testConstructor1() { ModelUrn modelUrn = new ModelUrn(rawURN); assertEquals(rawURN, modelUrn.getURN()); } - + @Test public void testConstructor2() { String legalEntity = "testLegalEntity"; @@ -42,13 +57,13 @@ public void testConstructor2() { String revision = "5"; String elementId = "testId"; String elementInstance = "testInstance"; - + ModelUrn modelUrn = new ModelUrn(legalEntity, subUnit, subModel, version, revision, elementId, elementInstance); - String appendedString = "urn:" + legalEntity + ":" + subUnit + ":" + subModel + ":" + version + ":" + revision + ":" + elementId + "#"+ elementInstance; + String appendedString = "urn:" + legalEntity + ":" + subUnit + ":" + subModel + ":" + version + ":" + revision + ":" + elementId + "#" + elementInstance; assertEquals(appendedString, modelUrn.getURN()); assertEquals(IdentifierType.IRI, modelUrn.getIdType()); } - + @Test public void testAppend() { String suffix = "testSuffix"; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java index e62df536..6897e517 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/descriptor/TestSubmodelDescriptor.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.descriptor; @@ -14,6 +29,7 @@ import java.util.ArrayList; import java.util.Collections; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelDescriptor; import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; @@ -38,12 +54,12 @@ * @author haque * */ -public class TestSubmodelDescriptor { +public class TestSubmodelDescriptor extends ModelDescriptorTestSuite { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final String HTTP_ENDPOINT = "testEnd/submodel"; private static final String ID_SHORT_STRING = "testIdShort"; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, ID_SHORT_STRING); - + @Test public void testConstructor1() { ModelingKind modelingKind = ModelingKind.INSTANCE; @@ -61,13 +77,13 @@ public void testConstructor1() { Qualifiable qualifiable = new Qualifiable(formula); HasDataSpecification hasDataSpecification = new HasDataSpecification(new ArrayList<>(), Collections.singleton(reference)); Submodel subModel = new Submodel(hasSemantics, identifiable, qualifiable, hasDataSpecification, hasKind); - + SubmodelDescriptor descriptor = new SubmodelDescriptor(subModel, HTTP_ENDPOINT); assertEquals(HTTP_ENDPOINT, descriptor.getFirstEndpoint()); assertEquals(ID_SHORT_STRING, descriptor.getIdShort()); assertEquals(IDENTIFIER, descriptor.getIdentifier()); } - + @Test public void testConstructor2() { SubmodelDescriptor descriptor = new SubmodelDescriptor(ID_SHORT_STRING, IDENTIFIER, HTTP_ENDPOINT); @@ -75,4 +91,9 @@ public void testConstructor2() { assertEquals(ID_SHORT_STRING, descriptor.getIdShort()); assertEquals(IDENTIFIER, descriptor.getIdentifier()); } + + @Override + public ModelDescriptor retrieveModelDescriptor() { + return new SubmodelDescriptor(ID_SHORT_STRING, IDENTIFIER, HTTP_ENDPOINT); + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java index 4062b945..137607b0 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestAsset.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts; @@ -29,34 +44,33 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link Asset} for their - * correctness + * Tests constructor, setter and getter of {@link Asset} for their correctness * * @author haque * */ public class TestAsset { private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ASSET, false); - + private Asset asset; - + @Before public void buildAsset() { asset = new Asset(REFERENCE); } - + @Test public void testConstructor() { assertEquals(REFERENCE, asset.getAssetIdentificationModel()); } - + @Test public void testSetDataSpecificationReferences() { Collection refs = Collections.singleton(REFERENCE); asset.setDataSpecificationReferences(refs); assertEquals(refs, asset.getDataSpecificationReferences()); } - + @Test public void testSetEmbeddedDataSpecifications() { EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification(); @@ -64,21 +78,21 @@ public void testSetEmbeddedDataSpecifications() { asset.setEmbeddedDataSpecifications(specifications); assertEquals(specifications, asset.getEmbeddedDataSpecifications()); } - + @Test public void testAssetKind() { AssetKind kind = AssetKind.INSTANCE; asset.setAssetKind(kind); assertEquals(kind, asset.getAssetKind()); } - + @Test public void testSetAdministration() { AdministrativeInformation information = new AdministrativeInformation("1.0", "5"); asset.setAdministration(information); assertEquals(information, asset.getAdministration()); - } - + } + @Test public void testSetIdentification() { IdentifierType idType = IdentifierType.IRI; @@ -86,44 +100,44 @@ public void testSetIdentification() { asset.setIdentification(idType, newIdString); assertEquals(new Identifier(idType, newIdString), asset.getIdentification()); } - + @Test public void testSetAssetIdentificationModel() { asset.setAssetIdentificationModel(REFERENCE); assertEquals(REFERENCE, asset.getAssetIdentificationModel()); } - + @Test public void testSetIdShort() { String newIdString = "newId"; asset.setIdShort(newIdString); assertEquals(newIdString, asset.getIdShort()); } - + @Test public void testSetCategory() { String newCategoryString = "newCategory"; asset.setCategory(newCategoryString); assertEquals(newCategoryString, asset.getCategory()); } - + @Test public void testSetDescription() { LangStrings newDescriptionString = new LangStrings("DE", "newTest"); asset.setDescription(newDescriptionString); assertEquals(newDescriptionString, asset.getDescription()); } - + @Test public void testSetParent() { Reference parent = new Reference(new Identifier(IdentifierType.IRDI, "testNewId"), KeyElements.ASSET, true); asset.setParent(parent); assertEquals(parent, asset.getParent()); } - + @Test public void testSetBillOfMaterial() { asset.setBillOfMaterial(REFERENCE); assertEquals(REFERENCE, asset.getBillOfMaterial()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java index 17737d7c..eae8b038 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestConceptDictionary.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts; @@ -41,9 +56,9 @@ public class TestConceptDictionary { private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ASSET, false); private static final Reference REFERENCE2 = new Reference(new Identifier(IdentifierType.IRDI, "testNewId"), KeyElements.ASSET, true); - + private ConceptDictionary dictionary; - + @Before public void buildConceptDictionary() { List refs = new ArrayList<>(); @@ -51,40 +66,40 @@ public void buildConceptDictionary() { dictionary = new ConceptDictionary("testIdShort"); dictionary.setConceptDescriptionReferences(refs); } - + @Test public void testConstructor() { assertEquals(Collections.singleton(REFERENCE), dictionary.getConceptDescriptionReferences()); assertEquals(new ArrayList(), dictionary.getConceptDescriptions()); } - + @Test public void testSetIdShort() { String newIdString = "newId"; dictionary.setIdShort(newIdString); assertEquals(newIdString, dictionary.getIdShort()); } - + @Test public void testSetCategory() { String newCategoryString = "newCategory"; dictionary.setCategory(newCategoryString); assertEquals(newCategoryString, dictionary.getCategory()); } - + @Test public void testSetDescription() { LangStrings newDescriptionString = new LangStrings("DE", "newTest"); dictionary.setDescription(newDescriptionString); assertEquals(newDescriptionString, dictionary.getDescription()); } - + @Test public void testSetParent() { dictionary.setParent(REFERENCE2); assertEquals(REFERENCE2, dictionary.getParent()); } - + @Test public void testSetConceptDescriptionReferences() { Collection references = new HashSet(); @@ -93,7 +108,7 @@ public void testSetConceptDescriptionReferences() { dictionary.setConceptDescriptionReferences(references); assertEquals(references, dictionary.getConceptDescriptionReferences()); } - + @Test public void testSetConceptDescriptions() { ConceptDescription description1 = new ConceptDescription("testIdShort1", new Identifier(IdentifierType.IRDI, "testIdShort1")); @@ -105,8 +120,8 @@ public void testSetConceptDescriptions() { descriptions.add(description2); dictionary.setConceptDescriptions(descriptions); assertEquals(descriptions, dictionary.getConceptDescriptions()); - } - + } + @Test public void testAddConceptDescription() { IdentifierType idType = IdentifierType.IRI; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java index eb5fd099..932a129f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/parts/TestView.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.parts; @@ -28,8 +43,7 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link View} for their - * correctness + * Tests constructor, setter and getter of {@link View} for their correctness * * @author haque * @@ -37,10 +51,10 @@ public class TestView { private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ASSET, false); private static final Reference REFERENCE2 = new Reference(new Identifier(IdentifierType.IRDI, "testNewId"), KeyElements.ASSET, true); - + private View view; private Collection references; - + @Before public void buildConceptDictionary() { view = new View("testIdShort"); @@ -49,30 +63,30 @@ public void buildConceptDictionary() { references.add(REFERENCE); references.add(REFERENCE2); } - + @Test public void testConstructor() { assertEquals(Collections.singleton(REFERENCE), view.getContainedElement()); } - + @Test public void testSetContainedElement() { view.setContainedElement(references); assertEquals(references, view.getContainedElement()); } - + @Test public void testSetSemanticID() { view.setSemanticId(REFERENCE); assertEquals(REFERENCE, view.getSemanticId()); } - + @Test public void testSetDataSpecificationReferences() { view.setDataSpecificationReferences(references); assertEquals(references, view.getDataSpecificationReferences()); } - + @Test public void testSetEmbeddedDataSpecifications() { EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification(); @@ -80,28 +94,28 @@ public void testSetEmbeddedDataSpecifications() { view.setEmbeddedDataSpecifications(specifications); assertEquals(specifications, view.getEmbeddedDataSpecifications()); } - + @Test public void testSetIdShort() { String newIdString = "newId"; view.setIdShort(newIdString); assertEquals(newIdString, view.getIdShort()); } - + @Test public void testSetCategory() { String newCategoryString = "newCategory"; view.setCategory(newCategoryString); assertEquals(newCategoryString, view.getCategory()); } - + @Test public void testSetDescription() { LangStrings newDescriptionString = new LangStrings("DE", "newTest"); view.setDescription(newDescriptionString); assertEquals(newDescriptionString, view.getDescription()); } - + @Test public void testSetParent() { view.setParent(REFERENCE2); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java index ef52a64c..eea60c3d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/policypoints/TestAccessControlPolicyPoints.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.policypoints; @@ -20,42 +35,41 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link AccessControlPolicyPoints} for their - * correctness + * Tests constructor, setter and getter of {@link AccessControlPolicyPoints} for + * their correctness * * @author haque * */ public class TestAccessControlPolicyPoints { private AccessControlPolicyPoints points; - - + @Before public void buildObject() { points = new AccessControlPolicyPoints(); } - + @Test public void testSetPolicyAdministrationPoint() { PolicyAdministrationPoint policyAdministrationPoint = new PolicyAdministrationPoint(); points.setPolicyAdministrationPoint(policyAdministrationPoint); assertEquals(policyAdministrationPoint, points.getPolicyAdministrationPoint()); } - + @Test public void testPolicyDecisionPoint() { PolicyDecisionPoint policyDecisionPoint = new PolicyDecisionPoint(); points.setPolicyDecisionPoint(policyDecisionPoint); assertEquals(policyDecisionPoint, points.getPolicyDecisionPoint()); } - + @Test public void testPolicyEnforcementPoint() { PolicyEnforcementPoint policyEnforcementPoint = new PolicyEnforcementPoint(); points.setPolicyEnforcementPoint(policyEnforcementPoint); assertEquals(policyEnforcementPoint, points.getPolicyEnforcementPoint()); } - + @Test public void testPolicyInformationPoints() { PolicyInformationPoints policyInformationPoints = new PolicyInformationPoints(); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java index d83bf012..9430308c 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/metamodel/map/security/TestSecurity.java @@ -1,17 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.metamodel.map.security; import static org.junit.Assert.assertEquals; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.aas.metamodel.map.policypoints.AccessControlPolicyPoints; @@ -30,7 +45,7 @@ * */ public class TestSecurity { - + @Test public void testSetAccessControlPolicyPoints() { AccessControlPolicyPoints points = new AccessControlPolicyPoints(); @@ -38,13 +53,13 @@ public void testSetAccessControlPolicyPoints() { security.setAccessControlPolicyPoints(points); assertEquals(points, security.getAccessControlPolicyPoints()); } - + @Test public void testGetRequiredCertificateExtension() { Reference reference = new Reference(new Key(KeyElements.ASSET, false, "testValue", IdentifierType.IRI)); - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put(Security.REQUIREDCERTIFICATEEXTENSION, reference); Security security = Security.createAsFacade(map); assertEquals(reference, security.getRequiredCertificateExtension()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java index 57e3a434..bc551ffc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.registration; @@ -34,7 +49,8 @@ import org.junit.Test; /** - * Integration test for a registry. All registry provider implementations have to pass these tests. + * Integration test for a registry. All registry provider implementations have + * to pass these tests. * * @author espen * @@ -58,6 +74,7 @@ public abstract class TestRegistryProviderSuite { protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2 + "/submodel"; protected Asset asset1; protected Asset asset2; + /** * Getter for the tested registry provider. Tests for actual registry provider * have to realize this method. @@ -80,12 +97,12 @@ public void setUp() { AASDescriptor aasDesc1 = new AASDescriptor(aasIdShort1, aasId1, asset1, aasEndpoint1); aasDesc1.addSubmodelDescriptor(new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1)); AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, aasEndpoint2); - + // Register Asset Administration Shells proxy.register(aasDesc1); proxy.register(aasDesc2); } - + /** * Remove registry entries after each test */ @@ -113,7 +130,6 @@ public void testGetSingleAAS() { validateDescriptor1(descriptor); } - /** * Tests getting all entries from the registry and validates the result. */ @@ -133,8 +149,8 @@ public void testGetMultiAAS() { } /** - * Checks, if the given descriptor is valid. Should contain the values of the first descriptor - * as given by the test setup + * Checks, if the given descriptor is valid. Should contain the values of the + * first descriptor as given by the test setup */ protected void validateDescriptor1(AASDescriptor descriptor) { assertEquals(aasId1.getId(), descriptor.getIdentifier().getId()); @@ -152,8 +168,8 @@ protected void validateDescriptor1(AASDescriptor descriptor) { } /** - * Checks, if the given descriptor is valid. Should contain the values of the second descriptor - * as given by the test setup + * Checks, if the given descriptor is valid. Should contain the values of the + * second descriptor as given by the test setup */ protected void validateDescriptor2(AASDescriptor descriptor) { assertEquals(aasId2.getId(), descriptor.getIdentifier().getId()); @@ -207,9 +223,9 @@ public void testDeleteCall() { // After the setup, both AAS should have been inserted to the registry assertNotNull(proxy.lookupAAS(aasId1)); assertNotNull(proxy.lookupAAS(aasId2)); - + proxy.delete(aasId2); - + // After aas2 has been deleted, only aas1 should be registered assertNotNull(proxy.lookupAAS(aasId1)); try { @@ -327,7 +343,7 @@ public void testSubmodelCalls() { assertNotNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort1)); assertNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2)); } - + @Test(expected = ResourceNotFoundException.class) public void testRegisterSubmodelToNotExistingAAS() { proxy.register(new Identifier(IdentifierType.CUSTOM, "nonExistent"), new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1)); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java index 3ef1f3ea..ef299352 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/memory/TestMapRegistry.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.registration.memory; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/observing/ObservableAASRegistryServiceTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/observing/ObservableAASRegistryServiceTest.java new file mode 100644 index 00000000..a0752165 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/observing/ObservableAASRegistryServiceTest.java @@ -0,0 +1,182 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.aas.registration.observing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; +import org.eclipse.basyx.aas.registration.observing.IAASRegistryServiceObserver; +import org.eclipse.basyx.aas.registration.observing.ObservableAASRegistryService; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.junit.Before; +import org.junit.Test; + +public class ObservableAASRegistryServiceTest { + + private static final String AASID = "aasid1"; + private static final String SUBMODELID = "submodelid1"; + private static final String AASENDPOINT = "http://localhost:8080/aasList/" + AASID + "/aas"; + private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID); + private static final Identifier SUBMODELIDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODELID); + + private ObservableAASRegistryService observedRegistry; + private MockObserver observer; + + @Before + public void setup() { + // Create underlying registry service + IAASRegistry registryService = new InMemoryRegistry(); + + AssetAdministrationShell shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE)); + AASDescriptor aasDescriptor = new AASDescriptor(shell, AASENDPOINT); + registryService.register(aasDescriptor); + + Submodel submodel = new Submodel(SUBMODELID, SUBMODELIDENTIFIER); + String submodelEndpoint = AASENDPOINT + "/submodels/" + SUBMODELID + "/submodel"; + SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint); + registryService.register(AASIDENTIFIER, submodelDescriptor); + + observedRegistry = new ObservableAASRegistryService(registryService); + + // Create an Observer + observer = new MockObserver(); + + // Register the observer at the API + observedRegistry.addObserver(observer); + } + + @Test + public void testRegisterAAS() { + String newAASId = "aasid2"; + Identifier newIdentifier = new Identifier(IdentifierType.IRI, newAASId); + AssetAdministrationShell shell = new AssetAdministrationShell(newAASId, newIdentifier, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE)); + String aasEndpoint = "http://localhost:8080/aasList/" + newAASId + "/aas"; + + AASDescriptor aasDescriptor = new AASDescriptor(shell, aasEndpoint); + observedRegistry.register(aasDescriptor); + + assertEquals(newAASId, observer.aasId); + assertTrue(observer.registerAASNotified); + } + + @Test + public void testRegisterSubmodel() { + String submodelid = "submodelid2"; + Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRI, submodelid); + Submodel submodel = new Submodel(submodelid, newSubmodelIdentifier); + String submodelEndpoint = AASENDPOINT + "/submodels/" + submodelid + "/submodel"; + SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint); + + observedRegistry.register(AASIDENTIFIER, submodelDescriptor); + + assertTrue(observer.registerSubmodelNotified); + assertEquals(AASID, observer.aasId); + assertEquals(submodelid, observer.smId); + } + + @Test + public void testDeleteAAS() { + observedRegistry.delete(AASIDENTIFIER); + assertTrue(observer.deleteAASNotified); + assertEquals(AASID, observer.aasId); + } + + @Test + public void testDeleteSubmodel() { + observedRegistry.delete(AASIDENTIFIER, SUBMODELIDENTIFIER); + assertTrue(observer.deleteSubmodelNotified); + assertEquals(AASID, observer.aasId); + assertEquals(SUBMODELID, observer.smId); + } + + @Test + public void testRemoveObserver() { + assertTrue(observedRegistry.removeObserver(observer)); + observedRegistry.delete(AASIDENTIFIER); + assertFalse(observer.deleteAASNotified); + } + + private class MockObserver implements IAASRegistryServiceObserver { + + public boolean registerAASNotified = false; + public boolean registerSubmodelNotified = false; + public boolean deleteAASNotified = false; + public boolean deleteSubmodelNotified = false; + + public String aasId = ""; + public String smId = ""; + + @Override + public void aasRegistered(String aasId) { + this.registerAASNotified = true; + this.registerSubmodelNotified = false; + this.deleteAASNotified = false; + this.deleteSubmodelNotified = false; + this.aasId = aasId; + } + + @Override + public void submodelRegistered(IIdentifier aasId, IIdentifier smId) { + this.registerAASNotified = false; + this.registerSubmodelNotified = true; + this.deleteAASNotified = false; + this.deleteSubmodelNotified = false; + this.aasId = aasId.getId(); + this.smId = smId.getId(); + } + + @Override + public void aasDeleted(String aasId) { + this.registerAASNotified = false; + this.registerSubmodelNotified = false; + this.deleteAASNotified = true; + this.deleteSubmodelNotified = false; + this.aasId = aasId; + } + + @Override + public void submodelDeleted(IIdentifier aasId, IIdentifier smId) { + this.registerAASNotified = false; + this.registerSubmodelNotified = false; + this.deleteAASNotified = false; + this.deleteSubmodelNotified = true; + this.aasId = aasId.getId(); + this.smId = smId.getId(); + } + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java index 495db3ff..68ea555b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/AASRegistryServlet.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.registration.restapi; @@ -14,8 +29,9 @@ import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface; /** - * A registry servlet based on an InMemory Registry. The servlet therefore provides an implementation - * for the IAASRegistryService interface without a permanent storage capability. + * A registry servlet based on an InMemory Registry. The servlet therefore + * provides an implementation for the IAASRegistryService interface without a + * permanent storage capability. * * @author espen */ @@ -30,4 +46,3 @@ public AASRegistryServlet() { } } - diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java index 868b8b57..9c2f1491 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.registration.restapi; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java index 0fbc2fc7..0b1d4046 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProviderServlet.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.registration.restapi; @@ -24,13 +39,11 @@ */ public class TestDirectoryModelProviderServlet extends TestRegistryProviderSuite { /** - * Makes sure Tomcat Server is started after before each test case - * Initializes a new directory provider servlet + * Makes sure Tomcat Server is started after before each test case Initializes a + * new directory provider servlet */ @Rule - public AASHTTPServerResource res = new AASHTTPServerResource( - new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")) - .addServletMapping("/Testsuite/directory/*", new AASRegistryServlet())); + public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")).addServletMapping("/Testsuite/directory/*", new AASRegistryServlet())); @Override protected IAASRegistry getRegistryService() { diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java index 73ca6afe..8a3fe38f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderRemoteInvocationTest.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.restapi; @@ -44,8 +59,8 @@ import org.junit.Test; /** - * Tests the capability remote submodel invocation from registry - * in VABMultiSubmodelProvider + * Tests the capability remote submodel invocation from registry in + * VABMultiSubmodelProvider * * @author haque */ @@ -64,14 +79,13 @@ public class MultiSubmodelProviderRemoteInvocationTest { private List services = new ArrayList<>(); private MultiSubmodelProvider provider; - + // Creating a new AAS Registry private IAASRegistry registry = new InMemoryRegistry(); @Before public void init() { - - + // Create descriptors for AAS and submodels String aasEndpoint = "basyx://localhost:8000/aas"; String remoteSmEndpoint = "basyx://localhost:8001/submodel"; @@ -83,11 +97,10 @@ public void init() { // Register Asset Administration Shells registry.register(aasDesc); - // Create a VABMultiSubmodelProvider using the registry and a http connector provider = new MultiSubmodelProvider(registry, new BaSyxConnectorFactory()); - + // Create and add an AAS to the provider with same id as the AAS in the registry AssetAdministrationShell aas = new AssetAdministrationShell(); aas.setIdShort(AASIDSHORT1); @@ -108,7 +121,7 @@ public void init() { services.forEach(b -> b.start()); } - + /** * Checks if GET is correctly forwarded by checking if the Id of the remote * submodel can be retrieved @@ -120,7 +133,7 @@ public void testGetModelPropertyValue() throws Exception { Submodel sm = getRemoteSubmodel(); assertEquals(sm.getIdentification().getId(), REMOTESMID.getId()); } - + /** * Checks if a call to "/aas/submodels" correctly includes the remote submodels */ @@ -133,19 +146,21 @@ public void testGetAllSubmodels() { assertTrue(smIdShorts.contains(LOCALSMIDSHORT)); assertTrue(smIdShorts.size() == 2); } - + /** - * Tries to register a Submodel, not actually push it to the server and try to request all Submodels - * This will result in an endless loop if not handled correctly + * Tries to register a Submodel, not actually push it to the server and try to + * request all Submodels This will result in an endless loop if not handled + * correctly */ @Test public void testGetRegisteredButNotExistentSM() { - // Create a Descriptor for a Submodel (with a local Endpoint), that is not present on the server + // Create a Descriptor for a Submodel (with a local Endpoint), that is not + // present on the server SubmodelDescriptor smDescriptor = new SubmodelDescriptor("nonexist", new ModelUrn("nonexisting"), "basyx://localhost:8000/aas/submodels/nonexist"); - + // Register this SubmodelDescriptor registry.register(AASID1, smDescriptor); - + // Try to request all Submodels from the server try { provider.getValue("/aas/submodels"); @@ -169,7 +184,7 @@ public void testSetModelPropertyValue() throws Exception { Submodel sm = getRemoteSubmodel(); assertEquals(newVal, sm.getProperties().get(SimpleAASSubmodel.INTPROPIDSHORT).getValue()); } - + /** * Checks if CREATE is correctly forwarded by checking if a new property can be * created in the remote submodel @@ -186,7 +201,7 @@ public void testCreateModelPropertyValue() throws Exception { assertTrue(getRemoteSubmodel().getProperties().containsKey(testPropIdShort)); } - + /** * Checks if DELETE is correctly forwarded by checking if a property can be * deleted in the remote submodel diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java index af618f98..6b35f2e4 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/MultiSubmodelProviderTest.java @@ -5,10 +5,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Collection; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell; @@ -21,6 +25,10 @@ import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider; import org.eclipse.basyx.submodel.restapi.SubmodelProvider; @@ -29,6 +37,7 @@ import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.modelprovider.VABElementProxy; +import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProviderHelper; import org.junit.Before; import org.junit.Test; @@ -41,11 +50,9 @@ public class MultiSubmodelProviderTest { private VABElementProxy proxy; - // Used short ids private static final String AASIDSHORT = "StubAAS"; - - // Used URNs private static final ModelUrn AASURN = new ModelUrn("urn:fhg:es.iese:aas:1:1:myAAS#001"); + private String dynamicPropertyStringValue = "Test"; @Before public void build() { @@ -56,37 +63,52 @@ public void build() { // set dummy aas AssetAdministrationShell aas = new AssetAdministrationShell(AASIDSHORT, AASURN, new Asset("assetIdShort", new Identifier(IdentifierType.CUSTOM, "assetId"), AssetKind.INSTANCE)); provider.setAssetAdministrationShell(new AASModelProvider(aas)); - provider.addSubmodel(new SubmodelProvider(new SimpleAASSubmodel())); + Submodel dynamicSubmodel = createDynamicSubmodel(); + provider.addSubmodel(new SubmodelProvider(dynamicSubmodel)); stub.addProvider(urn, "", provider); proxy = stub.connectToVABElement(urn); } - + + private Submodel createDynamicSubmodel() { + Submodel sm = new SimpleAASSubmodel(); + Property stringProp = (Property) sm.getSubmodelElements().get("stringProperty"); + stringProp.set(VABLambdaProviderHelper.createSimple(() -> { + dynamicPropertyStringValue += dynamicPropertyStringValue; + return dynamicPropertyStringValue; + }, null), ValueType.String); + return sm; + } + @Test public void invokeExceptionTest() { // Invoke operationEx1 try { proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/exception1/invokable/invoke"); fail(); - } catch (ProviderException e) {} + } catch (ProviderException e) { + } // Invoke operationEx2 try { proxy.invokeOperation("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/exception2/invokable/invoke", "prop1"); fail(); - } catch (ProviderException e) {} + } catch (ProviderException e) { + } } - + @Test public void invalidPathPrefixInvokeTest() { try { proxy.invokeOperation("/aas/submodelX/SimpleAASSubmodel/submodel/submodelElements/complex/" + Operation.INVOKE, 10, 3); fail(); - } catch (MalformedRequestException e) {} - + } catch (MalformedRequestException e) { + } + try { proxy.invokeOperation("/abc/submodels/SimpleAASSubmodel/submodel/submodelElements/complex/" + Operation.INVOKE, 10, 3); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } @Test @@ -104,18 +126,27 @@ public void getTest() { getTestRunner("SimpleAASSubmodel"); } - + + @Test + public void getDynamicProperty() { + Object dynamicValue = proxy.getValue("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/stringProperty/value"); + Object dynamicValue2 = proxy.getValue("/aas/submodels/SimpleAASSubmodel/submodel/submodelElements/stringProperty/value"); + assertNotEquals(dynamicValue, dynamicValue2); + } + @Test public void invalidPathPrefixGetTest() { try { proxy.getValue("/aas/submodelX/SimpleAASSubmodel/submodel/"); fail(); - } catch (MalformedRequestException e) {} - + } catch (MalformedRequestException e) { + } + try { proxy.getValue("/abc/submodel/SimpleAASSubmodel/submodel/"); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } @Test @@ -132,7 +163,7 @@ public void updateSubmodelTest() { String newId = shell.getSubmodels().get("TestSM").getIdentification().getId(); assertEquals("TestId2", newId); } - + @Test public void invalidPathPrefixSetTest() { Submodel sm = new SimpleAASSubmodel("TestSM"); @@ -140,18 +171,20 @@ public void invalidPathPrefixSetTest() { try { proxy.setValue("/aas/submodelX/" + sm.getIdShort(), sm); fail(); - } catch (MalformedRequestException e) {} - + } catch (MalformedRequestException e) { + } + try { proxy.setValue("/abc/submodels/" + sm.getIdShort(), sm); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } @Test public void createDeleteSubmodelTest() { Submodel sm = new SimpleAASSubmodel("TestSM"); - sm.setIdentification(IdentifierType.CUSTOM, "TestId"); + sm.setIdentification(IdentifierType.CUSTOM, "http://testUrl.de"); proxy.setValue("/aas/submodels/" + sm.getIdShort(), sm); getTestRunner("TestSM"); @@ -160,7 +193,7 @@ public void createDeleteSubmodelTest() { ConnectedAssetAdministrationShell shell = new ConnectedAssetAdministrationShell(proxy.getDeepProxy("/aas")); Collection refs = shell.getSubmodelReferences(); assertEquals(2, refs.size()); - assertEquals(sm.getReference(), refs.iterator().next()); + assertTrue(refs.contains(sm.getReference())); proxy.deleteValue("/aas/submodels/TestSM"); @@ -175,7 +208,22 @@ public void createDeleteSubmodelTest() { // Expected } } - + + /** + * Tests if SubmodelElements are returned as a List in Submodel and + * SubmodelElementCollection and not as Map + */ + @SuppressWarnings("unchecked") + @Test + public void submodelElementsAreContainedAsList() { + List> submodels = (List>) proxy.getValue("/aas/submodels"); + Map submodel = submodels.get(0); + assertTrue(submodel.get(Submodel.SUBMODELELEMENT) instanceof List); + List> smCollections = ((List>) submodel.get(Submodel.SUBMODELELEMENT)).stream().filter(e -> ModelType.createAsFacade(e).getName().equals(SubmodelElementCollection.MODELTYPE)) + .collect(Collectors.toList()); + assertTrue(smCollections.get(0).get(Property.VALUE) instanceof List); + } + @Test public void invalidPathPrefixDeleteTest() { Submodel sm = new SimpleAASSubmodel("TestSM"); @@ -183,19 +231,19 @@ public void invalidPathPrefixDeleteTest() { try { proxy.deleteValue("/aas/submodelX/SimpleAASSubmodel"); fail(); - } catch (MalformedRequestException e) {} - + } catch (MalformedRequestException e) { + } + try { proxy.deleteValue("/aas/submodelX/SimpleAASSubmodel"); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } - private void getTestRunner(String smId) { // Get property value - Integer value = (Integer) proxy - .getValue("/aas/submodels/" + smId + "/" + SubmodelProvider.SUBMODEL + "/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value"); + Integer value = (Integer) proxy.getValue("/aas/submodels/" + smId + "/" + SubmodelProvider.SUBMODEL + "/" + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value"); assertEquals(123, value.intValue()); // Get property value with /submodel suffix diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java index 178f6d46..de8d20df 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/restapi/StubAASServlet.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.aas.restapi; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java b/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java index 0917f4ce..16d418e2 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/enumhelper/StandardizedLiteralEnumHelperTests.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.enumhelper; @@ -19,9 +34,9 @@ public class StandardizedLiteralEnumHelperTests { public static enum SampleEnum implements StandardizedLiteralEnum { LITERAL1("Literal1"), LITERAL2("Literal2"); - + private final String standardizedLiteral; - + private SampleEnum(String standardizedLiteral) { this.standardizedLiteral = standardizedLiteral; } @@ -30,12 +45,12 @@ private SampleEnum(String standardizedLiteral) { public String getStandardizedLiteral() { return standardizedLiteral; } - + public static SampleEnum fromString(String literal) { return StandardizedLiteralEnumHelper.fromLiteral(SampleEnum.class, literal); } } - + @Test public void testGetEnumFromLiteral() { assertTrue(SampleEnum.LITERAL1 == SampleEnum.fromString("Literal1")); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/MqttBrokerSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/MqttBrokerSuite.java new file mode 100644 index 00000000..39c40794 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/MqttBrokerSuite.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas; + +import java.io.IOException; + +import io.moquette.broker.Server; +import io.moquette.broker.config.ClasspathResourceLoader; +import io.moquette.broker.config.IConfig; +import io.moquette.broker.config.IResourceLoader; +import io.moquette.broker.config.ResourceLoaderConfig; + +public abstract class MqttBrokerSuite { + + protected static Server createAndStartMqttBroker() throws IOException { + Server mqttBroker = new Server(); + IResourceLoader classpathLoader = new ClasspathResourceLoader(); + final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); + mqttBroker.startServer(classPathConfig); + + return mqttBroker; + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorAASXUpload.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorAASXUpload.java new file mode 100644 index 00000000..f9192e76 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorAASXUpload.java @@ -0,0 +1,44 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.aasxupload; + +import org.eclipse.basyx.aas.aggregator.AASAggregator; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.AASAggregatorAASXUpload; + +/** + * Tests AAS Aggragator with AASX upload functionality + * + * @author haque + * + */ +public class TestAASAggregatorAASXUpload extends TestAASAggregatorAASXUploadSuite { + @Override + protected IAASAggregator getAggregator() { + return new AASAggregatorAASXUpload(new AASAggregator()); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorAASXUploadSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorAASXUploadSuite.java new file mode 100644 index 00000000..4c23e7d5 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorAASXUploadSuite.java @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.aasxupload; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.http.client.ClientProtocolException; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.api.IAASAggregatorAASXUpload; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.testsuite.regression.aas.aggregator.AASAggregatorSuite; +import org.junit.Test; + +/** + * Test suite for testing AAS Aggregator along with AASX upload + * + * @author haque + * + */ +public abstract class TestAASAggregatorAASXUploadSuite extends AASAggregatorSuite { + public static final String AASX_PATH = "src/test/resources/aas/factory/aasx/01_Festo.aasx"; + + @Test + public void testUploadAASX() throws ClientProtocolException, IOException { + File file = Paths.get(AASX_PATH).toFile(); + IAASAggregatorAASXUpload aggregator = (IAASAggregatorAASXUpload) getAggregator(); + aggregator.uploadAASX(new FileInputStream(file)); + checkAASX(aggregator.getAASList()); + } + + public static void checkAASX(Collection shells) { + assertEquals(2, shells.size()); + + Iterator iterator = shells.iterator(); + IAssetAdministrationShell shell1 = iterator.next(); + + assertEquals("smart.festo.com/demo/aas/1/1/454576463545648365874", shell1.getIdentification().getId()); + assertEquals("Festo_3S7PM0CP4BD", shell1.getIdShort()); + + Iterator smIteratorShell1 = shell1.getSubmodelReferences().iterator(); + IReference shell1Sm1 = smIteratorShell1.next(); + assertEquals("www.company.com/ids/sm/4343_5072_7091_3242", shell1Sm1.getKeys().get(0).getValue()); + IReference shell1Sm2 = smIteratorShell1.next(); + assertEquals("www.company.com/ids/sm/2543_5072_7091_2660", shell1Sm2.getKeys().get(0).getValue()); + IReference shell1Sm3 = smIteratorShell1.next(); + assertEquals("smart.festo.com/demo/sm/instance/1/1/13B7CCD9BF7A3F24", shell1Sm3.getKeys().get(0).getValue()); + IReference shell1Sm4 = smIteratorShell1.next(); + assertEquals("www.company.com/ids/sm/6053_5072_7091_5102", shell1Sm4.getKeys().get(0).getValue()); + IReference shell1Sm5 = smIteratorShell1.next(); + assertEquals("www.company.com/ids/sm/6563_5072_7091_4267", shell1Sm5.getKeys().get(0).getValue()); + + IAssetAdministrationShell shell2 = iterator.next(); + assertEquals("www.admin-shell.io/aas-sample/1/1", shell2.getIdentification().getId()); + assertEquals("test_asset_aas", shell2.getIdShort()); + + Iterator smIteratorShell2 = shell2.getSubmodelReferences().iterator(); + IReference shell2Sm1 = smIteratorShell2.next(); + assertEquals("de.iese.com/ids/sm/0000_000_000_001", shell2Sm1.getKeys().get(0).getValue()); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorProxyWithAASXProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorProxyWithAASXProvider.java new file mode 100644 index 00000000..59b60f4e --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/aasxupload/TestAASAggregatorProxyWithAASXProvider.java @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.aasxupload; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Collection; + +import org.apache.http.client.ClientProtocolException; +import org.eclipse.basyx.aas.aggregator.AASAggregator; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.AASAggregatorAASXUpload; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.proxy.AASAggregatorAASXUploadProxy; +import org.eclipse.basyx.extensions.aas.aggregator.aasxupload.restapi.AASAggregatorAASXUploadProvider; +import org.eclipse.basyx.testsuite.regression.aas.aggregator.TestAASAggregatorProxy; +import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext; +import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test for the {@link AASAggregatorAASXUploadProxy} + * + * @author haque + * + */ +public class TestAASAggregatorProxyWithAASXProvider extends TestAASAggregatorProxy { + private static final String SERVER = "localhost"; + private static final int PORT = 4000; + private static final String CONTEXT_PATH = "aggregator"; + private static final String API_URL = "http://" + SERVER + ":" + PORT + "/" + CONTEXT_PATH + "/shells"; + private AASAggregatorAASXUploadProvider provider = new AASAggregatorAASXUploadProvider(new AASAggregatorAASXUpload(new AASAggregator())); + + @Rule + public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/" + CONTEXT_PATH, "", SERVER, PORT).addServletMapping("/*", new VABHTTPInterface(provider))); + + @Override + protected IAASAggregator getAggregator() { + return new AASAggregatorAASXUploadProxy(API_URL); + } + + @Test + public void testClientUpload() throws ClientProtocolException, IOException { + AASAggregatorAASXUploadProxy proxy = new AASAggregatorAASXUploadProxy(API_URL); + proxy.uploadAASX(new FileInputStream(Paths.get(TestAASAggregatorAASXUploadSuite.AASX_PATH).toFile())); + + Collection uploadedShells = proxy.getAASList(); + TestAASAggregatorAASXUploadSuite.checkAASX(uploadedShells); + } +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/TestAuthorizedAASAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/TestAuthorizedAASAggregator.java new file mode 100644 index 00000000..a83263d0 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/authorization/TestAuthorizedAASAggregator.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.authorization; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.extensions.aas.aggregator.authorization.AuthorizedAASAggregator; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.AuthorizationContextProvider; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Tests authorization with the AuthorizedAASAggregator + * + * @author jungjan, fried, fischer + */ +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class TestAuthorizedAASAggregator { + @Mock + private IAASAggregator aggregatorMock; + private AuthorizedAASAggregator testSubject; + private AuthorizationContextProvider securityContextProvider = new AuthorizationContextProvider(AuthorizedAASAggregator.READ_AUTHORITY, AuthorizedAASAggregator.WRITE_AUTHORITY); + + @Before + public void setUp() { + testSubject = new AuthorizedAASAggregator(aggregatorMock); + } + + @After + public void tearDown() { + securityContextProvider.clearContext(); + Mockito.verifyNoMoreInteractions(aggregatorMock); + } + + private AssetAdministrationShell invokeCreateAAS() { + final IIdentifier shellId = new ModelUrn("urn:test1"); + final AssetAdministrationShell shell = new AssetAdministrationShell("test", shellId, new Asset()); + testSubject.createAAS(shell); + return shell; + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenCreateAAS_thenThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + invokeCreateAAS(); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenCreateAAS_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + AssetAdministrationShell shell = invokeCreateAAS(); + Mockito.verify(aggregatorMock).createAAS(shell); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingWriteAuthority_whenCreateAAS_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + invokeCreateAAS(); + } + + private IIdentifier invokeDeleteAAS() { + final IIdentifier shellId = new ModelUrn("urn:test"); + testSubject.deleteAAS(shellId); + return shellId; + } + + @Test + public void givenPrincipalHasWriteAuthority_whenDeleteAAS_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + final IIdentifier shellId = invokeDeleteAAS(); + Mockito.verify(aggregatorMock).deleteAAS(shellId); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingWriteAuthority_whenDeleteAAS_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + invokeDeleteAAS(); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetAAS_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + + final IIdentifier shellId = new ModelUrn("urn:test1"); + final AssetAdministrationShell expectedShell = new AssetAdministrationShell("test", shellId, new Asset()); + Mockito.when(aggregatorMock.getAAS(shellId)).thenReturn(expectedShell); + + final IAssetAdministrationShell shell = testSubject.getAAS(shellId); + + Assert.assertEquals(expectedShell, shell); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetAAS_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + + final IIdentifier shellId = new ModelUrn("urn:test1"); + + testSubject.getAAS(shellId); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetAASList_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + + final IIdentifier shellId = new ModelUrn("urn:test1"); + final Collection expectedAASDescriptorList = Collections.singletonList(new AssetAdministrationShell("test", shellId, new Asset())); + Mockito.when(aggregatorMock.getAASList()).thenReturn(expectedAASDescriptorList); + + final Collection shellList = testSubject.getAASList(); + + Assert.assertEquals(expectedAASDescriptorList, shellList); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetAASList_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + + testSubject.getAASList(); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestFullMqttAASAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestFullMqttAASAggregator.java new file mode 100644 index 00000000..a41c951a --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestFullMqttAASAggregator.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.mqtt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.eclipse.basyx.aas.aggregator.AASAggregatorFactory; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider; +import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; +import org.eclipse.basyx.aas.restapi.AASAPIFactory; +import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttAASAggregatorHelper; +import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttDecoratingAASAggregatorFactory; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttAASAPIHelper; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttDecoratingAASAPIFactory; +import org.eclipse.basyx.extensions.submodel.aggregator.mqtt.MqttDecoratingSubmodelAggregatorFactory; +import org.eclipse.basyx.extensions.submodel.aggregator.mqtt.MqttSubmodelAggregatorHelper; +import org.eclipse.basyx.submodel.aggregator.SubmodelAggregatorFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory; +import org.eclipse.basyx.testsuite.regression.extensions.aas.MqttBrokerSuite; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.eclipse.basyx.vab.protocol.api.IConnectorFactory; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttSecurityException; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; + +public class TestFullMqttAASAggregator extends MqttBrokerSuite { + protected static Server mqttBroker; + protected static MqttClient client; + protected static IAASAggregator aggregator; + protected static MqttTestListener listener; + + protected static ConnectedAssetAdministrationShellManager manager; + protected static IIdentifier shellIdentifier = new CustomId("shellId"); + protected static IIdentifier submodelIdentifier = new CustomId("submodelId"); + + @BeforeClass + public static void setUp() throws IOException, MqttSecurityException, MqttException { + mqttBroker = createAndStartMqttBroker(); + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + + client = createMqttClient(); + client.connect(); + + IAASRegistry aasRegistry = new InMemoryRegistry(); + + aggregator = createAggregator(aasRegistry); + + manager = createConnectedAASManager(aasRegistry); + } + + private static ConnectedAssetAdministrationShellManager createConnectedAASManager(IAASRegistry aasRegistry) { + return new ConnectedAssetAdministrationShellManager(aasRegistry, new IConnectorFactory() { + + @Override + public IModelProvider getConnector(String addr) { + return new AASAggregatorProvider(aggregator); + } + }); + } + + private static IAASAggregator createAggregator(IAASRegistry aasRegistry) throws MqttException { + return new MqttDecoratingAASAggregatorFactory( + new AASAggregatorFactory(new MqttDecoratingAASAPIFactory(new AASAPIFactory(), client), new MqttDecoratingSubmodelAggregatorFactory(new SubmodelAggregatorFactory(new VABSubmodelAPIFactory()), client), aasRegistry), client) + .create(); + } + + private static MqttClient createMqttClient() throws MqttException { + return new MqttClient("tcp://localhost:1884", "testClient", new MqttDefaultFilePersistence()); + } + + @Test + public void shellLifeCycle() { + AssetAdministrationShell shell = createShell(shellIdentifier.getId(), shellIdentifier); + manager.createAAS(shell, getURL()); + + assertTrue(listenerHasTopic(MqttAASAggregatorHelper.TOPIC_CREATEAAS)); + assertEquals(shell.getIdShort(), manager.retrieveAAS(shellIdentifier).getIdShort()); + + manager.deleteAAS(shellIdentifier); + + assertTrue(listenerHasTopic(MqttAASAggregatorHelper.TOPIC_DELETEAAS)); + + try { + manager.retrieveAAS(shellIdentifier); + fail(); + } catch (ResourceNotFoundException e) { + // ResourceNotFoundException expected + } + } + + @Test + public void submodelLifeCycle() { + IIdentifier shellIdentifierForSubmodel = new CustomId("shellSubmodelId"); + + AssetAdministrationShell shell = createShell(shellIdentifierForSubmodel.getId(), shellIdentifierForSubmodel); + manager.createAAS(shell, getURL()); + + Submodel submodel = createSubmodel(submodelIdentifier.getId(), submodelIdentifier); + + manager.createSubmodel(shellIdentifierForSubmodel, submodel); + + assertTrue(listenerHasTopic(MqttSubmodelAggregatorHelper.TOPIC_CREATESUBMODEL)); + assertTrue(listenerHasTopic(MqttAASAPIHelper.TOPIC_ADDSUBMODEL)); + assertEquals(submodel.getIdShort(), manager.retrieveSubmodel(shellIdentifierForSubmodel, submodelIdentifier).getIdShort()); + + manager.deleteSubmodel(shellIdentifierForSubmodel, submodelIdentifier); + assertTrue(listenerHasTopic(MqttSubmodelAggregatorHelper.TOPIC_DELETESUBMODEL)); + assertTrue(listenerHasTopic(MqttAASAPIHelper.TOPIC_REMOVESUBMODEL)); + try { + manager.retrieveSubmodel(shellIdentifierForSubmodel, submodelIdentifier); + fail(); + } catch (ResourceNotFoundException e) { + // ResourceNotFoundException expected + } + manager.deleteAAS(shellIdentifierForSubmodel); + } + + private String getURL() { + return ""; + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.removeInterceptHandler(listener); + mqttBroker.stopServer(); + } + + protected AssetAdministrationShell createShell(String idShort, IIdentifier identifier) { + AssetAdministrationShell shell = new AssetAdministrationShell(); + shell.setIdentification(identifier); + shell.setIdShort(idShort); + return shell; + } + + protected Submodel createSubmodel(String idShort, IIdentifier submodelIdentifier) { + Submodel submodel = new Submodel(); + submodel.setIdentification(submodelIdentifier); + submodel.setIdShort(idShort); + return submodel; + } + + private boolean listenerHasTopic(String expectedTopic) { + return listener.getTopics().stream().anyMatch(t -> t.equals(expectedTopic)); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java index 9ffca3bc..3759246d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregator.java @@ -1,30 +1,45 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.mqtt; -import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; - import static org.junit.Assert.assertEquals; import java.io.IOException; -import org.eclipse.basyx.aas.aggregator.AASAggregator; +import org.eclipse.basyx.aas.aggregator.AASAggregatorFactory; import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; import org.eclipse.basyx.aas.metamodel.map.parts.Asset; -import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttAASAggregator; +import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttAASAggregatorHelper; +import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttDecoratingAASAggregatorFactory; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttException; -import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -44,12 +59,13 @@ */ public class TestMqttAASAggregator { protected AssetAdministrationShell shell; - private static final String AASID = "aasid1"; + private static final String AASID = "AASId"; private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID); - + private static Server mqttBroker; - private static MqttAASAggregator eventAPI; - private MqttTestListener listener; + private static IAASAggregator eventAPI; + private static MqttClient client; + private static MqttTestListener listener; /** * Sets up the MQTT broker and AASAggregator for tests @@ -62,56 +78,52 @@ public static void setUpClass() throws MqttException, IOException { final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); mqttBroker.startServer(classPathConfig); - // Create underlying aas aggregator - IAASAggregator aggregator = new AASAggregator(); - - eventAPI = new MqttAASAggregator(aggregator, "tcp://localhost:1884", "testClient"); + client = new MqttClient("tcp://localhost:1884", "testClient"); + client.connect(); + + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + + eventAPI = new MqttDecoratingAASAggregatorFactory(new AASAggregatorFactory(), client).create(); } @AfterClass public static void tearDownClass() { + mqttBroker.removeInterceptHandler(listener); mqttBroker.stopServer(); } - + @Before public void setUp() { - shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE)); + shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetId", new Identifier(IdentifierType.IRI, "assetId"), AssetKind.INSTANCE)); eventAPI.createAAS(shell); - - listener = new MqttTestListener(); - mqttBroker.addInterceptHandler(listener); - } - - @After - public void tearDown() { - mqttBroker.removeInterceptHandler(listener); } - + @Test public void testCreateAAS() { - String aasId2 = "aas2"; - Identifier identifier2 = new Identifier(IdentifierType.IRDI, aasId2); - AssetAdministrationShell shell2 = new AssetAdministrationShell(aasId2, identifier2, new Asset("assetid2", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE)); - eventAPI.createAAS(shell2); + String newAASId = "newAASId"; + Identifier newAASIdentifier = new Identifier(IdentifierType.IRDI, newAASId); + AssetAdministrationShell newShell = new AssetAdministrationShell(newAASId, newAASIdentifier, new Asset("newAssetId", new Identifier(IdentifierType.IRI, "newAssetId"), AssetKind.INSTANCE)); + eventAPI.createAAS(newShell); - assertEquals(aasId2, listener.lastPayload); - assertEquals(MqttAASAggregator.TOPIC_CREATEAAS, listener.lastTopic); + assertEquals(newAASId, listener.lastPayload); + assertEquals(MqttAASAggregatorHelper.TOPIC_CREATEAAS, listener.lastTopic); } - + @Test public void testUpdateAAS() { shell.setCategory("newCategory"); eventAPI.updateAAS(shell); - + assertEquals(AASID, listener.lastPayload); - assertEquals(MqttAASAggregator.TOPIC_UPDATEAAS, listener.lastTopic); + assertEquals(MqttAASAggregatorHelper.TOPIC_UPDATEAAS, listener.lastTopic); } - + @Test public void testDeleteAAS() { eventAPI.deleteAAS(AASIDENTIFIER); assertEquals(AASID, listener.lastPayload); - assertEquals(MqttAASAggregator.TOPIC_DELETEAAS, listener.lastTopic); + assertEquals(MqttAASAggregatorHelper.TOPIC_DELETEAAS, listener.lastTopic); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregatorObserver.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregatorObserver.java new file mode 100644 index 00000000..4ea9ffec --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/aggregator/mqtt/TestMqttAASAggregatorObserver.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas.aggregator.mqtt; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.eclipse.basyx.aas.aggregator.AASAggregatorFactory; +import org.eclipse.basyx.aas.aggregator.api.IAASAggregator; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttAASAggregatorHelper; +import org.eclipse.basyx.extensions.aas.aggregator.mqtt.MqttDecoratingAASAggregatorFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; +import io.moquette.broker.config.ClasspathResourceLoader; +import io.moquette.broker.config.IConfig; +import io.moquette.broker.config.IResourceLoader; +import io.moquette.broker.config.ResourceLoaderConfig; + +/** + * Tests events emitting with the MqttAASAggregatorObserver + * + * @author haque + * + */ +public class TestMqttAASAggregatorObserver { + protected AssetAdministrationShell shell; + private static final String AASID = "aasid1"; + private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID); + + private static Server mqttBroker; + private static IAASAggregator observedAPI; + private static MqttClient client; + private static MqttTestListener listener; + + /** + * Sets up the MQTT broker and ObservableAASAggregator for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + // Start MQTT broker + mqttBroker = new Server(); + IResourceLoader classpathLoader = new ClasspathResourceLoader(); + final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); + mqttBroker.startServer(classPathConfig); + + client = new MqttClient("tcp://localhost:1884", "testClient"); + client.connect(); + + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + + observedAPI = createObservedAASAggregator(); + + } + + private static IAASAggregator createObservedAASAggregator() throws MqttException { + return new MqttDecoratingAASAggregatorFactory(new AASAggregatorFactory(), client).create(); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.removeInterceptHandler(listener); + mqttBroker.stopServer(); + } + + @Before + public void setUp() { + shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetId", new Identifier(IdentifierType.IRI, "assetId"), AssetKind.INSTANCE)); + observedAPI.createAAS(shell); + } + + @Test + public void testCreateAAS() { + String newAASId = "newAASId"; + Identifier newAASIdentifier = new Identifier(IdentifierType.IRDI, newAASId); + AssetAdministrationShell newShell = new AssetAdministrationShell(newAASId, newAASIdentifier, new Asset("newAssetId", new Identifier(IdentifierType.IRI, "newAssetId"), AssetKind.INSTANCE)); + observedAPI.createAAS(newShell); + + assertEquals(newAASId, listener.lastPayload); + assertEquals(MqttAASAggregatorHelper.TOPIC_CREATEAAS, listener.lastTopic); + } + + @Test + public void testUpdateAAS() { + shell.setCategory("newCategory"); + observedAPI.updateAAS(shell); + + assertEquals(AASID, listener.lastPayload); + assertEquals(MqttAASAggregatorHelper.TOPIC_UPDATEAAS, listener.lastTopic); + } + + @Test + public void testDeleteAAS() { + observedAPI.deleteAAS(AASIDENTIFIER); + + assertEquals(AASID, listener.lastPayload); + assertEquals(MqttAASAggregatorHelper.TOPIC_DELETEAAS, listener.lastTopic); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/TestAuthorizedAASAPI.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/TestAuthorizedAASAPI.java new file mode 100644 index 00000000..05bc5752 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/authorization/TestAuthorizedAASAPI.java @@ -0,0 +1,122 @@ +package org.eclipse.basyx.testsuite.regression.extensions.aas.api.authorization; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.extensions.aas.api.authorization.AuthorizedAASAPI; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.AuthorizationContextProvider; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Tests authorization with the AuthorizedAASAPI + * + * @author espen + */ +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class TestAuthorizedAASAPI { + @Mock + private IAASAPI apiMock; + private AuthorizedAASAPI testSubject; + private AuthorizationContextProvider securityContextProvider; + + private static final String SHELL_ID = "shell_one"; + private static final Identifier SHELL_IDENTIFIER = new Identifier(IdentifierType.IRI, SHELL_ID); + private static final String SUBMODEL_ID = "submodel_1"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + private static final String ASSET_ID = "asset_one"; + private static final Identifier ASSET_IDENTIFIER = new Identifier(IdentifierType.IRI, ASSET_ID); + private static final Asset SHELL_ASSET = new Asset(ASSET_ID, ASSET_IDENTIFIER, AssetKind.INSTANCE); + + private static AssetAdministrationShell shell; + private static Submodel submodel; + + @Before + public void setUp() { + testSubject = new AuthorizedAASAPI(apiMock); + securityContextProvider = new AuthorizationContextProvider(AuthorizedAASAPI.READ_AUTHORITY, AuthorizedAASAPI.WRITE_AUTHORITY); + + shell = new AssetAdministrationShell(SHELL_ID, SHELL_IDENTIFIER, SHELL_ASSET); + submodel = new Submodel(SUBMODEL_ID, SUBMODEL_IDENTIFIER); + } + + @After + public void tearDown() { + securityContextProvider.clearContext(); + Mockito.verifyNoMoreInteractions(apiMock); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetAAS_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.getAAS()).thenReturn(shell); + + IAssetAdministrationShell returnedShell = testSubject.getAAS(); + assertEquals(shell, returnedShell); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetAAS_thenThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + testSubject.getAAS(); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetAAS_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + testSubject.getAAS(); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenAddSubmodel_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + IReference smReference2Add = submodel.getReference(); + testSubject.addSubmodel(smReference2Add); + Mockito.verify(apiMock).addSubmodel(smReference2Add); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenAddSubmodel_thenThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + testSubject.addSubmodel(submodel.getReference()); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenAddSubmodel_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + testSubject.addSubmodel(submodel.getReference()); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenRemoveSubmodel_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + testSubject.removeSubmodel(SUBMODEL_ID); + Mockito.verify(apiMock).removeSubmodel(SUBMODEL_ID); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenRemoveSubmodel_thenThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + testSubject.removeSubmodel(SUBMODEL_ID); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenRemoveSubmodel_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + testSubject.removeSubmodel(SUBMODEL_ID); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/mqtt/TestMqttAASAPIEvents.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/mqtt/TestMqttAASAPIEvents.java new file mode 100644 index 00000000..768d5756 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/mqtt/TestMqttAASAPIEvents.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (C) 2022 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas.api.mqtt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.aas.restapi.AASAPIFactory; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttAASAPIHelper; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttAASAPIObserver; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttDecoratingAASAPIFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.aas.MqttBrokerSuite; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; + +/** + * Tests events emitting with the MqttAASAPI + * + * @author fried + * + */ +public class TestMqttAASAPIEvents extends MqttBrokerSuite { + private static final String SHELL_ID = "shellId"; + private static final Identifier SHELL_IDENTIFIER = new Identifier(IdentifierType.IRI, SHELL_ID); + + private static final String ASSET_ID = "assetId"; + private static final Identifier ASSET_IDENTIFIER = new Identifier(IdentifierType.IRI, ASSET_ID); + private static final Asset SHELL_ASSET = new Asset(ASSET_ID, ASSET_IDENTIFIER, AssetKind.INSTANCE); + + private static final String SUBMODEL_ID = "submodelId"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + + private static AssetAdministrationShell shell; + private static Submodel submodel; + + private static Server mqttBroker; + private static IAASAPI eventAPI; + private static MqttTestListener listener; + private static MqttClient client; + + /** + * Sets up the MQTT broker and submodelAPI for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + mqttBroker = createAndStartMqttBroker(); + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + + client = new MqttClient("tcp://localhost:1884", "testClient"); + client.connect(); + + shell = new AssetAdministrationShell(SHELL_ID, SHELL_IDENTIFIER, SHELL_ASSET); + + eventAPI = createObservableAASAPI(); + submodel = new Submodel(SUBMODEL_ID, SUBMODEL_IDENTIFIER); + + eventAPI.addSubmodel(submodel.getReference()); + } + + private static IAASAPI createObservableAASAPI() throws MqttException { + return new MqttDecoratingAASAPIFactory(new AASAPIFactory(), client).getAASApi(shell); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.removeInterceptHandler(listener); + mqttBroker.stopServer(); + } + + @Test + public void submodelCreationEventSent() throws InterruptedException { + String submodelId = "newSubmodelId"; + Identifier submodelIdentifier = new Identifier(IdentifierType.IRI, submodelId); + Submodel submodel = new Submodel(submodelId, submodelIdentifier); + eventAPI.addSubmodel(submodel.getReference()); + + assertEquals(MqttAASAPIObserver.getCombinedMessage(SHELL_ID, submodelId), listener.lastPayload); + assertTrue(listenerHasTopic(MqttAASAPIHelper.TOPIC_ADDSUBMODEL)); + } + + @Test + public void submodelDeletionEventSent() { + eventAPI.removeSubmodel(SUBMODEL_ID); + + assertEquals(MqttAASAPIObserver.getCombinedMessage(SHELL_ID, SUBMODEL_ID), listener.lastPayload); + assertTrue(listenerHasTopic(MqttAASAPIHelper.TOPIC_REMOVESUBMODEL)); + } + + private boolean listenerHasTopic(String expectedTopic) { + return listener.getTopics().stream().anyMatch(t -> t.equals(expectedTopic)); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/mqtt/TestMqttAASAPIObserver.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/mqtt/TestMqttAASAPIObserver.java new file mode 100644 index 00000000..a8811097 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/api/mqtt/TestMqttAASAPIObserver.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas.api.mqtt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.aas.restapi.AASAPIFactory; +import org.eclipse.basyx.aas.restapi.api.IAASAPI; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttAASAPIHelper; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttAASAPIObserver; +import org.eclipse.basyx.extensions.aas.api.mqtt.MqttDecoratingAASAPIFactory; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.aas.MqttBrokerSuite; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; + +/** + * Tests for MqttAASAPIObserver + * + * @author fried + * + */ +public class TestMqttAASAPIObserver extends MqttBrokerSuite { + private static final String SHELL_ID = "testAASId"; + private static final Identifier SHELL_IDENTIFIER = new Identifier(IdentifierType.IRI, SHELL_ID); + private static final Asset SHELL_ASSET = new Asset("shellAsset", new Identifier(IdentifierType.IRI, "shellAsset"), AssetKind.INSTANCE); + + private static final String SUBMODEL_ID = "testSubmodelId"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + + private static AssetAdministrationShell shell; + private static Submodel submodel; + + private static Server mqttBroker; + private static IAASAPI observableAPI; + private static MqttTestListener listener; + private static MqttClient client; + + /** + * Sets up the MQTT broker and aasAPI for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + mqttBroker = createAndStartMqttBroker(); + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + + shell = new AssetAdministrationShell(SHELL_ID, SHELL_IDENTIFIER, SHELL_ASSET); + submodel = new Submodel(SUBMODEL_ID, SUBMODEL_IDENTIFIER); + + client = new MqttClient("tcp://localhost:1884", "testClient"); + client.connect(); + + observableAPI = createObservableAASAPI(); + observableAPI.addSubmodel(submodel.getReference()); + } + + private static IAASAPI createObservableAASAPI() throws MqttException { + return new MqttDecoratingAASAPIFactory(new AASAPIFactory(), client).getAASApi(shell); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.removeInterceptHandler(listener); + mqttBroker.stopServer(); + } + + @Test + public void submodelCreationEventSent() throws InterruptedException { + String smIdShort = "testAddProp"; + Identifier smIdentifier = new Identifier(IdentifierType.IRI, smIdShort); + Submodel sm = new Submodel(smIdShort, smIdentifier); + observableAPI.addSubmodel(sm.getReference()); + + assertEquals(MqttAASAPIObserver.getCombinedMessage(shell.getIdShort(), smIdShort), listener.lastPayload); + assertTrue(listenerHasTopic(MqttAASAPIHelper.TOPIC_ADDSUBMODEL)); + } + + @Test + public void submodelDeletionEventSent() { + String idShort = submodel.getIdShort(); + observableAPI.removeSubmodel(idShort); + + assertEquals(MqttAASAPIObserver.getCombinedMessage(SHELL_ID, idShort), listener.lastPayload); + assertTrue(listenerHasTopic(MqttAASAPIHelper.TOPIC_REMOVESUBMODEL)); + } + + private boolean listenerHasTopic(String expectedTopic) { + return listener.getTopics().stream().anyMatch(t -> t.equals(expectedTopic)); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java index 1d836838..31029efc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/TestTaggedDirectorySuite.java @@ -1,11 +1,10 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0/ * - * SPDX-License-Identifier: EPL-2.0 + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged; @@ -13,13 +12,16 @@ import static org.junit.Assert.assertTrue; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory; import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedAASDescriptor; +import org.eclipse.basyx.extensions.aas.directory.tagged.api.TaggedSubmodelDescriptor; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; import org.eclipse.basyx.testsuite.regression.aas.registration.TestRegistryProviderSuite; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; @@ -41,16 +43,37 @@ public abstract class TestTaggedDirectorySuite extends TestRegistryProviderSuite protected final IIdentifier taggedAAS1 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedDirectoryAAS#001"); protected final IIdentifier taggedAAS2 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedDirectoryAAS#002"); protected final IIdentifier taggedAAS3 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedDirectoryAAS#003"); + protected final IIdentifier taggedAAS4 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedDirectoryAAS#004"); + protected final IIdentifier taggedAAS5 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedDirectoryAAS#005"); + + protected IIdentifier taggedSmId1 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedSM#001"); + protected IIdentifier taggedSmId2 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedSM#002"); + protected IIdentifier taggedSmId3 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:taggedSM#003"); + protected IIdentifier submodelId1 = new ModelUrn("urn:de.FHG:devices.es.iese/test:aas:1.0:1:submodel#001"); // IdShorts used in test cases protected final String taggedAasIdShort1 = "taggedAasIdShort1"; protected final String taggedAasIdShort2 = "taggedAasIdShort2"; protected final String taggedAasIdShort3 = "taggedAasIdShort3"; + protected final String taggedAasIdShort4 = "taggedAasIdShort4"; + protected final String taggedAasIdShort5 = "taggedAasIdShort5"; + + protected final String taggedSmIdShort1 = "taggedSubmodelIdShort1"; + protected final String taggedSmIdShort2 = "taggedSubmodelIdShort2"; + protected final String taggedSmIdShort3 = "taggedSubmodelIdShort3"; + protected final String submodelIdShort1 = "submodelIdShort1"; // Endpoints used in test cases protected final String taggedAasEndpoint1 = "http://www.registrytest.de/aas01/taggedaas"; protected final String taggedAasEndpoint2 = "http://www.registrytest.de/aas02/taggedaas"; protected final String taggedAasEndpoint3 = "http://www.registrytest.de/aas03/taggedaas"; + protected final String taggedAasEndpoint4 = "http://www.registrytest.de/aas04/taggedaas"; + protected final String taggedAasEndpoint5 = "http://www.registrytest.de/aas05/taggedaas"; + + protected String taggedSmEndpoint1 = "http://www.registrytest.de/aas01/taggedAas/submodel"; + protected String taggedSmEndpoint2 = "http://www.registrytest.de/aas02/taggedAas/submodel"; + protected String taggedSmEndpoint3 = "http://www.registrytest.de/aas03/taggedAas/submodel"; + protected String submodelEndpoint1 = "http://www.registrytest.de/aas01/taggedAas/submodel_not_tagged"; // Tags used in test cases protected final String DEVICE = "device"; @@ -59,6 +82,11 @@ public abstract class TestTaggedDirectorySuite extends TestRegistryProviderSuite protected final String MILL = "mill"; protected final String PACKAGER = "packager"; protected final String BASYS_READY = "basysReady"; + protected final String INTERNAL = "internal"; + protected final String INTEGRATOR = "integrator"; + protected final String MACHINE = "machine"; + protected final String KEY = "key"; + protected final String COMPONENT = "component"; /** * This method is not included in @Before to not interfere with test cases of @@ -80,6 +108,30 @@ private void init() { TaggedAASDescriptor desc3 = new TaggedAASDescriptor(taggedAasIdShort3, taggedAAS3, taggedAasEndpoint3); desc3.addTags(Arrays.asList(DEVICE, PACKAGER, SUPPLIER_B, BASYS_READY)); directory.register(desc3); + + TaggedAASDescriptor desc4 = new TaggedAASDescriptor(taggedAasIdShort4, taggedAAS4, taggedAasEndpoint4); + desc4.addTags(Arrays.asList(INTERNAL, INTEGRATOR, MACHINE)); + directory.register(desc4); + + TaggedSubmodelDescriptor taggedSmDesc1 = new TaggedSubmodelDescriptor(taggedSmIdShort1, taggedSmId1, taggedSmEndpoint1); + taggedSmDesc1.addTags(Arrays.asList(INTERNAL, INTEGRATOR, MACHINE)); + directory.registerSubmodel(taggedAAS4, taggedSmDesc1); + + TaggedAASDescriptor desc5 = new TaggedAASDescriptor(taggedAasIdShort5, taggedAAS5, taggedAasEndpoint5); + desc5.addTags(Arrays.asList(INTERNAL, MACHINE)); + + SubmodelDescriptor smDesc = new SubmodelDescriptor(submodelIdShort1, submodelId1, submodelEndpoint1); + desc5.addSubmodelDescriptor(smDesc); + + directory.register(desc5); + + TaggedSubmodelDescriptor taggedSmDesc2 = new TaggedSubmodelDescriptor(taggedSmIdShort2, taggedSmId2, taggedSmEndpoint2); + taggedSmDesc2.addTags(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + directory.registerSubmodel(taggedAAS5, taggedSmDesc2); + + TaggedSubmodelDescriptor taggedSmDesc3 = new TaggedSubmodelDescriptor(taggedSmIdShort3, taggedSmId3, taggedSmEndpoint3); + taggedSmDesc3.addTags(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + directory.registerSubmodel(taggedAAS5, taggedSmDesc3); } /** @@ -89,17 +141,47 @@ private void init() { @After public void tearDown() { try { - proxy.delete(taggedAAS1); + directory.delete(taggedAAS1); + } catch (ResourceNotFoundException e) { + // Does not matter + } + try { + directory.delete(taggedAAS2); + } catch (ResourceNotFoundException e) { + // Does not matter + } + try { + directory.delete(taggedAAS3); + } catch (ResourceNotFoundException e) { + // Does not matter + } + try { + directory.delete(taggedAAS4, taggedSmId1); + } catch (ResourceNotFoundException e) { + // Does not matter + } + try { + directory.delete(taggedAAS4); + } catch (ResourceNotFoundException e) { + // Does not matter + } + try { + directory.delete(taggedAAS5); } catch (ResourceNotFoundException e) { // Does not matter } try { - proxy.delete(taggedAAS2); + directory.delete(taggedAAS5, taggedSmId2); } catch (ResourceNotFoundException e) { // Does not matter } try { - proxy.delete(taggedAAS3); + directory.delete(taggedAAS5, taggedSmId3); + } catch (ResourceNotFoundException e) { + // Does not matter + } + try { + directory.delete(taggedAAS5, submodelId1); } catch (ResourceNotFoundException e) { // Does not matter } @@ -110,7 +192,7 @@ public void testRetrieveSingleTag() { init(); // Lookup a tag that all three AAS have assertEquals(3, directory.lookupTag(DEVICE).size()); - + // Lookup a tag that multiple, but not all AAS have Set packagers = directory.lookupTag(PACKAGER); assertEquals(2, packagers.size()); @@ -164,4 +246,149 @@ private void testDescriptorsExistance(Set descriptors, List }); } + @Test + public void testLookupTaggedSubmodelDescriptor() { + init(); + + Set descriptors = directory.lookupSubmodelTag(INTERNAL); + + assertEquals(1, descriptors.size()); + } + + @Test + public void testLookUpNonExistingSubmodelTag() { + init(); + + Set descriptors = directory.lookupSubmodelTag("non-existing-tag"); + + assertTrue(descriptors.isEmpty()); + } + + @Test + public void testLookUpMultipleSubmodelTags() { + init(); + + Set descriptors1 = directory.lookupSubmodelTags(new HashSet<>(Arrays.asList(INTERNAL, INTEGRATOR, MACHINE))); + + assertEquals(1, descriptors1.size()); + } + + @Test + public void testRegisterAndLookupAasAndSubmodelTags() { + init(); + + Set taggedSmDescriptors = directory.lookupSubmodelTags(new HashSet<>(Arrays.asList(INTERNAL, INTEGRATOR, MACHINE))); + + assertEquals(1, taggedSmDescriptors.size()); + + Set taggedAASDescriptors = directory.lookupTags(new HashSet<>(Arrays.asList(INTERNAL, INTEGRATOR, MACHINE))); + + assertEquals(1, taggedAASDescriptors.size()); + } + + @Test + public void testSameTagShouldOnlyBeAddedOnce() { + TaggedSubmodelDescriptor taggedSubmodelDescriptor = new TaggedSubmodelDescriptor(smIdShort1, smId1, smEndpoint1); + taggedSubmodelDescriptor.addTag("same-tag"); + taggedSubmodelDescriptor.addTag("same-tag"); + + assertEquals(1, taggedSubmodelDescriptor.getTags().size()); + } + + @Test + public void testLookUpBothAasAndSubmodelTags() { + init(); + + Set aasTags = new HashSet<>(Arrays.asList(INTERNAL, MACHINE)); + Set submodelTags = new HashSet<>(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + + Set taggedSmDescriptors = directory.lookupBothAasAndSubmodelTags(aasTags, submodelTags); + assertEquals(2, taggedSmDescriptors.size()); + + Set aasTags1 = new HashSet<>(Arrays.asList(INTERNAL)); + Set submodelTags1 = new HashSet<>(Arrays.asList(KEY, COMPONENT)); + + Set taggedSmDescriptors1 = directory.lookupBothAasAndSubmodelTags(aasTags1, submodelTags1); + assertEquals(2, taggedSmDescriptors1.size()); + } + + @Test + public void testLookupMultipleSubmodelDescriptors() { + init(); + + Set submodelTags1 = new HashSet<>(Arrays.asList(INTEGRATOR, COMPONENT)); + Set desc1 = directory.lookupSubmodelTags(submodelTags1); + assertEquals(2, desc1.size()); + + Set submodelTags2 = new HashSet<>(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + Set desc2 = directory.lookupSubmodelTags(submodelTags2); + assertEquals(2, desc2.size()); + + Set submodelTags3 = new HashSet<>(Collections.emptyList()); + Set desc3 = directory.lookupSubmodelTags(submodelTags3); + assertEquals(0, desc3.size()); + } + + @Test + public void testLookupAasTagsAndSubmodelTagsThatDontBelongTogether() { + init(); + + Set aasTags = new HashSet<>(Arrays.asList(DEVICE, PACKAGER, SUPPLIER_A, BASYS_READY)); + Set smTags = new HashSet<>(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + + Set taggedSmDescriptors = directory.lookupBothAasAndSubmodelTags(aasTags, smTags); + assertEquals(0, taggedSmDescriptors.size()); + } + + @Test + public void testLookUpBothAasAndSubmodelTagsWithEmptySets() { + init(); + + Set emptyTags = new HashSet<>(Arrays.asList()); + Set submodelTags = new HashSet<>(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + + Set taggedSmDescriptors = directory.lookupBothAasAndSubmodelTags(emptyTags, submodelTags); + assertEquals(0, taggedSmDescriptors.size()); + + Set aasTags1 = new HashSet<>(Arrays.asList(INTERNAL, MACHINE)); + + Set taggedSmDescriptors2 = directory.lookupBothAasAndSubmodelTags(aasTags1, emptyTags); + assertEquals(0, taggedSmDescriptors2.size()); + + Set taggedSmDescriptors3 = directory.lookupBothAasAndSubmodelTags(emptyTags, emptyTags); + + assertEquals(0, taggedSmDescriptors3.size()); + } + + @Test + public void testLookUpBothAasAndSubmodelTagsWithWildcard() { + init(); + + Set allTags = new HashSet<>(Arrays.asList("*")); + Set submodelTags = new HashSet<>(Arrays.asList(INTEGRATOR, KEY, COMPONENT)); + + Set taggedSmDescriptors = directory.lookupBothAasAndSubmodelTags(allTags, submodelTags); + assertEquals(2, taggedSmDescriptors.size()); + + Set aasTagsWithWildcard = new HashSet<>(Arrays.asList(INTERNAL, MACHINE, "*")); + + Set taggedSmDescriptors1 = directory.lookupBothAasAndSubmodelTags(aasTagsWithWildcard, submodelTags); + + assertEquals(2, taggedSmDescriptors1.size()); + + Set aasTags = new HashSet<>(Arrays.asList(INTERNAL, INTEGRATOR, MACHINE)); + + Set taggedSmDescriptors2 = directory.lookupBothAasAndSubmodelTags(aasTags, allTags); + assertEquals(1, taggedSmDescriptors2.size()); + + Set aasTags1 = new HashSet<>(Arrays.asList(INTERNAL, MACHINE)); + + Set taggedSmDescriptors3 = directory.lookupBothAasAndSubmodelTags(aasTags1, allTags); + assertEquals(4, taggedSmDescriptors3.size()); + + Set taggedSmDescriptors4 = directory.lookupBothAasAndSubmodelTags(allTags, allTags); + + assertEquals(0, taggedSmDescriptors4.size()); + + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java index 95455982..5f2fc79c 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/map/TestMapTaggedDirectory.java @@ -1,15 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.map; -import java.util.HashMap; +import java.util.LinkedHashMap; import org.eclipse.basyx.aas.registration.api.IAASRegistry; import org.eclipse.basyx.extensions.aas.directory.tagged.api.IAASTaggedDirectory; @@ -26,7 +41,7 @@ public class TestMapTaggedDirectory extends TestTaggedDirectorySuite { @Override protected IAASTaggedDirectory getDirectory() { - return new MapTaggedDirectory(new HashMap<>(), new HashMap<>()); + return new MapTaggedDirectory(new LinkedHashMap<>(), new LinkedHashMap<>()); } @Override diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java index 2e9470dd..fc1ab1c1 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/proxy/TestProxyTaggedDirectory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.proxy; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java index dd90a152..607d4c0e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/directory/tagged/servlet/TestTaggedDirectoryProviderHTTP.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.aas.directory.tagged.servlet; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/TestAuthorizedAASRegistry.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/TestAuthorizedAASRegistry.java new file mode 100644 index 00000000..0ad3ec1e --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/authorization/TestAuthorizedAASRegistry.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas.registration.authorization; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.extensions.aas.registration.authorization.AASRegistryScopes; +import org.eclipse.basyx.extensions.aas.registration.authorization.AuthorizedAASRegistry; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * Tests authorization with the AuthorizedAASRegistry + * + * @author pneuschwander + */ +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class TestAuthorizedAASRegistry { + + @Mock + private IAASRegistry registryMock; + private AuthorizedAASRegistry testSubject; + + private SecurityContext _getSecurityContextWithAuthorities(String... authorities) { + final SecurityContext context = SecurityContextHolder.createEmptyContext(); + final Authentication authentication = new TestingAuthenticationToken(null, null, authorities); + context.setAuthentication(authentication); + return context; + } + + private SecurityContext getEmptySecurityContext() { + return SecurityContextHolder.createEmptyContext(); + } + + private SecurityContext getSecurityContextWithoutAuthorities() { + return _getSecurityContextWithAuthorities(); + } + + private SecurityContext getSecurityContextWithReadAuthority() { + return _getSecurityContextWithAuthorities("SCOPE_" + AASRegistryScopes.READ_SCOPE); + } + + private SecurityContext getSecurityContextWithWriteAuthority() { + return _getSecurityContextWithAuthorities("SCOPE_" + AASRegistryScopes.WRITE_SCOPE); + } + + @Before + public void setUp() { + testSubject = new AuthorizedAASRegistry(registryMock); + } + + @After + public void tearDown() { + SecurityContextHolder.clearContext(); + Mockito.verifyNoMoreInteractions(registryMock); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenRegisterAAS_thenThrowProviderException() { + SecurityContextHolder.setContext(getEmptySecurityContext()); + + final AASDescriptor aasDescriptor = new AASDescriptor("test", new ModelUrn("urn:test"), "http://test.example/aas"); + testSubject.register(aasDescriptor); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenRegisterAASDescriptor_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithWriteAuthority()); + + final AASDescriptor aasDescriptor = new AASDescriptor("test", new ModelUrn("urn:test"), "http://test.example/aas"); + testSubject.register(aasDescriptor); + + Mockito.verify(registryMock).register(aasDescriptor); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingWriteAuthority_whenRegisterAASDescriptor_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final AASDescriptor aasDescriptor = new AASDescriptor("test", new ModelUrn("urn:test"), "http://test.example/aas"); + testSubject.register(aasDescriptor); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenRegisterSubmodelDescriptor_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithWriteAuthority()); + + final IIdentifier aas = new ModelUrn("urn:test"); + final SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor("test", new ModelUrn("urn:test"), "http://test.example/submodel"); + testSubject.register(aas, submodelDescriptor); + + Mockito.verify(registryMock).register(aas, submodelDescriptor); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingWriteAuthority_whenRegisterSubmodelDescriptor_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final IIdentifier aas = new ModelUrn("urn:test"); + final SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor("test", new ModelUrn("urn:test"), "http://test.example/submodel"); + testSubject.register(aas, submodelDescriptor); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenDeleteAAS_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithWriteAuthority()); + + final IIdentifier aasId = new ModelUrn("urn:test"); + testSubject.delete(aasId); + + Mockito.verify(registryMock).delete(aasId); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingWriteAuthority_whenDeleteAAS_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final IIdentifier aasId = new ModelUrn("urn:test"); + testSubject.delete(aasId); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenDeleteSubmodel_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithWriteAuthority()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + final IIdentifier smId = new ModelUrn("urn:test2"); + testSubject.delete(aasId, smId); + + Mockito.verify(registryMock).delete(aasId, smId); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingWriteAuthority_whenDeleteSubmodel_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + final IIdentifier smId = new ModelUrn("urn:test2"); + testSubject.delete(aasId, smId); + } + + @Test + public void givenPrincipalHasReadAuthority_whenLookupAAS_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithReadAuthority()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + final AASDescriptor expectedAASDescriptor = new AASDescriptor("test", aasId, "http://test.example/aas"); + Mockito.when(registryMock.lookupAAS(aasId)).thenReturn(expectedAASDescriptor); + + final AASDescriptor aasDescriptor = testSubject.lookupAAS(aasId); + + Assert.assertEquals(expectedAASDescriptor, aasDescriptor); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenLookupAAS_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + + testSubject.lookupAAS(aasId); + } + + @Test + public void givenPrincipalHasReadAuthority_whenLookupAll_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithReadAuthority()); + + final List expectedAASDescriptorList = Collections.singletonList(new AASDescriptor("test", new ModelUrn("urn:test"), "http://test.example/aas")); + Mockito.when(registryMock.lookupAll()).thenReturn(expectedAASDescriptorList); + + final List aasDescriptorList = testSubject.lookupAll(); + + Assert.assertEquals(expectedAASDescriptorList, aasDescriptorList); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenLookupAll_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + testSubject.lookupAll(); + } + + @Test + public void givenPrincipalHasReadAuthority_whenLookupSubmodels_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithReadAuthority()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + final List expectedSubmodelDescriptorList = Collections.singletonList(new SubmodelDescriptor("test", new ModelUrn("urn:test"), "http://test.example/submodel")); + Mockito.when(registryMock.lookupSubmodels(aasId)).thenReturn(expectedSubmodelDescriptorList); + + final List submodelDescriptorList = testSubject.lookupSubmodels(aasId); + + Assert.assertEquals(expectedSubmodelDescriptorList, submodelDescriptorList); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenLookupSubmodels_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + + testSubject.lookupSubmodels(aasId); + } + + @Test + public void givenPrincipalHasReadAuthority_whenLookupSubmodel_thenInvocationIsForwarded() { + SecurityContextHolder.setContext(getSecurityContextWithReadAuthority()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + final IIdentifier smId = new ModelUrn("urn:test2"); + final SubmodelDescriptor expectedSubmodelDescriptor = new SubmodelDescriptor("test", smId, "http://test.example/submodel"); + Mockito.when(registryMock.lookupSubmodel(aasId, smId)).thenReturn(expectedSubmodelDescriptor); + + final SubmodelDescriptor submodelDescriptor = testSubject.lookupSubmodel(aasId, smId); + + Assert.assertEquals(expectedSubmodelDescriptor, submodelDescriptor); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenLookupSubmodel_thenThrowProviderException() { + SecurityContextHolder.setContext(getSecurityContextWithoutAuthorities()); + + final IIdentifier aasId = new ModelUrn("urn:test1"); + final IIdentifier smId = new ModelUrn("urn:test2"); + + testSubject.lookupSubmodel(aasId, smId); + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java index e6f3ac39..5c0d0c5f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryService.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.aas.registration.mqtt; @@ -20,6 +35,7 @@ import org.eclipse.basyx.aas.metamodel.map.parts.Asset; import org.eclipse.basyx.aas.registration.api.IAASRegistry; import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; +import org.eclipse.basyx.extensions.aas.registration.mqtt.MqttAASRegistryHelper; import org.eclipse.basyx.extensions.aas.registration.mqtt.MqttAASRegistryService; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.map.Submodel; @@ -45,13 +61,13 @@ * */ public class TestMqttAASRegistryService { - + private static final String AASID = "aasid1"; private static final String SUBMODELID = "submodelid1"; private static final String AASENDPOINT = "http://localhost:8080/aasList/" + AASID + "/aas"; private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID); private static final Identifier SUBMODELIDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODELID); - + private static Server mqttBroker; private static MqttAASRegistryService eventAPI; private MqttTestListener listener; @@ -69,7 +85,7 @@ public static void setUpClass() throws MqttException, IOException { // Create underlying registry service IAASRegistry registryService = new InMemoryRegistry(); - + eventAPI = new MqttAASRegistryService(registryService, "tcp://localhost:1884", "testClient"); } @@ -77,41 +93,41 @@ public static void setUpClass() throws MqttException, IOException { public static void tearDownClass() { mqttBroker.stopServer(); } - + @Before public void setUp() { AssetAdministrationShell shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE)); AASDescriptor aasDescriptor = new AASDescriptor(shell, AASENDPOINT); eventAPI.register(aasDescriptor); - + Submodel submodel = new Submodel(SUBMODELID, SUBMODELIDENTIFIER); String submodelEndpoint = AASENDPOINT + "/submodels/" + SUBMODELID + "/submodel"; SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint); eventAPI.register(AASIDENTIFIER, submodelDescriptor); - + listener = new MqttTestListener(); mqttBroker.addInterceptHandler(listener); } - + @After public void tearDown() { mqttBroker.removeInterceptHandler(listener); } - + @Test public void testRegisterAAS() { String newAASId = "aasid2"; Identifier newIdentifier = new Identifier(IdentifierType.IRI, newAASId); AssetAdministrationShell shell = new AssetAdministrationShell(newAASId, newIdentifier, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE)); String aasEndpoint = "http://localhost:8080/aasList/" + newAASId + "/aas"; - + AASDescriptor aasDescriptor = new AASDescriptor(shell, aasEndpoint); eventAPI.register(aasDescriptor); - + assertEquals(newAASId, listener.lastPayload); - assertEquals(MqttAASRegistryService.TOPIC_REGISTERAAS, listener.lastTopic); + assertEquals(MqttAASRegistryHelper.TOPIC_REGISTERAAS, listener.lastTopic); } - + @Test public void testRegisterSubmodel() { String submodelid = "submodelid2"; @@ -119,26 +135,26 @@ public void testRegisterSubmodel() { Submodel submodel = new Submodel(submodelid, newSubmodelIdentifier); String submodelEndpoint = AASENDPOINT + "/submodels/" + submodelid + "/submodel"; SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint); - + eventAPI.register(AASIDENTIFIER, submodelDescriptor); - - assertEquals(MqttAASRegistryService.concatAasSmId(AASIDENTIFIER, newSubmodelIdentifier), listener.lastPayload); - assertEquals(MqttAASRegistryService.TOPIC_REGISTERSUBMODEL, listener.lastTopic); + + assertEquals(MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(AASIDENTIFIER, newSubmodelIdentifier), listener.lastPayload); + assertEquals(MqttAASRegistryHelper.TOPIC_REGISTERSUBMODEL, listener.lastTopic); } - + @Test public void testDeleteAAS() { eventAPI.delete(AASIDENTIFIER); - + assertEquals(AASID, listener.lastPayload); - assertEquals(MqttAASRegistryService.TOPIC_DELETEAAS, listener.lastTopic); + assertEquals(MqttAASRegistryHelper.TOPIC_DELETEAAS, listener.lastTopic); } - + @Test public void testDeleteSubmodel() { eventAPI.delete(AASIDENTIFIER, SUBMODELIDENTIFIER); - assertEquals(MqttAASRegistryService.concatAasSmId(AASIDENTIFIER, SUBMODELIDENTIFIER), listener.lastPayload); - assertEquals(MqttAASRegistryService.TOPIC_DELETESUBMODEL, listener.lastTopic); + assertEquals(MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(AASIDENTIFIER, SUBMODELIDENTIFIER), listener.lastPayload); + assertEquals(MqttAASRegistryHelper.TOPIC_DELETESUBMODEL, listener.lastTopic); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryServiceObserver.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryServiceObserver.java new file mode 100644 index 00000000..4d402995 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/aas/registration/mqtt/TestMqttAASRegistryServiceObserver.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.aas.registration.mqtt; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.eclipse.basyx.aas.metamodel.api.parts.asset.AssetKind; +import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; +import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; +import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor; +import org.eclipse.basyx.aas.metamodel.map.parts.Asset; +import org.eclipse.basyx.aas.registration.api.IAASRegistry; +import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry; +import org.eclipse.basyx.aas.registration.observing.ObservableAASRegistryService; +import org.eclipse.basyx.extensions.aas.registration.mqtt.MqttAASRegistryHelper; +import org.eclipse.basyx.extensions.aas.registration.mqtt.MqttAASRegistryServiceObserver; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; +import io.moquette.broker.config.ClasspathResourceLoader; +import io.moquette.broker.config.IConfig; +import io.moquette.broker.config.IResourceLoader; +import io.moquette.broker.config.ResourceLoaderConfig; + +/** + * Tests events emitting with the MqttAASRegistryServiceObserver + * + * @author haque + * + */ +public class TestMqttAASRegistryServiceObserver { + + private static final String AASID = "aasid1"; + private static final String SUBMODELID = "submodelid1"; + private static final String AASENDPOINT = "http://localhost:8080/aasList/" + AASID + "/aas"; + private static final Identifier AASIDENTIFIER = new Identifier(IdentifierType.IRI, AASID); + private static final Identifier SUBMODELIDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODELID); + + private static Server mqttBroker; + private static ObservableAASRegistryService observedAPI; + private static MqttAASRegistryServiceObserver mqttObserver; + private MqttTestListener listener; + + /** + * Sets up the MQTT broker and AASRegistryService for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + // Start MQTT broker + mqttBroker = new Server(); + IResourceLoader classpathLoader = new ClasspathResourceLoader(); + final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); + mqttBroker.startServer(classPathConfig); + + // Create underlying registry service + IAASRegistry registryService = new InMemoryRegistry(); + observedAPI = new ObservableAASRegistryService(registryService); + + mqttObserver = new MqttAASRegistryServiceObserver("tcp://localhost:1884", "testClient"); + observedAPI.addObserver(mqttObserver); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.stopServer(); + } + + @Before + public void setUp() { + AssetAdministrationShell shell = new AssetAdministrationShell(AASID, AASIDENTIFIER, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid1"), AssetKind.INSTANCE)); + AASDescriptor aasDescriptor = new AASDescriptor(shell, AASENDPOINT); + observedAPI.register(aasDescriptor); + + Submodel submodel = new Submodel(SUBMODELID, SUBMODELIDENTIFIER); + String submodelEndpoint = AASENDPOINT + "/submodels/" + SUBMODELID + "/submodel"; + SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint); + observedAPI.register(AASIDENTIFIER, submodelDescriptor); + + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + } + + @After + public void tearDown() { + mqttBroker.removeInterceptHandler(listener); + } + + @Test + public void testRegisterAAS() { + String newAASId = "aasid2"; + Identifier newIdentifier = new Identifier(IdentifierType.IRI, newAASId); + AssetAdministrationShell shell = new AssetAdministrationShell(newAASId, newIdentifier, new Asset("assetid1", new Identifier(IdentifierType.IRI, "assetid2"), AssetKind.INSTANCE)); + String aasEndpoint = "http://localhost:8080/aasList/" + newAASId + "/aas"; + + AASDescriptor aasDescriptor = new AASDescriptor(shell, aasEndpoint); + observedAPI.register(aasDescriptor); + + assertEquals(newAASId, listener.lastPayload); + assertEquals(MqttAASRegistryHelper.TOPIC_REGISTERAAS, listener.lastTopic); + } + + @Test + public void testRegisterSubmodel() { + String submodelid = "submodelid2"; + Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRI, submodelid); + Submodel submodel = new Submodel(submodelid, newSubmodelIdentifier); + String submodelEndpoint = AASENDPOINT + "/submodels/" + submodelid + "/submodel"; + SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(submodel, submodelEndpoint); + + observedAPI.register(AASIDENTIFIER, submodelDescriptor); + + assertEquals(MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(AASIDENTIFIER, newSubmodelIdentifier), listener.lastPayload); + assertEquals(MqttAASRegistryHelper.TOPIC_REGISTERSUBMODEL, listener.lastTopic); + } + + @Test + public void testDeleteAAS() { + observedAPI.delete(AASIDENTIFIER); + + assertEquals(AASID, listener.lastPayload); + assertEquals(MqttAASRegistryHelper.TOPIC_DELETEAAS, listener.lastTopic); + } + + @Test + public void testDeleteSubmodel() { + observedAPI.delete(AASIDENTIFIER, SUBMODELIDENTIFIER); + + assertEquals(MqttAASRegistryHelper.createSubmodelDescriptorOfAASChangedPayload(AASIDENTIFIER, SUBMODELIDENTIFIER), listener.lastPayload); + assertEquals(MqttAASRegistryHelper.TOPIC_DELETESUBMODEL, listener.lastTopic); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/AuthorizationContextProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/AuthorizationContextProvider.java new file mode 100644 index 00000000..159fa0e1 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/AuthorizationContextProvider.java @@ -0,0 +1,54 @@ +package org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt; + +import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * Can set various types of SecurityContexts for test purposes for testing + * invalid, read or write access. + * + * @author espen + * + */ +public class AuthorizationContextProvider { + private final String READ_SCOPE; + private final String WRITE_SCOPE; + + public AuthorizationContextProvider(String readScope, String writeScope) { + READ_SCOPE = readScope; + WRITE_SCOPE = writeScope; + } + + private SecurityContext _getSecurityContextWithAuthorities(String... authorities) { + final SecurityContext context = SecurityContextHolder.createEmptyContext(); + final Authentication authentication = new TestingAuthenticationToken(null, null, authorities); + context.setAuthentication(authentication); + return context; + } + + public void setEmptySecurityContext() { + SecurityContext context = SecurityContextHolder.createEmptyContext(); + SecurityContextHolder.setContext(context); + } + + public void setSecurityContextWithoutAuthorities() { + SecurityContext context = _getSecurityContextWithAuthorities(); + SecurityContextHolder.setContext(context); + } + + public void setSecurityContextWithReadAuthority() { + SecurityContext context = _getSecurityContextWithAuthorities(READ_SCOPE); + SecurityContextHolder.setContext(context); + } + + public void setSecurityContextWithWriteAuthority() { + SecurityContext context = _getSecurityContextWithAuthorities(WRITE_SCOPE); + SecurityContextHolder.setContext(context); + } + + public void clearContext() { + SecurityContextHolder.clearContext(); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java index ab2d192b..c67cc108 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/shared/mqtt/MqttTestListener.java @@ -1,15 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import io.moquette.interception.InterceptHandler; import io.moquette.interception.messages.InterceptAcknowledgedMessage; @@ -21,8 +37,8 @@ import io.moquette.interception.messages.InterceptUnsubscribeMessage; /** - * Very simple MQTT broker listener for testing Submodel API events. - * Stores the last received event and makes its topic and payload available for reading. + * Very simple MQTT broker listener for testing Submodel API events. Stores the + * last received event and makes its topic and payload available for reading. * * @author espen * @@ -31,6 +47,7 @@ public class MqttTestListener implements InterceptHandler { // Topic and payload of the most recent event public String lastTopic; public String lastPayload; + private ArrayList topics = new ArrayList<>(); @Override public String getID() { @@ -59,7 +76,8 @@ public void onMessageAcknowledged(InterceptAcknowledgedMessage arg0) { } @Override - public void onPublish(InterceptPublishMessage msg) { + public synchronized void onPublish(InterceptPublishMessage msg) { + topics.add(msg.getTopicName()); lastTopic = msg.getTopicName(); lastPayload = msg.getPayload().toString(StandardCharsets.UTF_8); } @@ -71,4 +89,8 @@ public void onSubscribe(InterceptSubscribeMessage arg0) { @Override public void onUnsubscribe(InterceptUnsubscribeMessage arg0) { } + + public ArrayList getTopics() { + return topics; + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/TestAuthorizedSubmodelAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/TestAuthorizedSubmodelAggregator.java new file mode 100644 index 00000000..20a64246 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/authorization/TestAuthorizedSubmodelAggregator.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.submodel.aggregator.authorization; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.basyx.extensions.submodel.aggregator.authorization.AuthorizedSubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.AuthorizationContextProvider; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Tests authorization with the AuthorizedSubmodelAggregator + * + * @author espen + * + */ +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class TestAuthorizedSubmodelAggregator { + @Mock + private ISubmodelAggregator aggregatorMock; + private AuthorizedSubmodelAggregator authorizedSubmodelAggregator; + + protected static Submodel submodel; + protected static ISubmodelAPI submodelAPI; + private static final String SUBMODEL_IDSHORT = "submodelIdShort"; + private static final String SUBMODEL_ID = "submodelId"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + + private AuthorizationContextProvider securityContextProvider = new AuthorizationContextProvider(AuthorizedSubmodelAggregator.READ_AUTHORITY, AuthorizedSubmodelAggregator.WRITE_AUTHORITY); + + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + submodel = new Submodel(SUBMODEL_IDSHORT, SUBMODEL_IDENTIFIER); + submodelAPI = new VABSubmodelAPI(new VABMapProvider(submodel)); + } + + @Before + public void setUp() { + authorizedSubmodelAggregator = new AuthorizedSubmodelAggregator(aggregatorMock); + } + + @After + public void tearDown() { + securityContextProvider.clearContext(); + Mockito.verifyNoMoreInteractions(aggregatorMock); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelList_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.getSubmodelList(); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelList_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.getSubmodelList(); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelList_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Collection expectedList = new ArrayList<>(); + expectedList.add(submodel); + Mockito.when(aggregatorMock.getSubmodelList()).thenReturn(expectedList); + Collection smList = authorizedSubmodelAggregator.getSubmodelList(); + assertEquals(expectedList, smList); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodel_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.getSubmodel(SUBMODEL_IDENTIFIER); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodel_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.getSubmodel(SUBMODEL_IDENTIFIER); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodel_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(aggregatorMock.getSubmodel(SUBMODEL_IDENTIFIER)).thenReturn(submodel); + ISubmodel returnedSubmodel = authorizedSubmodelAggregator.getSubmodel(SUBMODEL_IDENTIFIER); + assertEquals(submodel, returnedSubmodel); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whengetSubmodelbyIdShort_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.getSubmodelbyIdShort(SUBMODEL_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whengetSubmodelbyIdShort_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.getSubmodelbyIdShort(SUBMODEL_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelbyIdShort_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(aggregatorMock.getSubmodelbyIdShort(SUBMODEL_IDSHORT)).thenReturn(submodel); + ISubmodel returnedSubmodel = authorizedSubmodelAggregator.getSubmodelbyIdShort(SUBMODEL_IDSHORT); + assertEquals(submodel, returnedSubmodel); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelAPIById_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.getSubmodelAPIById(SUBMODEL_IDENTIFIER); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelAPIById_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.getSubmodelAPIById(SUBMODEL_IDENTIFIER); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelAPIById_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(aggregatorMock.getSubmodelAPIById(SUBMODEL_IDENTIFIER)).thenReturn(submodelAPI); + ISubmodelAPI returnedSubmodelAPI = authorizedSubmodelAggregator.getSubmodelAPIById(SUBMODEL_IDENTIFIER); + assertEquals(submodelAPI, returnedSubmodelAPI); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelAPIByIdShort_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(aggregatorMock.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT)).thenReturn(submodelAPI); + ISubmodelAPI returnedSubmodelAPI = authorizedSubmodelAggregator.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT); + assertEquals(submodelAPI, returnedSubmodelAPI); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelAPIByIdShort_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelAPIByIdShort_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.getSubmodelAPIByIdShort(SUBMODEL_IDSHORT); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenCreateSubmodel_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAggregator.createSubmodel(submodel); + Mockito.verify(aggregatorMock).createSubmodel(submodel); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenCreateSubmodel_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.createSubmodel(submodel); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenCreateSubmodel_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.createSubmodel(submodel); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenCreateSubmodelAPI_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAggregator.createSubmodel(submodelAPI); + Mockito.verify(aggregatorMock).createSubmodel(submodelAPI); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenCreateSubmodelAPI_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.createSubmodel(submodelAPI); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenCreateSubmodelAPI_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.createSubmodel(submodelAPI); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenUpdateSubmodel_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAggregator.updateSubmodel(submodel); + Mockito.verify(aggregatorMock).updateSubmodel(submodel); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenUpdateSubmodel_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.updateSubmodel(submodel); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenUpdateSubmodel_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.updateSubmodel(submodel); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenDeleteSubmodelByIdentifier_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + Mockito.verify(aggregatorMock).deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenDeleteSubmodelByIdentifier_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenDeleteSubmodelByIdentifier_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenDeleteSubmodelByIdShort_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAggregator.deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + Mockito.verify(aggregatorMock).deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenDeleteSubmodelByIdShort_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAggregator.deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenDeleteSubmodelByIdShort_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAggregator.deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/mqtt/TestMqttSubmodelAggregator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/mqtt/TestMqttSubmodelAggregator.java new file mode 100644 index 00000000..956c3f27 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/mqtt/TestMqttSubmodelAggregator.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.submodel.aggregator.mqtt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.eclipse.basyx.extensions.submodel.aggregator.mqtt.MqttDecoratingSubmodelAggregatorFactory; +import org.eclipse.basyx.extensions.submodel.aggregator.mqtt.MqttSubmodelAggregatorHelper; +import org.eclipse.basyx.submodel.aggregator.SubmodelAggregatorFactory; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; +import io.moquette.broker.config.ClasspathResourceLoader; +import io.moquette.broker.config.IConfig; +import io.moquette.broker.config.IResourceLoader; +import io.moquette.broker.config.ResourceLoaderConfig; + +/** + * Tests events emitting with the MqttSubmodelAggregator + * + * @author fischer, jungjan, fried + * + */ +public class TestMqttSubmodelAggregator { + protected Submodel submodel; + private static final String SUBMODEL_IDSHORT = "submodelIdShort"; + private static final String SUBMODEL_ID = "submodelId"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + + private static Server mqttBroker; + private static ISubmodelAggregator mqttSubmodelAggregator; + private static MqttTestListener listener; + + /** + * Sets up the MQTT broker and SubmodelAggregator for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + // Start MQTT broker + mqttBroker = new Server(); + IResourceLoader classpathLoader = new ClasspathResourceLoader(); + final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); + mqttBroker.startServer(classPathConfig); + + MqttClient client = new MqttClient("tcp://localhost:1884", "testClient"); + client.connect(); + + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + mqttSubmodelAggregator = new MqttDecoratingSubmodelAggregatorFactory(new SubmodelAggregatorFactory(), client).create(); + } + + @Before + public void setUp() { + submodel = new Submodel(SUBMODEL_IDSHORT, SUBMODEL_IDENTIFIER); + mqttSubmodelAggregator.createSubmodel(submodel); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.removeInterceptHandler(listener); + mqttBroker.stopServer(); + } + + @Test + public void testCreateSubmodel() { + String newSubmodelIdShort = "newSubmodelIdShort"; + String newSubmodelId = "newSubmodelId"; + Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRDI, newSubmodelId); + Submodel newSubmodel = new Submodel(newSubmodelIdShort, newSubmodelIdentifier); + mqttSubmodelAggregator.createSubmodel(newSubmodel); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, newSubmodelId), listener.lastPayload); + assertTrue(listenerHasTopic(MqttSubmodelAggregatorHelper.TOPIC_CREATESUBMODEL)); + } + + @Test + public void testUpdateSubmodel() { + submodel.setCategory("newCategory"); + mqttSubmodelAggregator.updateSubmodel(submodel); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, SUBMODEL_ID), listener.lastPayload); + assertTrue(listenerHasTopic(MqttSubmodelAggregatorHelper.TOPIC_UPDATESUBMODEL)); + } + + @Test + public void testDeleteSubmodelByIdentifier() { + mqttSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, SUBMODEL_ID), listener.lastPayload); + assertTrue(listenerHasTopic(MqttSubmodelAggregatorHelper.TOPIC_DELETESUBMODEL)); + } + + @Test + public void testDeleteSubmodelByIdShort() { + mqttSubmodelAggregator.deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, SUBMODEL_ID), listener.lastPayload); + assertTrue(listenerHasTopic(MqttSubmodelAggregatorHelper.TOPIC_DELETESUBMODEL)); + } + + private boolean listenerHasTopic(String expectedTopic) { + return listener.getTopics().stream().anyMatch(t -> t.equals(expectedTopic)); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/mqtt/TestMqttSubmodelAggregatorObserver.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/mqtt/TestMqttSubmodelAggregatorObserver.java new file mode 100644 index 00000000..3f056910 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/aggregator/mqtt/TestMqttSubmodelAggregatorObserver.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.submodel.aggregator.mqtt; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.eclipse.basyx.extensions.submodel.aggregator.mqtt.MqttSubmodelAggregatorHelper; +import org.eclipse.basyx.extensions.submodel.aggregator.mqtt.MqttSubmodelAggregatorObserver; +import org.eclipse.basyx.submodel.aggregator.SubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.observing.ObservableSubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; +import io.moquette.broker.config.ClasspathResourceLoader; +import io.moquette.broker.config.IConfig; +import io.moquette.broker.config.IResourceLoader; +import io.moquette.broker.config.ResourceLoaderConfig; + +/** + * Tests events emitting with the MqttSubmodelAggregatorObserver + * + * @author fischer, jungjan + * + */ +public class TestMqttSubmodelAggregatorObserver { + protected Submodel submodel; + private static final String SUBMODEL_IDSHORT = "submodelIdShort"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_IDSHORT); + + private static Server mqttBroker; + private static ObservableSubmodelAggregator observedSubmodelAggregator; + private static MqttSubmodelAggregatorObserver mqttSubmodelAggregatorObserver; + private MqttTestListener listener; + + /** + * Sets up the MQTT broker and ObservableSubmodelAggregator for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + // Start MQTT broker + mqttBroker = new Server(); + IResourceLoader classpathLoader = new ClasspathResourceLoader(); + final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); + mqttBroker.startServer(classPathConfig); + + // Create underlying submodel aggregator + ISubmodelAggregator submodelAggregator = new SubmodelAggregator(); + observedSubmodelAggregator = new ObservableSubmodelAggregator(submodelAggregator); + + // Create mqtt as an observer + mqttSubmodelAggregatorObserver = new MqttSubmodelAggregatorObserver("tcp://localhost:1884", "testClient"); + observedSubmodelAggregator.addObserver(mqttSubmodelAggregatorObserver); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.stopServer(); + } + + @Before + public void setUp() { + submodel = new Submodel(SUBMODEL_IDSHORT, SUBMODEL_IDENTIFIER); + observedSubmodelAggregator.createSubmodel(submodel); + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + } + + @After + public void tearDown() { + mqttBroker.removeInterceptHandler(listener); + } + + @Test + public void testCreateSubmodel() { + String newSubmodelIdShort = "newSubmodelIdShort"; + String newSubmodelId = "newSubmodelId"; + Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRDI, newSubmodelId); + Submodel newSubmodel = new Submodel(newSubmodelIdShort, newSubmodelIdentifier); + observedSubmodelAggregator.createSubmodel(newSubmodel); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, newSubmodelId), listener.lastPayload); + assertEquals(MqttSubmodelAggregatorHelper.TOPIC_CREATESUBMODEL, listener.lastTopic); + } + + @Test + public void testUpdateSubmodel() { + submodel.setCategory("newCategory"); + observedSubmodelAggregator.updateSubmodel(submodel); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, SUBMODEL_IDSHORT), listener.lastPayload); + assertEquals(MqttSubmodelAggregatorHelper.TOPIC_UPDATESUBMODEL, listener.lastTopic); + } + + @Test + public void testDeleteSubmodelByIdentifier() { + observedSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, SUBMODEL_IDSHORT), listener.lastPayload); + assertEquals(MqttSubmodelAggregatorHelper.TOPIC_DELETESUBMODEL, listener.lastTopic); + } + + @Test + public void testDeleteSubmodelByIdShort() { + observedSubmodelAggregator.deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + + assertEquals(MqttSubmodelAggregatorHelper.getCombinedMessage(null, SUBMODEL_IDSHORT), listener.lastPayload); + assertEquals(MqttSubmodelAggregatorHelper.TOPIC_DELETESUBMODEL, listener.lastTopic); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/TestAuthorizedSubmodelAPI.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/TestAuthorizedSubmodelAPI.java new file mode 100644 index 00000000..3ee866e9 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/authorization/TestAuthorizedSubmodelAPI.java @@ -0,0 +1,335 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.submodel.authorization; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.basyx.extensions.submodel.authorization.AuthorizedSubmodelAPI; +import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.AuthorizationContextProvider; +import org.eclipse.basyx.vab.exception.provider.ProviderException; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Tests authorization with the AuthorizedSubmodelAggregator + * + * @author espen + * + */ +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class TestAuthorizedSubmodelAPI { + @Mock + private ISubmodelAPI apiMock; + private AuthorizedSubmodelAPI authorizedSubmodelAPI; + + protected static Submodel submodel; + private static final String SUBMODEL_IDSHORT = "submodelIdShort"; + private static final String SUBMODEL_ID = "submodelId"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + private static final String PROPERTY_IDSHORT = "testProp"; + private static final boolean PROPERTY_VALUE = true; + private static final ISubmodelElement PROPERTY = new Property(PROPERTY_IDSHORT, PROPERTY_VALUE); + private static final String OPERATION_IDSHORT = "testOperation"; + private static final String ASYNC_REQUEST_ID = "requestId"; + private static final IOperation OPERATION = new Operation(OPERATION_IDSHORT); + + private AuthorizationContextProvider securityContextProvider = new AuthorizationContextProvider(AuthorizedSubmodelAPI.READ_AUTHORITY, AuthorizedSubmodelAPI.WRITE_AUTHORITY); + + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + submodel = new Submodel(SUBMODEL_IDSHORT, SUBMODEL_IDENTIFIER); + } + + @Before + public void setUp() { + authorizedSubmodelAPI = new AuthorizedSubmodelAPI(apiMock); + } + + @After + public void tearDown() { + securityContextProvider.clearContext(); + Mockito.verifyNoMoreInteractions(apiMock); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodel_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getSubmodel(); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodel_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getSubmodel(); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodel_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.getSubmodel()).thenReturn(submodel); + ISubmodel returnedSubmodel = authorizedSubmodelAPI.getSubmodel(); + assertEquals(submodel, returnedSubmodel); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenAddSubmodelElement_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.addSubmodelElement(PROPERTY); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenAddSubmodelElement_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.addSubmodelElement(PROPERTY); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenAddSubmodelElement_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAPI.addSubmodelElement(PROPERTY); + Mockito.verify(apiMock).addSubmodelElement(PROPERTY); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenAddSubmodelElementWithPath_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.addSubmodelElement(PROPERTY_IDSHORT, PROPERTY); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenAddSubmodelElementWithPath_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.addSubmodelElement(PROPERTY_IDSHORT, PROPERTY); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenAddSubmodelElementWithPath_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAPI.addSubmodelElement(PROPERTY_IDSHORT, PROPERTY); + Mockito.verify(apiMock).addSubmodelElement(PROPERTY_IDSHORT, PROPERTY); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenDeleteSubmodelElement_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.deleteSubmodelElement(PROPERTY_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenDeleteSubmodelElement_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.deleteSubmodelElement(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenDeleteSubmodelElement_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAPI.deleteSubmodelElement(PROPERTY_IDSHORT); + Mockito.verify(apiMock).deleteSubmodelElement(PROPERTY_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenUpdateSubmodelElement_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.updateSubmodelElement(PROPERTY_IDSHORT, PROPERTY_VALUE); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenUpdateSubmodelElement_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.updateSubmodelElement(PROPERTY_IDSHORT, PROPERTY_VALUE); + } + + @Test + public void givenPrincipalHasWriteAuthority_whenUpdateSubmodelElement_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithWriteAuthority(); + authorizedSubmodelAPI.updateSubmodelElement(PROPERTY_IDSHORT, PROPERTY_VALUE); + Mockito.verify(apiMock).updateSubmodelElement(PROPERTY_IDSHORT, PROPERTY_VALUE); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelElement_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getSubmodelElement(PROPERTY_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelElement_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getSubmodelElement(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelElement_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.getSubmodelElement(PROPERTY_IDSHORT)).thenReturn(PROPERTY); + ISubmodelElement returnedProperty = authorizedSubmodelAPI.getSubmodelElement(PROPERTY_IDSHORT); + assertEquals(PROPERTY, returnedProperty); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetOperations_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getOperations(); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetOperations_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getOperations(); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetOperations_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Collection expectedOperations = new ArrayList<>(); + expectedOperations.add(OPERATION); + Mockito.when(apiMock.getOperations()).thenReturn(expectedOperations); + Collection returnedOperations = authorizedSubmodelAPI.getOperations(); + assertEquals(expectedOperations, returnedOperations); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelElements_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getSubmodelElements(); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelElements_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getSubmodelElements(); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelElements_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Collection expectedElements = new ArrayList<>(); + expectedElements.add(PROPERTY); + Mockito.when(apiMock.getSubmodelElements()).thenReturn(expectedElements); + Collection returnedElements = authorizedSubmodelAPI.getSubmodelElements(); + assertEquals(expectedElements, returnedElements); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetSubmodelElementValue_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getSubmodelElementValue(PROPERTY_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetSubmodelElementValue_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getSubmodelElementValue(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetSubmodelElementValue_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.getSubmodelElementValue(PROPERTY_IDSHORT)).thenReturn(PROPERTY_VALUE); + Object returnedValue = authorizedSubmodelAPI.getSubmodelElementValue(PROPERTY_IDSHORT); + assertEquals(PROPERTY_VALUE, returnedValue); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenInvokeOperation_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.invokeOperation(PROPERTY_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenInvokeOperation_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.invokeOperation(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenInvokeOperation_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.invokeOperation(PROPERTY_IDSHORT)).thenReturn(PROPERTY_VALUE); + Object returnedValue = authorizedSubmodelAPI.invokeOperation(PROPERTY_IDSHORT); + assertEquals(PROPERTY_VALUE, returnedValue); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenInvokeAsync_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.invokeAsync(PROPERTY_IDSHORT); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenInvokeAsync_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.invokeAsync(PROPERTY_IDSHORT); + } + + @Test + public void givenPrincipalHasReadAuthority_whenInvokeAsync_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.invokeAsync(PROPERTY_IDSHORT)).thenReturn(PROPERTY_VALUE); + Object returnedValue = authorizedSubmodelAPI.invokeAsync(PROPERTY_IDSHORT); + assertEquals(PROPERTY_VALUE, returnedValue); + } + + @Test(expected = ProviderException.class) + public void givenPrincipalIsMissingReadAuthority_whenGetOperationResult_thenThrowProviderException() { + securityContextProvider.setSecurityContextWithoutAuthorities(); + authorizedSubmodelAPI.getOperationResult(PROPERTY_IDSHORT, ASYNC_REQUEST_ID); + } + + @Test(expected = ProviderException.class) + public void givenSecurityContextIsEmpty_whenGetOperationResult_ThrowProviderException() { + securityContextProvider.setEmptySecurityContext(); + authorizedSubmodelAPI.getOperationResult(PROPERTY_IDSHORT, ASYNC_REQUEST_ID); + } + + @Test + public void givenPrincipalHasReadAuthority_whenGetOperationResult_thenInvocationIsForwarded() { + securityContextProvider.setSecurityContextWithReadAuthority(); + Mockito.when(apiMock.getOperationResult(PROPERTY_IDSHORT, ASYNC_REQUEST_ID)).thenReturn(PROPERTY_VALUE); + Object returnedValue = authorizedSubmodelAPI.getOperationResult(PROPERTY_IDSHORT, ASYNC_REQUEST_ID); + assertEquals(PROPERTY_VALUE, returnedValue); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/MqttSubmodelAPIObserverTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/MqttSubmodelAPIObserverTest.java new file mode 100644 index 00000000..4c5775a5 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/MqttSubmodelAPIObserverTest.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.extensions.submodel.mqtt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.io.IOException; + +import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPIHelper; +import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPIObserver; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.metamodel.map.reference.Key; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.restapi.observing.ObservableSubmodelAPI; +import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI; +import org.eclipse.basyx.testsuite.regression.extensions.shared.mqtt.MqttTestListener; +import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.moquette.broker.Server; +import io.moquette.broker.config.ClasspathResourceLoader; +import io.moquette.broker.config.IConfig; +import io.moquette.broker.config.IResourceLoader; +import io.moquette.broker.config.ResourceLoaderConfig; + +/** + * Test for MqttSubmodelAPIObserver + * + * @author espen, conradi + * + */ +public class MqttSubmodelAPIObserverTest { + private static final String AASID = "testaasid"; + private static final String SUBMODELID = "testsubmodelid"; + + private static Server mqttBroker; + private static ObservableSubmodelAPI observableAPI; + private MqttTestListener listener; + + /** + * Sets up the MQTT broker and submodelAPI for tests + */ + @BeforeClass + public static void setUpClass() throws MqttException, IOException { + // Start MQTT broker + mqttBroker = new Server(); + IResourceLoader classpathLoader = new ClasspathResourceLoader(); + final IConfig classPathConfig = new ResourceLoaderConfig(classpathLoader); + mqttBroker.startServer(classPathConfig); + + // Create submodel + Submodel sm = new Submodel(SUBMODELID, new Identifier(IdentifierType.CUSTOM, SUBMODELID)); + Reference parentRef = new Reference(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID, IdentifierType.IRDI)); + sm.setParent(parentRef); + + VABSubmodelAPI vabAPI = new VABSubmodelAPI(new VABMapProvider(sm)); + observableAPI = new ObservableSubmodelAPI(vabAPI); + new MqttSubmodelAPIObserver(observableAPI, "tcp://localhost:1884", "testClient"); + } + + @AfterClass + public static void tearDownClass() { + mqttBroker.stopServer(); + } + + @Before + public void setUp() { + listener = new MqttTestListener(); + mqttBroker.addInterceptHandler(listener); + } + + @After + public void tearDown() { + mqttBroker.removeInterceptHandler(listener); + } + + @Test + public void testAddSubmodelElement() throws InterruptedException { + String elemIdShort = "testAddProp"; + Property prop = new Property(true); + prop.setIdShort(elemIdShort); + observableAPI.addSubmodelElement(prop); + + assertEquals(MqttSubmodelAPIObserver.getCombinedMessage(AASID, SUBMODELID, elemIdShort), listener.lastPayload); + assertEquals(MqttSubmodelAPIHelper.TOPIC_ADDELEMENT, listener.lastTopic); + } + + @Test + public void testAddNestedSubmodelElement() { + String idShortPath = "/testColl/testAddProp/"; + SubmodelElementCollection coll = new SubmodelElementCollection(); + coll.setIdShort("testColl"); + observableAPI.addSubmodelElement(coll); + + Property prop = new Property(true); + prop.setIdShort("testAddProp"); + observableAPI.addSubmodelElement(idShortPath, prop); + + assertEquals(MqttSubmodelAPIObserver.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload); + assertEquals(MqttSubmodelAPIHelper.TOPIC_ADDELEMENT, listener.lastTopic); + } + + @Test + public void testDeleteSubmodelElement() { + String idShortPath = "/testDeleteProp"; + Property prop = new Property(true); + prop.setIdShort("testDeleteProp"); + observableAPI.addSubmodelElement(prop); + observableAPI.deleteSubmodelElement(idShortPath); + + assertEquals(MqttSubmodelAPIObserver.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload); + assertEquals(MqttSubmodelAPIHelper.TOPIC_DELETEELEMENT, listener.lastTopic); + } + + @Test + public void testUpdateSubmodelElement() { + String idShortPath = "testUpdateProp"; + Property prop = new Property(true); + prop.setIdShort(idShortPath); + observableAPI.addSubmodelElement(prop); + observableAPI.updateSubmodelElement(idShortPath, false); + + assertFalse((boolean) observableAPI.getSubmodelElementValue(idShortPath)); + assertEquals(MqttSubmodelAPIObserver.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload); + assertEquals(MqttSubmodelAPIHelper.TOPIC_UPDATEELEMENT, listener.lastTopic); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java index 87bbad51..e3ad9211 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/extensions/submodel/mqtt/TestMqttSubmodelAPIEvents.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.extensions.submodel.mqtt; @@ -15,6 +30,7 @@ import java.io.IOException; import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPI; +import org.eclipse.basyx.extensions.submodel.mqtt.MqttSubmodelAPIHelper; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; import org.eclipse.basyx.submodel.metamodel.map.Submodel; @@ -45,10 +61,11 @@ * @author espen * */ +@SuppressWarnings("deprecation") public class TestMqttSubmodelAPIEvents { private static final String AASID = "testaasid"; private static final String SUBMODELID = "testsubmodelid"; - + private static Server mqttBroker; private static MqttSubmodelAPI eventAPI; private MqttTestListener listener; @@ -68,7 +85,7 @@ public static void setUpClass() throws MqttException, IOException { Submodel sm = new Submodel(SUBMODELID, new Identifier(IdentifierType.CUSTOM, SUBMODELID)); Reference parentRef = new Reference(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AASID, IdentifierType.IRDI)); sm.setParent(parentRef); - + VABSubmodelAPI vabAPI = new VABSubmodelAPI(new VABMapProvider(sm)); eventAPI = new MqttSubmodelAPI(vabAPI, "tcp://localhost:1884", "testClient"); } @@ -77,13 +94,13 @@ public static void setUpClass() throws MqttException, IOException { public static void tearDownClass() { mqttBroker.stopServer(); } - + @Before public void setUp() { listener = new MqttTestListener(); mqttBroker.addInterceptHandler(listener); } - + @After public void tearDown() { mqttBroker.removeInterceptHandler(listener); @@ -91,13 +108,13 @@ public void tearDown() { @Test public void testAddSubmodelElement() throws InterruptedException { - String elemIdShort = "testAddProp"; + String elemIdShort = "testAddProp"; Property prop = new Property(true); prop.setIdShort(elemIdShort); eventAPI.addSubmodelElement(prop); assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, elemIdShort), listener.lastPayload); - assertEquals(MqttSubmodelAPI.TOPIC_ADDELEMENT, listener.lastTopic); + assertEquals(MqttSubmodelAPIHelper.TOPIC_ADDELEMENT, listener.lastTopic); } @Test @@ -112,7 +129,7 @@ public void testAddNestedSubmodelElement() { eventAPI.addSubmodelElement(idShortPath, prop); assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload); - assertEquals(MqttSubmodelAPI.TOPIC_ADDELEMENT, listener.lastTopic); + assertEquals(MqttSubmodelAPIHelper.TOPIC_ADDELEMENT, listener.lastTopic); } @Test @@ -124,7 +141,7 @@ public void testDeleteSubmodelElement() { eventAPI.deleteSubmodelElement(idShortPath); assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload); - assertEquals(MqttSubmodelAPI.TOPIC_DELETEELEMENT, listener.lastTopic); + assertEquals(MqttSubmodelAPIHelper.TOPIC_DELETEELEMENT, listener.lastTopic); } @Test @@ -137,6 +154,6 @@ public void testUpdateSubmodelElement() { assertFalse((boolean) eventAPI.getSubmodelElementValue(idShortPath)); assertEquals(MqttSubmodelAPI.getCombinedMessage(AASID, SUBMODELID, idShortPath), listener.lastPayload); - assertEquals(MqttSubmodelAPI.TOPIC_UPDATEELEMENT, listener.lastTopic); + assertEquals(MqttSubmodelAPIHelper.TOPIC_UPDATEELEMENT, listener.lastTopic); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/aggregator/observing/ObservableSubmodelAggregatorTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/aggregator/observing/ObservableSubmodelAggregatorTest.java new file mode 100644 index 00000000..4f01b641 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/aggregator/observing/ObservableSubmodelAggregatorTest.java @@ -0,0 +1,163 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.aggregator.observing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.basyx.submodel.aggregator.SubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.api.ISubmodelAggregator; +import org.eclipse.basyx.submodel.aggregator.observing.ISubmodelAggregatorObserver; +import org.eclipse.basyx.submodel.aggregator.observing.ObservableSubmodelAggregator; +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests events emitting with the SubmodelAggregator + * + * @author fischer, jungjan, fried + * + */ +public class ObservableSubmodelAggregatorTest { + protected Submodel submodel; + + private static final String SUBMODEL_IDSHORT = "submodelIdShort"; + private static final String SUBMODEL_ID = "submodelId"; + private static final Identifier SUBMODEL_IDENTIFIER = new Identifier(IdentifierType.IRI, SUBMODEL_ID); + private static final String PARENT_AAS_ID = "parent_aas"; + private static final Identifier PARENT_AAS_IDENTIFIER = new Identifier(IdentifierType.IRI, PARENT_AAS_ID); + + private ObservableSubmodelAggregator observerdSubmodelAggregator; + private MockObserver observer; + + @Before + public void setup() { + ISubmodelAggregator aggregator = new SubmodelAggregator(); + submodel = new Submodel(SUBMODEL_IDSHORT, SUBMODEL_IDENTIFIER); + + IReference parentReference = new Reference(PARENT_AAS_IDENTIFIER, KeyElements.ASSETADMINISTRATIONSHELL, false); + + submodel.setParent(parentReference); + aggregator.createSubmodel(submodel); + + observerdSubmodelAggregator = new ObservableSubmodelAggregator(aggregator); + + // Create an Observer + observer = new MockObserver(); + + // Register the observer at the API + observerdSubmodelAggregator.addObserver(observer); + } + + @Test + public void testCreateSubmodel() { + String newSubmodelIdShort = "newSubmodelIdShort"; + Identifier newSubmodelIdentifier = new Identifier(IdentifierType.IRDI, newSubmodelIdShort); + Submodel newSubmodel = new Submodel(newSubmodelIdShort, newSubmodelIdentifier); + observerdSubmodelAggregator.createSubmodel(newSubmodel); + + assertEquals(newSubmodelIdShort, observer.submodelId); + assertTrue(observer.createdNotified); + } + + @Test + public void testUpdateSubmodel() { + submodel.setCategory("newCategory"); + observerdSubmodelAggregator.updateSubmodel(submodel); + + assertTrue(observer.updatedNotified); + assertEquals(SUBMODEL_ID, observer.submodelId); + assertEquals(PARENT_AAS_ID, observer.shellId); + } + + @Test + public void testDeleteSubmodelByIdentifier() { + observerdSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + assertTrue(observer.deletedNotified); + assertEquals(SUBMODEL_ID, observer.submodelId); + assertEquals(PARENT_AAS_ID, observer.shellId); + } + + @Test + public void testDeleteSubmodelByIdShort() { + observerdSubmodelAggregator.deleteSubmodelByIdShort(SUBMODEL_IDSHORT); + assertTrue(observer.deletedNotified); + assertEquals(SUBMODEL_ID, observer.submodelId); + assertEquals(PARENT_AAS_ID, observer.shellId); + } + + @Test + public void testRemoveObserver() { + assertTrue(observerdSubmodelAggregator.removeObserver(observer)); + observerdSubmodelAggregator.deleteSubmodelByIdentifier(SUBMODEL_IDENTIFIER); + assertFalse(observer.deletedNotified); + } + + private class MockObserver implements ISubmodelAggregatorObserver { + + public boolean createdNotified = false; + public boolean deletedNotified = false; + public boolean updatedNotified = false; + + public String shellId = ""; + public String submodelId = ""; + + @Override + public void submodelCreated(String shellId, String submodelId) { + createdNotified = true; + deletedNotified = false; + updatedNotified = false; + this.shellId = shellId; + this.submodelId = submodelId; + } + + @Override + public void submodelUpdated(String shellId, String submodelId) { + createdNotified = false; + deletedNotified = false; + updatedNotified = true; + this.shellId = shellId; + this.submodelId = submodelId; + } + + @Override + public void submodelDeleted(String shellId, String submodelId) { + createdNotified = false; + deletedNotified = true; + updatedNotified = false; + this.shellId = shellId; + this.submodelId = submodelId; + } + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/factory/xml/converters/submodelelement/operation/TestOperationXMLConverter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/factory/xml/converters/submodelelement/operation/TestOperationXMLConverter.java index f1c1a786..935a0e22 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/factory/xml/converters/submodelelement/operation/TestOperationXMLConverter.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/factory/xml/converters/submodelelement/operation/TestOperationXMLConverter.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.factory.xml.converters.submodelelement.operation; @@ -14,7 +29,7 @@ import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.ReferableXMLConverter; @@ -25,6 +40,7 @@ /** * This class tests {@link OperationXMLConverter} + * * @author haque * */ @@ -33,12 +49,12 @@ public class TestOperationXMLConverter { @Test public void testParseOperationWithoutVariables() { String idShort = "operation_ID"; - Map operationMap = new HashMap(); + Map operationMap = new LinkedHashMap(); operationMap.put(ReferableXMLConverter.ID_SHORT, "operation_ID"); Operation parsedOperation = OperationXMLConverter.parseOperation(operationMap); assertEquals(idShort, parsedOperation.getIdShort()); assertEquals(new ArrayList(), parsedOperation.getInputVariables()); assertEquals(new ArrayList(), parsedOperation.getOutputVariables()); - assertEquals(new ArrayList(), parsedOperation.getInOutputVariables()); + assertEquals(new ArrayList(), parsedOperation.getInOutputVariables()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java index 63f05407..6e512a9b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/TestSubmodelSuite.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel; @@ -21,7 +36,7 @@ import java.util.ArrayList; import java.util.Base64; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -77,7 +92,6 @@ public abstract class TestSubmodelSuite { private final String MULTI_LANG_PROP_ID = "multi_lang_prop_id"; private final String REFERENCE_ELEMENT_ID = "reference_element_id"; private final String PROPERTY_ID2 = "property_id2"; - private final static Reference testSemanticIdRef = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "testVal", IdentifierType.CUSTOM)); @@ -124,7 +138,6 @@ public void propertiesTest() throws Exception { assertEquals(100, prop.getValue()); } - @Test public void saveAndLoadPropertyTest() throws Exception { ISubmodel submodel = getSubmodel(); @@ -152,7 +165,6 @@ public void saveAndLoadSubmodelElementTest() throws Exception { submodel.addSubmodelElement(element); } - // Get sample SubmodelElements and save them into Submodel Map testSMElements = getTestSubmodelElements(); for (ISubmodelElement element : testSMElements.values()) { @@ -251,7 +263,7 @@ public void testGetValues() { * Generates test IDataElements */ private Map getTestDataProperty() { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); Property property = new Property(); property.setIdShort(PROPERTY_ID); @@ -281,16 +293,17 @@ private Map getTestDataProperty() { Property bigNumberProp = new Property(); bigNumberProp.setIdShort("bignumber_prop01"); BigInteger bignumber = new BigInteger("9223372036854775817"); - property.setValue(bignumber); + bigNumberProp.setValue(bignumber); ret.put(bigNumberProp.getIdShort(), bigNumberProp); return ret; } + /** * Generates test ISubmodelElements */ private Map getTestSubmodelElements() { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); SubmodelElementCollection smECollection = new SubmodelElementCollection(); smECollection.setIdShort(SUBMODEL_ELEM_COLLECTION_ID); @@ -300,7 +313,6 @@ private Map getTestSubmodelElements() { Property contained = new Property(PROPERTY_CONTAINED_ID, true); values.add(contained); - smECollection.setValue(values); ret.put(smECollection.getIdShort(), smECollection); @@ -310,7 +322,7 @@ private Map getTestSubmodelElements() { Reference first = new Reference(new Key(KeyElements.BASICEVENT, true, "testFirst", IdentifierType.CUSTOM)); Reference second = new Reference(new Key(KeyElements.BASICEVENT, true, "testSecond", IdentifierType.CUSTOM)); - + RelationshipElement relElement = new RelationshipElement(RELATIONSHIP_ELEM_ID, first, second); ret.put(relElement.getIdShort(), relElement); @@ -320,23 +332,23 @@ private Map getTestSubmodelElements() { annotations.add(annotationProperty); annotatedRelElement.setAnnotation(annotations); ret.put(annotatedRelElement.getIdShort(), annotatedRelElement); - + Property property = new Property(PROPERTY_ID2, ValueType.AnySimpleType); ret.put(property.getIdShort(), property); - + Range range = new Range(RANGE_ID, ValueType.Integer); range.setValue(new RangeValue(-100, +100)); ret.put(range.getIdShort(), range); - + File file = new File("text/plain"); file.setIdShort(FILE_ID); file.setValue("fileUrl"); ret.put(file.getIdShort(), file); - + MultiLanguageProperty languageProperty = new MultiLanguageProperty(MULTI_LANG_PROP_ID); languageProperty.setValue(new LangStrings(new LangString("en-en", "TestDescription"))); ret.put(languageProperty.getIdShort(), languageProperty); - + ReferenceElement referenceElement = new ReferenceElement(REFERENCE_ELEMENT_ID, first); ret.put(referenceElement.getIdShort(), referenceElement); @@ -380,7 +392,6 @@ private void checkSubmodelElements(Map actual) throws Collection elements = actualCollection.getSubmodelElements().values(); - // Check for correct Type assertEquals(1, elements.size()); assertTrue(elements.iterator().next() instanceof IProperty); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java index 0ef7980e..a36655d4 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/qualifier/TestIdShortValidator.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.api.qualifier; @@ -25,7 +40,7 @@ public class TestIdShortValidator { @Test public void testValidator() { - String[] accepted = {"abc", "AbC"}; + String[] accepted = { "abc", "AbC" }; String[] notAccepted = { ":", " test", "1Test", "äTest", null, "" }; for (String s : accepted) { diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java index 95602e2d..921e87ff 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/api/submodelelement/TestSubmodelElementIdShortBlacklist.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.api.submodelelement; @@ -26,7 +41,7 @@ public class TestSubmodelElementIdShortBlacklist { @Test public void testIsBlacklisted() { String allowed[] = { "test", "values", "invocations" }; - + for (String s : SubmodelElementIdShortBlacklist.BLACKLIST) { assertTrue(s + " was incorrectly allowed", SubmodelElementIdShortBlacklist.isBlacklisted(s)); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java index 8b24e4ee..6cd22e0a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected; @@ -54,9 +69,7 @@ public void testEmptyProperty() throws Exception { Property propertyMeta = new Property("testIdShort", ValueType.String); propertyMeta.setValue(null); Map destroyType = TypeDestroyer.destroyType(propertyMeta); - prop = new ConnectedProperty( - new VABConnectionManagerStub(new SubmodelElementProvider(new VABMapProvider(destroyType))) - .connectToVABElement("")); + prop = new ConnectedProperty(new VABConnectionManagerStub(new SubmodelElementProvider(new VABMapProvider(destroyType))).connectToVABElement("")); prop.setValue("content"); assertEquals("content", prop.getValue()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java index fa79a2ff..9a13f291 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodel.java @@ -1,22 +1,36 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.Serializable; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Function; @@ -56,16 +70,15 @@ public class TestConnectedSubmodel extends TestSubmodelSuite { public void build() { Submodel reference = getReferenceSubmodel(); - // Create an operation Operation op = new Operation((Function & Serializable) obj -> { return (int) obj[0] + (int) obj[1]; }); Property aProp = new Property("a", 1); - aProp.setModelingKind(ModelingKind.TEMPLATE); + aProp.setKind(ModelingKind.TEMPLATE); Property bProp = new Property("b", 2); - bProp.setModelingKind(ModelingKind.TEMPLATE); + bProp.setKind(ModelingKind.TEMPLATE); Property rProp = new Property("r", 3); - rProp.setModelingKind(ModelingKind.TEMPLATE); + rProp.setKind(ModelingKind.TEMPLATE); OperationVariable a = new OperationVariable(aProp); OperationVariable b = new OperationVariable(bProp); OperationVariable r = new OperationVariable(rProp); @@ -95,7 +108,7 @@ public void operationsTest() throws Exception { // Check the operation itself IOperation op = ops.get(OP); - assertEquals(5, op.invoke(2, 3)); + assertEquals(5, op.invokeSimple(2, 3)); } @Test @@ -131,7 +144,7 @@ public void testGetLocalCopy() { * Generates test IOperations */ private Map getTestOperations() { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); Operation operation = new Operation(); operation.setIdShort(OPERATION_ID); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java index 9dfc2d66..8a2a82b4 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/TestConnectedSubmodelElementCollection.java @@ -1,15 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; @@ -26,6 +42,7 @@ import org.eclipse.basyx.submodel.metamodel.map.Submodel; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; import org.eclipse.basyx.submodel.restapi.SubmodelProvider; @@ -49,7 +66,7 @@ public class TestConnectedSubmodelElementCollection { ConnectedSubmodelElementCollection prop; - @Before + @Before public void build() { // Create PropertySingleValued containing the collection Property propertyMeta = new Property(4); @@ -60,11 +77,11 @@ public void build() { return (int) arr[0] + (int) arr[1]; }); Property aProp = new Property("a", 1); - aProp.setModelingKind(ModelingKind.TEMPLATE); + aProp.setKind(ModelingKind.TEMPLATE); Property bProp = new Property("b", 2); - bProp.setModelingKind(ModelingKind.TEMPLATE); + bProp.setKind(ModelingKind.TEMPLATE); Property rProp = new Property("r", 3); - rProp.setModelingKind(ModelingKind.TEMPLATE); + rProp.setKind(ModelingKind.TEMPLATE); OperationVariable a = new OperationVariable(aProp); OperationVariable b = new OperationVariable(bProp); OperationVariable r = new OperationVariable(rProp); @@ -82,10 +99,11 @@ public void build() { sm.addSubmodelElement(complex); Map destroyType = TypeDestroyer.destroyType(sm); - // Create a dummy connection manager containing the created ContainerProperty map - // The model is wrapped in the corresponding ModelProvider that implements the API access - VABConnectionManagerStub manager = new VABConnectionManagerStub( - new SubmodelProvider(new VABLambdaProvider(destroyType))); + // Create a dummy connection manager containing the created ContainerProperty + // map + // The model is wrapped in the corresponding ModelProvider that implements the + // API access + VABConnectionManagerStub manager = new VABConnectionManagerStub(new SubmodelProvider(new VABLambdaProvider(destroyType))); // Retrieve the ConnectedContainerProperty prop = new ConnectedSubmodelElementCollection(manager.connectToVABElement("").getDeepProxy("/submodel/submodelElements/" + complex.getIdShort())); @@ -126,23 +144,22 @@ public void testOperation() throws Exception { IOperation sum = ops.get(OPERATION); // Check operation invocation - assertEquals(5, sum.invoke(2, 3)); + assertEquals(5, sum.invokeSimple(2, 3)); } - + @Test public void testSetValue() { Property property = new Property("testProperty"); property.setIdShort(PROP); - - + Collection newValue = new ArrayList<>(); newValue.add(property); - + prop.setValue(newValue); - + Map value = prop.getSubmodelElements(); IProperty property2 = (IProperty) value.get(PROP); - + assertEquals("testProperty", property2.getValue()); } @@ -151,13 +168,13 @@ public void testGetSubmodelElement() { ISubmodelElement element = prop.getSubmodelElement(PROP); assertEquals(PROP, element.getIdShort()); } - + @Test(expected = ResourceNotFoundException.class) public void testDeleteSubmodelElement() { prop.deleteSubmodelElement(PROP); prop.getSubmodelElement(PROP); } - + @Test public void testAddSubmodelElement() { String newId = "abc"; @@ -167,4 +184,24 @@ public void testAddSubmodelElement() { ISubmodelElement element = prop.getSubmodelElement(newId); assertEquals(newId, element.getIdShort()); } + + @Test + public void testGetValues() { + Map values = prop.getValues(); + assertEquals(1, values.size()); + assertTrue(values.containsKey(PROP)); + assertEquals(4, values.get(PROP)); + + String newKey = "newKey"; + String newValue = "newValue"; + + Property newProp = new Property(newKey, newValue); + newProp.setValueType(ValueType.String); + prop.addSubmodelElement(newProp); + + values = prop.getValues(); + assertEquals(2, values.size()); + assertTrue(values.containsKey(newKey)); + assertEquals(newValue, values.get(newKey)); + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/SubmodelElementTestHelper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/SubmodelElementTestHelper.java index b8b13c18..db02e15a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/SubmodelElementTestHelper.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/SubmodelElementTestHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement; @@ -27,13 +42,12 @@ public class SubmodelElementTestHelper { /** * Returns a stub for the provided propertyElement * - * @return + * @return */ public static VABElementProxy createElementProxy(Map propertyElement) { - VABConnectionManagerStub manager = new VABConnectionManagerStub( - new TypeDestroyingProvider(new SubmodelElementProvider(new VABLambdaProvider(propertyElement)))); - + VABConnectionManagerStub manager = new VABConnectionManagerStub(new TypeDestroyingProvider(new SubmodelElementProvider(new VABLambdaProvider(propertyElement)))); + return manager.connectToVABElement(""); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java index 866c64bd..44b5d99b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/TestConnectedSubmodelElementFactory.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; @@ -51,8 +66,8 @@ import org.junit.Test; /** - * Tests if the ConnectedSubmodelElementFactory - * handles all ISubmodelElement Objects correctly. + * Tests if the ConnectedSubmodelElementFactory handles all ISubmodelElement + * Objects correctly. * * @author conradi * @@ -69,42 +84,41 @@ public class TestConnectedSubmodelElementFactory { private static final String CAPABILITY_ID = "CapabilityId"; private static final String OPERATION_ID = "OperationId"; private static final String RELELEMENT_ID = "RelElementId"; - private static final String SMELEMCOLLECTION_ID = "SmElemCollectionId"; - + private static final String SMELEMCOLLECTION_ID = "SmElemCollectionId"; + VABElementProxy proxy; - + @Before public void build() { - + Map dataElements = buildDataElements(); - + Map operations = buildOperations(); - + Map submodelElements = buildSubmodelElements(); - + submodelElements.putAll(dataElements); submodelElements.putAll(operations); - - - Map values = new HashMap<>(); - + + Map values = new LinkedHashMap<>(); + values.put(Submodel.SUBMODELELEMENT, submodelElements); - - proxy = new VABElementProxy("/" + SubmodelProvider.SUBMODEL, - new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values)))); + + proxy = new VABElementProxy("/" + SubmodelProvider.SUBMODEL, new SubmodelProvider(new TypeDestroyingProvider(new VABLambdaProvider(values)))); } - + /** * Builds a Map containing an Object of every IDataElement + * * @return A Map ID->IDataElement */ private Map buildDataElements() { - Map ret = new HashMap<>(); - + Map ret = new LinkedHashMap<>(); + Property property = new Property(); property.setIdShort(PROPERTY_ID); ret.put(PROPERTY_ID, property); - + Blob blob = new Blob(); blob.setIdShort(BLOB_ID); ret.put(BLOB_ID, blob); @@ -130,25 +144,27 @@ private Map buildDataElements() { /** * Builds a Map containing an Object of every IOperation + * * @return A Map ID->IOperation */ private Map buildOperations() { - Map ret = new HashMap<>(); + Map ret = new LinkedHashMap<>(); Operation operation = new Operation(); operation.setIdShort(OPERATION_ID); ret.put(OPERATION_ID, operation); - + return ret; } - + /** * Builds a Map containing an Object of every IOperation + * * @return A Map ID->IOperation */ private Map buildSubmodelElements() { - Map ret = new HashMap<>(); - + Map ret = new LinkedHashMap<>(); + BasicEvent basicEvent = new BasicEvent(); basicEvent.setIdShort(BASICEVENT_ID); ret.put(BASICEVENT_ID, basicEvent); @@ -156,53 +172,47 @@ private Map buildSubmodelElements() { Capability capability = new Capability(); capability.setIdShort(CAPABILITY_ID); ret.put(CAPABILITY_ID, capability); - + RelationshipElement relElement = new RelationshipElement(); relElement.setIdShort(RELELEMENT_ID); ret.put(RELELEMENT_ID, relElement); - + SubmodelElementCollection smElemCollection = new SubmodelElementCollection(); smElemCollection.setIdShort(SMELEMCOLLECTION_ID); ret.put(SMELEMCOLLECTION_ID, smElemCollection); - + return ret; } - + /** * Tests if getProperties() returns the correct value */ @Test public void testGetProperties() { - Map properties = - ConnectedSubmodelElementFactory.getProperties( - proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); - + Map properties = ConnectedSubmodelElementFactory.getProperties(proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); + assertEquals(1, properties.size()); assertTrue(properties.get(PROPERTY_ID) instanceof ConnectedProperty); } - + /** * Tests if getOperations() returns the correct value */ @Test public void testGetOperations() { - Map operations = - ConnectedSubmodelElementFactory.getOperations( - proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); - + Map operations = ConnectedSubmodelElementFactory.getOperations(proxy, MultiSubmodelElementProvider.ELEMENTS, MultiSubmodelElementProvider.ELEMENTS); + assertEquals(1, operations.size()); assertTrue(operations.get(OPERATION_ID) instanceof ConnectedOperation); } - + /** * Tests if getSubmodelElements() returns the correct value */ @Test public void testGetSubmodelElements() { - Map submodelElements = - ConnectedSubmodelElementFactory.getConnectedSubmodelElements( - proxy, Submodel.SUBMODELELEMENT, Submodel.SUBMODELELEMENT); - + Map submodelElements = ConnectedSubmodelElementFactory.getConnectedSubmodelElements(proxy, Submodel.SUBMODELELEMENT, Submodel.SUBMODELELEMENT); + assertEquals(11, submodelElements.size()); assertTrue(submodelElements.get(PROPERTY_ID) instanceof ConnectedProperty); assertTrue(submodelElements.get(BLOB_ID) instanceof ConnectedBlob); @@ -216,5 +226,5 @@ public void testGetSubmodelElements() { assertTrue(submodelElements.get(RELELEMENT_ID) instanceof ConnectedRelationshipElement); assertTrue(submodelElements.get(SMELEMCOLLECTION_ID) instanceof ConnectedSubmodelElementCollection); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java index 44d312ff..05fceb37 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedBlob.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement; @@ -30,21 +45,21 @@ public class TestConnectedBlob { public final String BLOB_CONTENT = "BLOB_VALUE"; protected ConnectedBlob connectedBlob; - protected Blob blob; - + protected Blob blob; + @Before public void build() { blob = new Blob("testIdShort", "mimeType"); - + byte[] value = BLOB_CONTENT.getBytes(StandardCharsets.UTF_8); - + blob.setByteArrayValue(value); - + VABElementProxy elementProxy = SubmodelElementTestHelper.createElementProxy(blob); connectedBlob = new ConnectedBlob(elementProxy); } - + /** * Tests if getValue() returns the correct value */ @@ -63,7 +78,7 @@ public void testGetByteArrayValue() { assertArrayEquals(blob.getByteArrayValue(), connectedBlob.getByteArrayValue()); assertArrayEquals(BLOB_CONTENT.getBytes(StandardCharsets.UTF_8), connectedBlob.getByteArrayValue()); } - + /** * Tests if getMimeType() returns the correct value */ @@ -71,7 +86,7 @@ public void testGetByteArrayValue() { public void testGetMimeType() { assertEquals(blob.getMimeType(), connectedBlob.getMimeType()); } - + /** * Tests if getUTF8String() returns the correct value */ @@ -111,15 +126,15 @@ public void testSetValue() { connectedBlob.setValue(newStringValue); assertEquals("NEW", connectedBlob.getUTF8String()); } - + @Test public void setValueUpdatesValueCorrectly() { triggerCachingOfSubmodelElement(); byte[] expected = BLOB_CONTENT.getBytes(StandardCharsets.US_ASCII); - + connectedBlob.setValue(Base64.getEncoder().encodeToString(expected)); - + assertEquals(Base64.getEncoder().encodeToString(expected), connectedBlob.getValue()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java index 5f92998b..95b98e3a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedFile.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement; @@ -27,19 +42,19 @@ public class TestConnectedFile { ConnectedFile connectedFile; File file; - + @Before public void build() { file = new File(); file.setIdShort("testIdShort"); file.setValue("FILE_VALUE"); file.setMimeType("mimeType"); - + VABElementProxy elementProxy = SubmodelElementTestHelper.createElementProxy(file); connectedFile = new ConnectedFile(elementProxy); } - + /** * Tests if getValue() returns the correct value */ @@ -47,7 +62,7 @@ public void build() { public void testGetValue() { assertEquals(file.getValue(), connectedFile.getValue()); } - + /** * Tests if getMimeType() returns the correct value */ @@ -55,7 +70,7 @@ public void testGetValue() { public void testGetMimeType() { assertEquals(file.getMimeType(), connectedFile.getMimeType()); } - + @Test public void testSetValue() { String value = connectedFile.getValue(); @@ -63,20 +78,20 @@ public void testSetValue() { connectedFile.setValue(value); assertEquals(value, connectedFile.getValue()); } - + @Test public void setValueUpdatesValueCorrectly() { triggerCachingOfSubmodelElement(); String expected = "Test File Value"; - + connectedFile.setValue(expected); - + assertEquals(expected, connectedFile.getValue()); } private void triggerCachingOfSubmodelElement() { connectedFile.getElem(); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java index baf6f7a3..0564ff89 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedMultiLanguageProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement; @@ -25,23 +40,23 @@ * */ public class TestConnectedMultiLanguageProperty { - + ConnectedMultiLanguageProperty connectedMLP; MultiLanguageProperty MLP; - + @Before public void build() { LangStrings langStrings = new LangStrings("de", "TestBeschreibung"); - + MLP = new MultiLanguageProperty("idShort"); - + MLP.setValue(langStrings); - + VABElementProxy elementProxy = SubmodelElementTestHelper.createElementProxy(MLP); connectedMLP = new ConnectedMultiLanguageProperty(elementProxy); } - + /** * Tests if getValue() returns the correct value */ @@ -49,7 +64,7 @@ public void build() { public void testGetValue() { assertEquals(MLP.getValue().get("de"), connectedMLP.getValue().get("de")); } - + /** * Tests if getValueId() returns the correct value */ @@ -57,15 +72,15 @@ public void testGetValue() { public void testGetValueId() { assertEquals(MLP.getValueId(), connectedMLP.getValueId()); } - + @Test public void setValueUpdatesValueCorrectly() { triggerCachingOfSubmodelElement(); - - LangStrings expected = new LangStrings("en", "English Language"); + + LangStrings expected = new LangStrings("en", "English Language"); connectedMLP.setValue(expected); - + assertEquals(expected, connectedMLP.getValue()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java index 6633a6c1..fda716a7 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedRange.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement; @@ -26,20 +41,20 @@ * */ public class TestConnectedRange { - + ConnectedRange connectedRange; Range range; - + @Before public void build() { range = new Range(ValueType.Integer, new Integer(1), new Integer(10)); range.setIdShort("testIdShort"); - + VABElementProxy elementProxy = SubmodelElementTestHelper.createElementProxy(range); connectedRange = new ConnectedRange(elementProxy); } - + /** * Tests if getValueType() returns the correct value */ @@ -47,7 +62,7 @@ public void build() { public void testGetValueType() { assertEquals(range.getValueType(), connectedRange.getValueType()); } - + /** * Tests if getMin() returns the correct value */ @@ -55,7 +70,7 @@ public void testGetValueType() { public void testGetMin() { assertEquals(range.getMin(), connectedRange.getMin()); } - + /** * Tests if getMax() returns the correct value */ @@ -63,7 +78,7 @@ public void testGetMin() { public void testGetMax() { assertEquals(range.getMax(), connectedRange.getMax()); } - + /** * Tests if getValue() returns the correct value */ @@ -73,29 +88,29 @@ public void testGetValue() { assertEquals(range.getMin(), rv.getMin()); assertEquals(range.getMax(), rv.getMax()); } - + /** * Tests if setValue() sets the correct value. */ @Test public void testSetValue() { RangeValue value = new RangeValue(2, 8); - + connectedRange.setValue(value); - + assertEquals(2, connectedRange.getMin()); assertEquals(8, connectedRange.getMax()); assertEquals(range.getValueType(), connectedRange.getValueType()); } - + @Test public void setValueUpdatesValueCorrectly() { triggerCachingOfSubmodelElement(); RangeValue expected = new RangeValue(10, 20); - + connectedRange.setValue(expected); - + assertEquals(expected, connectedRange.getValue()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java index 285705e2..48abe68e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/dataelement/TestConnectedReferenceElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.dataelement; @@ -30,22 +45,22 @@ * */ public class TestConnectedReferenceElement { - + ConnectedReferenceElement connectedRefElem; ReferenceElement refElem; - + @Before public void build() { - + Reference ref = new Reference(new Key(KeyElements.BLOB, true, "", IdentifierType.CUSTOM)); - + refElem = new ReferenceElement(ref); - + VABElementProxy elementProxy = SubmodelElementTestHelper.createElementProxy(refElem); connectedRefElem = new ConnectedReferenceElement(elementProxy); } - + /** * Tests if getValue() returns the correct value */ @@ -61,7 +76,7 @@ public void setValueUpdatesValueCorrectly() { IReference expected = new Reference(new Key(KeyElements.ASSET, true, "asset", IdentifierType.CUSTOM)); connectedRefElem.setValue(expected); - + assertEquals(expected, connectedRefElem.getValue()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java index ad870f56..7355f98c 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/event/TestConnectedBasicEvent.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.event; @@ -34,20 +49,19 @@ public class TestConnectedBasicEvent { ConnectedBasicEvent connectedEvent; BasicEvent event; - + @Before public void build() { - + Reference ref = new Reference(new Key(KeyElements.BLOB, true, "", IdentifierType.CUSTOM)); - + event = new BasicEvent(ref); - - VABConnectionManagerStub manager = new VABConnectionManagerStub( - new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(event)))); + + VABConnectionManagerStub manager = new VABConnectionManagerStub(new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(event)))); connectedEvent = new ConnectedBasicEvent(manager.connectToVABElement("")); } - + /** * Tests if getObserved() returns the correct value */ diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java index 3674dcdc..4109ef64 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.operation; @@ -34,8 +49,7 @@ public class TestConnectedOperation extends TestOperationSuite { protected IOperation prepareOperation(Operation operation) { Map destroyType = TypeDestroyer.destroyType(operation); // Create a dummy connection manager containing the created Operation map - VABConnectionManager manager = new VABConnectionManagerStub( - new OperationProvider(new VABMapProvider(destroyType))); + VABConnectionManager manager = new VABConnectionManagerStub(new OperationProvider(new VABMapProvider(destroyType))); // Create the ConnectedOperation based on the manager stub return new ConnectedOperation(manager.connectToVABElement("")); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperationInput.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperationInput.java new file mode 100644 index 00000000..d907f2ca --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperationInput.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.operation; + +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.restapi.OperationProvider; +import org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation.TestOperationInputSuite; +import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub; +import org.eclipse.basyx.vab.manager.VABConnectionManager; +import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; +import org.eclipse.basyx.vab.support.TypeDestroyer; + +/** + * Tests inputs of {@link ConnectedOperation} for their correctness + * + * + * @author espen, fischer + * + */ +public class TestConnectedOperationInput extends TestOperationInputSuite { + + @Override + protected IOperation prepareOperation(Operation operation) { + Map destroyType = TypeDestroyer.destroyType(operation); + // Create a dummy connection manager containing the created Operation map + VABConnectionManager manager = new VABConnectionManagerStub(new OperationProvider(new VABMapProvider(destroyType))); + + // Create the ConnectedOperation based on the manager stub + return new ConnectedOperation(manager.connectToVABElement("")); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperationParameter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperationParameter.java new file mode 100644 index 00000000..06aadb30 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/operation/TestConnectedOperationParameter.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.operation; + +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.restapi.OperationProvider; +import org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation.TestOperationParameterSuite; +import org.eclipse.basyx.testsuite.regression.vab.manager.VABConnectionManagerStub; +import org.eclipse.basyx.vab.manager.VABConnectionManager; +import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; +import org.eclipse.basyx.vab.support.TypeDestroyer; + +/** + * Tests if a ConnectedOperation can be created and used correctly with all + * parameters + * + * + * @author espen, fischer + * + */ +public class TestConnectedOperationParameter extends TestOperationParameterSuite { + + @Override + protected IOperation prepareOperation(Operation operation) { + Map destroyType = TypeDestroyer.destroyType(operation); + // Create a dummy connection manager containing the created Operation map + VABConnectionManager manager = new VABConnectionManagerStub(new OperationProvider(new VABMapProvider(destroyType))); + + // Create the ConnectedOperation based on the manager stub + return new ConnectedOperation(manager.connectToVABElement("")); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java index a101f933..081b49f6 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedAnnotatedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.relationship; @@ -31,7 +46,8 @@ import org.junit.Test; /** - * Tests if a ConnectedAnnotatedRelationshipElement can be created and used correctly + * Tests if a ConnectedAnnotatedRelationshipElement can be created and used + * correctly * * @author conradi * @@ -40,25 +56,24 @@ public class TestConnectedAnnotatedRelationshipElement { ConnectedAnnotatedRelationshipElement connectedElement; AnnotatedRelationshipElement element; - + @Before public void build() { Reference ref1 = new Reference(new Key(KeyElements.BLOB, true, "1", IdentifierType.CUSTOM)); Reference ref2 = new Reference(new Key(KeyElements.FILE, false, "2", IdentifierType.IRDI)); - + Property property = new Property("PropertyId", 10); List annotations = new ArrayList<>(); annotations.add(property); - + element = new AnnotatedRelationshipElement("testId", ref1, ref2); element.setAnnotation(annotations); - - VABConnectionManagerStub manager = new VABConnectionManagerStub( - new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(element)))); + + VABConnectionManagerStub manager = new VABConnectionManagerStub(new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(element)))); connectedElement = new ConnectedAnnotatedRelationshipElement(manager.connectToVABElement("")); } - + /** * Tests if getValue() returns the correct value */ @@ -69,5 +84,5 @@ public void testGetValue() { assertEquals(element.getSecond(), value.getSecond()); assertEquals(element.getValue().getAnnotations().size(), value.getAnnotations().size()); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java index 49308e7f..c0c3a50f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/connected/submodelelement/relationship/TestConnectedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.connected.submodelelement.relationship; @@ -32,21 +47,19 @@ * */ public class TestConnectedRelationshipElement { - + ConnectedRelationshipElement connectedRelElem; RelationshipElement relElem; - + @Before public void build() { - + Reference ref1 = new Reference(new Key(KeyElements.BLOB, true, "1", IdentifierType.CUSTOM)); Reference ref2 = new Reference(new Key(KeyElements.FILE, false, "2", IdentifierType.IRDI)); - + relElem = new RelationshipElement("testId", ref1, ref2); - - - VABConnectionManagerStub manager = new VABConnectionManagerStub( - new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem)))); + + VABConnectionManagerStub manager = new VABConnectionManagerStub(new SubmodelElementProvider(new TypeDestroyingProvider(new VABLambdaProvider(relElem)))); connectedRelElem = new ConnectedRelationshipElement(manager.connectToVABElement("")); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java index ddc55c97..5dbdea0e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/facade/TestSubmodelElementMapCollectionConverter.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.facade; @@ -14,14 +29,19 @@ import static org.junit.Assert.assertTrue; import java.util.Collection; +import java.util.HashSet; +import java.util.List; import java.util.Map; import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.entity.EntityType; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.entity.Entity; import org.eclipse.basyx.vab.support.TypeDestroyer; import org.junit.Test; @@ -35,45 +55,74 @@ public class TestSubmodelElementMapCollectionConverter { private static final String ID_SHORT = "testElement"; - @Test public void testMapToSM() { Submodel sm = getSM(); - + // Replace the smElement Map with a Collection sm.put(Submodel.SUBMODELELEMENT, sm.getSubmodelElements().values()); - + // Make a Map from the SM, as if it was transferred over the VAB Map map = TypeDestroyer.destroyType(sm); - - + sm = SubmodelElementMapCollectionConverter.mapToSM(map); - + assertTrue(sm.get(Submodel.SUBMODELELEMENT) instanceof Map); - + assertNotNull(sm.getSubmodelElements().get(ID_SHORT)); assertTrue(sm.getSubmodelElements().get(ID_SHORT) instanceof Property); } - + @SuppressWarnings("unchecked") @Test public void testSMToMap() { Submodel sm = getSM(); - + Map map = SubmodelElementMapCollectionConverter.smToMap(sm); - + assertTrue(map.get(Submodel.SUBMODELELEMENT) instanceof Collection); assertEquals(1, ((Collection) map.get(Submodel.SUBMODELELEMENT)).size()); } + @Test + public void entityStatementContainingSMCConverted() { + Entity entity = createTestEntityWithSMCAsStatement(); + + Map convertedEntity = SubmodelElementMapCollectionConverter.smElementToMap(entity); + + assertEntityCorrectlyConverted(convertedEntity); + } + + @SuppressWarnings("unchecked") + private void assertEntityCorrectlyConverted(Map convertedEntity) { + List> convertedStatements = (List>) convertedEntity.get(Entity.STATEMENT); + + Map convertedSMC = convertedStatements.get(0); + Object convertedSMCValue = convertedSMC.get(Property.VALUE); + assertTrue(convertedSMCValue instanceof List); + } + + private Entity createTestEntityWithSMCAsStatement() { + Entity entity = new Entity("entity", EntityType.COMANAGEDENTITY); + + SubmodelElementCollection smc = new SubmodelElementCollection("smc"); + + Property prop = new Property("prop", ValueType.String); + smc.addSubmodelElement(prop); + + Collection statements = new HashSet<>(); + statements.add(smc); + entity.setStatements(statements); + + return entity; + } private Submodel getSM() { Submodel sm = new Submodel("submodelIdShort", new ModelUrn("submodelUrn")); Property property = new Property(ID_SHORT, ValueType.String); - + sm.addSubmodelElement(property); return sm; } - - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java index 4b6ae58f..9e02a9b9 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/TestSubmodel.java @@ -1,20 +1,36 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; - +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Map; - +import org.eclipse.basyx.aas.metamodel.exception.IdShortDuplicationException; import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn; import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier; @@ -51,11 +67,11 @@ public void testParentAddSubmodelElement() { IIdentifier identifier = new ModelUrn("testId"); Submodel submodel = new Submodel("smIdShort", identifier); submodel.addSubmodelElement(prop); - + // Create expected parent of the element for assertion Reference expectedParent = new Reference(new Key(KeyElements.SUBMODEL, true, identifier.getId(), identifier.getIdType())); assertEquals(expectedParent, prop.getParent()); - } + } /** * Tests if a Submodel containing a list for SUBMODELELEMENT is correctly @@ -66,7 +82,7 @@ public void testParentAddSubmodelElement() { public void testCreateAsFacadePropertyList() { // Create test property String propId = "testProp"; - + Property expected = new Property(5); expected.setIdShort(propId); @@ -85,4 +101,28 @@ public void testCreateAsFacadePropertyList() { protected ISubmodel getSubmodel() { return submodel; } + + @Test(expected = IdShortDuplicationException.class) + public void checkForExceptionWithDuplicateIdShortInSubmodel() { + Map faultySubmodel = createSubmodelWithDuplicateIdShortProperties(); + + Submodel.createAsFacade(faultySubmodel); + } + + private Map createSubmodelWithDuplicateIdShortProperties() { + String duplicateIdShort = "testProp"; + + Property property1 = new Property(duplicateIdShort, 5); + Property property2 = new Property(duplicateIdShort, 7); + + Collection> collection = Arrays.asList(property1, property2); + + String idShort = "submodelIdShort"; + + Submodel submodel = new Submodel(idShort, new Identifier(IdentifierType.IRI, idShort)); + + submodel.put(Submodel.SUBMODELELEMENT, collection); + + return submodel; + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java index b001dc48..1fa14b3e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestDataSpecificationIEC61360.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification; @@ -29,8 +44,8 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link DataSpecificationIEC61360} for their - * correctness + * Tests constructor, setter and getter of {@link DataSpecificationIEC61360} for + * their correctness * * @author haque * @@ -41,7 +56,7 @@ public class TestDataSpecificationIEC61360 { private static final String SYMBOL = "testSymbol"; private static final DataTypeIEC61360 DATA_TYPE = DataTypeIEC61360.REAL_MEASURE; private static final String VALUE_FORMAT = "testValueFormat"; - private static final LangStrings PREFERRED_NAME = new LangStrings("DE", "testName"); + private static final LangStrings PREFERRED_NAME = new LangStrings("DE", "testName"); private static final String SOURCE_OF_DEFINITION = "testSource"; private static final LangStrings DEFINITION = new LangStrings("DE", "testDefinition"); private static final KeyElements KEY_ELEMENTS = KeyElements.ASSET; @@ -53,16 +68,14 @@ public class TestDataSpecificationIEC61360 { private static final Reference VALUE_ID = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); private static final IValueReferencePair VALUEREFPAIR = new ValueReferencePair(VALUE, VALUE_ID); private static final LevelType LEVELTYPE = LevelType.TYP; - + private DataSpecificationIEC61360Content specification; - + @Before public void buildDataSpecification() { - specification = new DataSpecificationIEC61360Content(PREFERRED_NAME, SHORT_NAME, - UNIT, UNIT_ID, SOURCE_OF_DEFINITION, SYMBOL, DATA_TYPE, DEFINITION, VALUE_FORMAT, - Arrays.asList(VALUEREFPAIR), VALUE, VALUE_ID, LEVELTYPE); + specification = new DataSpecificationIEC61360Content(PREFERRED_NAME, SHORT_NAME, UNIT, UNIT_ID, SOURCE_OF_DEFINITION, SYMBOL, DATA_TYPE, DEFINITION, VALUE_FORMAT, Arrays.asList(VALUEREFPAIR), VALUE, VALUE_ID, LEVELTYPE); } - + @Test public void testConstructor() { assertEquals(PREFERRED_NAME, specification.getPreferredName()); @@ -80,7 +93,7 @@ public void testConstructor() { assertEquals(LEVELTYPE, specification.getLevelType()); } - + @Test public void testSetPreferredName() { LangStrings newPreferredNameString = new LangStrings("EN", "newPreferredName"); @@ -88,7 +101,7 @@ public void testSetPreferredName() { TypeDestroyer.destroyType(specification); assertEquals(newPreferredNameString, specification.getPreferredName()); } - + @Test public void testSetShortName() { LangStrings newShortNameString = new LangStrings("DE", "newShortName"); @@ -96,14 +109,14 @@ public void testSetShortName() { TypeDestroyer.destroyType(specification); assertEquals(newShortNameString, specification.getShortName()); } - + @Test public void testSetUnit() { - String newUnitString = "newUnit"; + String newUnitString = "newUnit"; specification.setUnit(newUnitString); assertEquals(newUnitString, specification.getUnit()); } - + @Test public void testSetUnitId() { boolean isLocal = true; @@ -116,28 +129,28 @@ public void testSetUnitId() { TypeDestroyer.destroyType(specification); assertEquals(unitIdReference, specification.getUnitId()); } - + @Test public void testSetSourceOfDefinition() { String newSourceOfDefinition = "newSourceOfDefinition"; specification.setSourceOfDefinition(newSourceOfDefinition); assertEquals(newSourceOfDefinition, specification.getSourceOfDefinition()); } - + @Test public void testSetSymbol() { String newSymbolString = "newSymbol"; specification.setSymbol(newSymbolString); assertEquals(newSymbolString, specification.getSymbol()); } - + @Test public void testSetDataType() { DataTypeIEC61360 newDataTypeString = DataTypeIEC61360.BOOLEAN; specification.setDataType(newDataTypeString); assertEquals(newDataTypeString, specification.getDataType()); } - + @Test public void testSetDefinition() { LangStrings newDefinition = new LangStrings("EN", "newDefinition"); @@ -145,7 +158,7 @@ public void testSetDefinition() { TypeDestroyer.destroyType(specification); assertEquals(newDefinition, specification.getDefinition()); } - + @Test public void testSetValueFormat() { String newValueFormatString = "newValueFormat"; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java index 24bdb99f..d2364ba5 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestEmbeddedDataSpecification.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification; @@ -40,7 +55,7 @@ public class TestEmbeddedDataSpecification { private static final String SYMBOL = "testSymbol"; private static final DataTypeIEC61360 DATA_TYPE = DataTypeIEC61360.REAL_MEASURE; private static final String VALUE_FORMAT = "testValueFormat"; - private static final LangStrings PREFERRED_NAME = new LangStrings("DE", "testName"); + private static final LangStrings PREFERRED_NAME = new LangStrings("DE", "testName"); private static final String SOURCE_OF_DEFINITION = "testSource"; private static final LangStrings DEFINITION = new LangStrings("DE", "testDefinition"); private static final KeyElements KEY_ELEMENTS = KeyElements.ASSET; @@ -52,12 +67,11 @@ public class TestEmbeddedDataSpecification { private static final Reference VALUE_ID = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); private static final IValueReferencePair VALUEREFPAIR = new ValueReferencePair(VALUE, VALUE_ID); private static final LevelType LEVELTYPE = LevelType.TYP; - + @Test public void testConstructor() { - DataSpecificationIEC61360Content content = new DataSpecificationIEC61360Content(PREFERRED_NAME, SHORT_NAME, - UNIT, UNIT_ID, SOURCE_OF_DEFINITION, SYMBOL, DATA_TYPE, DEFINITION, VALUE_FORMAT, - Arrays.asList(VALUEREFPAIR), VALUE, VALUE_ID, LEVELTYPE); + DataSpecificationIEC61360Content content = new DataSpecificationIEC61360Content(PREFERRED_NAME, SHORT_NAME, UNIT, UNIT_ID, SOURCE_OF_DEFINITION, SYMBOL, DATA_TYPE, DEFINITION, VALUE_FORMAT, Arrays.asList(VALUEREFPAIR), VALUE, + VALUE_ID, LEVELTYPE); IEmbeddedDataSpecification specification = new DataSpecificationIEC61360(content); assertEquals(content, specification.getContent()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java index b0e84f18..31ad89c5 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/dataspecification/TestValueReferencePair.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.dataspecification; @@ -30,31 +45,31 @@ public class TestValueReferencePair { private static final String VALUE = "testValue"; private static final IReference VALUE_ID = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRDI)); - + private ValueReferencePair valueReferencePair; - + @Before public void buildValueReferencePair() { valueReferencePair = new ValueReferencePair(VALUE, VALUE_ID); } - + @Test public void testConstructor() { assertEquals(VALUE, valueReferencePair.getValue()); assertEquals(VALUE_ID, valueReferencePair.getValueId()); - } - + } + @Test public void testSetValue() { String newValue = "testValue1"; valueReferencePair.setValue(newValue); assertEquals(newValue, valueReferencePair.getValue()); - } - + } + @Test public void testSetValueId() { IReference newValueId = new Reference(new Key(KeyElements.BLOB, false, "testValueNew", IdentifierType.IRI)); valueReferencePair.setValueId(newValueId); assertEquals(newValueId, valueReferencePair.getValueId()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java index c1e11658..51af6275 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/identifier/TestIdentifier.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.identifier; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java index 71c22a9b..240d7452 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/modeltype/TestModelType.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.modeltype; @@ -15,8 +30,7 @@ import org.junit.Test; /** - * Tests constructor and getter of {@link ModelType} for their - * correctness + * Tests constructor and getter of {@link ModelType} for their correctness * * @author haque * diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java index 15920008..190308d1 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/parts/TestConceptDescription.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.parts; @@ -44,69 +59,69 @@ public class TestConceptDescription { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE); private static final Reference REFERENCE = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); - + private ConceptDescription description; - + @Before public void buildConceptDescription() { - description = new ConceptDescription("testConceptDescriptionID", new Identifier(IdentifierType.IRDI, "testId")); + description = new ConceptDescription("testConceptDescriptionID", new Identifier(IdentifierType.IRDI, "testId")); } - + @Test public void testSetDataSpecificationReferences() { Collection references = Collections.singleton(REFERENCE); description.setDataSpecificationReferences(references); assertEquals(references, description.getDataSpecificationReferences()); } - + @Test public void testSetAdministration() { String versionString = "1.0"; String revisionString = "4"; AdministrativeInformation information = new AdministrativeInformation(versionString, revisionString); - + description.setAdministration(information); assertEquals(information, description.getAdministration()); } - + @Test public void testSetIdentification() { description.setIdentification(ID_TYPE, ID_SHORT_STRING); Identifier identifier = new Identifier(ID_TYPE, ID_SHORT_STRING); assertEquals(identifier, description.getIdentification()); } - + @Test public void testSetIsCaseOf() { - Collection references = Collections.singleton(REFERENCE); + Collection references = Collections.singleton(REFERENCE); description.setIsCaseOf(Collections.singletonList(REFERENCE)); assertEquals(references, description.getIsCaseOf()); } - + @Test public void testSetIdShort() { description.setIdShort(ID_SHORT_STRING); assertEquals(ID_SHORT_STRING, description.getIdShort()); } - + @Test public void testSetCategory() { description.setCategory(CATE_STRING); assertEquals(CATE_STRING, description.getCategory()); } - + @Test public void testSetDescription() { description.setDescription(DESCRIPTION); assertEquals(DESCRIPTION, description.getDescription()); } - + @Test public void testSetParent() { description.setParent(REFERENCE); assertEquals(REFERENCE, description.getParent()); } - + @Test public void testSetEmbeddedDataSpecifications() { EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification(); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java index 64315ed7..50a6e3be 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestAdministrativeInformation.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -27,8 +42,8 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link AdministrativeInformation} for their - * correctness + * Tests constructor, setter and getter of {@link AdministrativeInformation} for + * their correctness * * @author haque * @@ -42,28 +57,28 @@ public class TestAdministrativeInformation { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE); private static final Reference REFERENCE = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); - + private AdministrativeInformation information; - + @Before public void buildAdministrativeInformation() { information = new AdministrativeInformation(VERSION, REVISION); } - + @Test public void testConstructor() { assertEquals(VERSION, information.getVersion()); assertEquals(REVISION, information.getRevision()); assertEquals(new HashSet(), information.getDataSpecificationReferences()); } - + @Test public void testSetDataSpecificationReferences() { Collection references = Collections.singleton(REFERENCE); information.setDataSpecificationReferences(references); assertEquals(references, information.getDataSpecificationReferences()); } - + @Test public void testSetVersionInformation() { String newVersionString = "2.0"; @@ -72,21 +87,21 @@ public void testSetVersionInformation() { assertEquals(newVersionString, information.getVersion()); assertEquals(newRevisionString, information.getRevision()); } - + @Test(expected = RuntimeException.class) public void testSetVersionInformationExceptionEmptyString() { String newVersionString = ""; String newRevisionString = "2.0.1"; information.setVersionInformation(newVersionString, newRevisionString); } - + @Test(expected = RuntimeException.class) public void testSetVersionInformationExceptionNullString() { String newVersionString = null; String newRevisionString = "2.0.1"; information.setVersionInformation(newVersionString, newRevisionString); } - + @Test public void testSetVersionInformationNoRevision() { String newVersionString = ""; @@ -95,7 +110,7 @@ public void testSetVersionInformationNoRevision() { assertEquals(newVersionString, information.getVersion()); assertEquals(newRevisionString, information.getRevision()); } - + @Test public void testSetEmbeddedDataSpecifications() { EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification(); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java index 6c4128cc..fab214ab 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasDataSpecification.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -25,8 +40,8 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link HasDataSpecification} for their - * correctness + * Tests constructor, setter and getter of {@link HasDataSpecification} for + * their correctness * * @author haque * @@ -38,20 +53,20 @@ public class TestHasDataSpecification { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE); private static final Reference REFERENCE = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); - + private HasDataSpecification specification; - + @Before public void buildHasDataSpecification() { specification = new HasDataSpecification(new ArrayList<>(), Collections.singleton(REFERENCE)); } - + @Test public void testConstructor() { Collection references = Collections.singleton(REFERENCE); assertEquals(references, specification.getDataSpecificationReferences()); } - + @Test public void testSetDataSpecificationReferences() { IdentifierType identifierType = IdentifierType.IRDI; @@ -61,7 +76,7 @@ public void testSetDataSpecificationReferences() { boolean isLocal = true; Reference reference = new Reference(identifier, keyElements, isLocal); Collection references = Collections.singleton(reference); - + specification.setDataSpecificationReferences(references); assertEquals(references, specification.getDataSpecificationReferences()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java index 2d753fff..e17c7fe6 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestHasSemantics.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -33,19 +48,19 @@ public class TestHasSemantics { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE); private static final Reference REFERENCE = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); - + private HasSemantics semantics; - + @Before public void buildHasSemantics() { semantics = new HasSemantics(REFERENCE); } - + @Test public void testConstructor() { assertEquals(REFERENCE, semantics.getSemanticId()); } - + @Test public void testSetSemanticID() { IdentifierType identifierType = IdentifierType.IRDI; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java index 3206a38a..72ae65a5 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestIdentifiable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -33,14 +48,14 @@ public class TestIdentifiable { private static final String ID_SHORT_STRING = "testIdShort"; private static final LangStrings DESCRIPTION = new LangStrings("Eng", "test"); private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; - + private Identifiable identifiable; - + @Before public void buildIdentifiable() { identifiable = new Identifiable(VERSION, REVISION, ID_SHORT_STRING, CATE_STRING, DESCRIPTION, ID_TYPE, ID_SHORT_STRING); } - + @Test public void testConstructor() { assertEquals(ID_SHORT_STRING, identifiable.getIdShort()); @@ -48,7 +63,7 @@ public void testConstructor() { assertEquals(new AdministrativeInformation(VERSION, REVISION), identifiable.getAdministration()); assertEquals(new Identifier(ID_TYPE, ID_SHORT_STRING), identifiable.getIdentification()); } - + @Test public void testSetAdministration() { String newVersion = "2.0"; @@ -57,7 +72,7 @@ public void testSetAdministration() { identifiable.setAdministration(information); assertEquals(information, identifiable.getAdministration()); } - + @Test public void testSetIdentification() { IdentifierType idType = IdentifierType.IRI; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java index d5d36b65..f68d51d1 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangString.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -24,7 +39,7 @@ public class TestLangString { private static final String LANGUAGE = "Eng"; private static final String DESCRIPTION = "test"; - + @Test public void testConstructor() { LangString langString = new LangString(LANGUAGE, DESCRIPTION); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java index 5a6fd7ec..871297d3 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestLangStrings.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -34,31 +49,31 @@ public class TestLangStrings { private static final String LANGUAGE2 = "Deu"; private static final String TEXT1 = "test"; private static final String TEXT2 = "test2"; - + @Test public void testConstructor1() { LangStrings langStrings = new LangStrings(LANGUAGE1, TEXT1); String textString = langStrings.get(LANGUAGE1); assertEquals(TEXT1, textString); } - + @Test public void testConstructor2() { LangString langString1 = new LangString(LANGUAGE1, TEXT1); LangString langString2 = new LangString(LANGUAGE2, TEXT2); - + Collection listsCollection = new ArrayList<>(); listsCollection.add(langString1); listsCollection.add(langString2); - + LangStrings langStrings = new LangStrings(listsCollection); String textString1 = langStrings.get(LANGUAGE1); assertEquals(TEXT1, textString1); - + String textString2 = langStrings.get(LANGUAGE2); assertEquals(TEXT2, textString2); } - + @Test public void testConstructor3() { LangString langString = new LangString(LANGUAGE1, TEXT1); @@ -66,38 +81,56 @@ public void testConstructor3() { String textString = langStrings.get(LANGUAGE1); assertEquals(TEXT1, textString); } - + @Test public void testAdd() { LangStrings langStrings = new LangStrings(LANGUAGE1, TEXT1); - + langStrings.add(new LangString(LANGUAGE2, TEXT2)); assertEquals(TEXT2, langStrings.get(LANGUAGE2)); } - + @Test public void testGetLanguages() { LangStrings langStrings = new LangStrings(LANGUAGE1, TEXT1); langStrings.add(new LangString(LANGUAGE2, TEXT2)); - + Set languageSet = new HashSet(); languageSet.add(LANGUAGE1); languageSet.add(LANGUAGE2); assertEquals(languageSet, langStrings.getLanguages()); } - + @Test public void testIsLangStrings() { LangStrings langStrings = new LangStrings(LANGUAGE1, TEXT1); - + assertTrue(LangStrings.isLangStrings(langStrings)); - + LangString langString = new LangString(LANGUAGE1, TEXT1); langString.put("language", null); - + langStrings.add(langString); - + assertFalse(LangStrings.isLangStrings(langStrings)); } - + + @Test + public void testFromStringPairs() { + LangStrings langStrings = LangStrings.fromStringPairs(LANGUAGE1, TEXT1, LANGUAGE2, TEXT2); + assertEquals(2, langStrings.getLanguages().size()); + assertEquals(TEXT1, langStrings.get(LANGUAGE1)); + assertEquals(TEXT2, langStrings.get(LANGUAGE2)); + } + + @Test + public void testFromStringPairsWithEmptyInput() { + LangStrings langStrings = LangStrings.fromStringPairs(); + assertEquals(0, langStrings.getLanguages().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringPairsWithOddNumber() { + LangStrings.fromStringPairs(LANGUAGE1); + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java index d16211c4..fc6df840 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/TestReferable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier; @@ -32,14 +47,14 @@ public class TestReferable { private static final String CATE_STRING = "testCategory"; private static final String ID_SHORT_STRING = "testIdShort"; private static final LangStrings DESCRIPTION = new LangStrings("Eng", "test"); - + private Referable referable; - + @Before public void buildReferable() { referable = new Referable(ID_SHORT_STRING, CATE_STRING, DESCRIPTION); } - + @Test public void testConstructor() { assertEquals(CATE_STRING, referable.getCategory()); @@ -47,28 +62,28 @@ public void testConstructor() { assertEquals(DESCRIPTION, referable.getDescription()); assertNull(referable.getParent()); } - + @Test public void testSetIdShort() { String newIdString = "newId"; referable.setIdShort(newIdString); assertEquals(newIdString, referable.getIdShort()); } - + @Test public void testSetCategory() { String newCategoryString = "newCategory"; referable.setCategory(newCategoryString); assertEquals(newCategoryString, referable.getCategory()); } - + @Test public void testSetDescription() { LangStrings newDescriptionString = new LangStrings("DE", "newTest"); referable.setDescription(newDescriptionString); assertEquals(newDescriptionString, referable.getDescription()); } - + @Test public void testSetParent() { Reference parent = new Reference(new Identifier(IdentifierType.IRDI, "testNewId"), KeyElements.ASSET, true); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java index f2f79b2d..d6b57af5 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/haskind/TestHasKind.java @@ -1,15 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.haskind; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; import org.eclipse.basyx.submodel.metamodel.map.qualifier.haskind.HasKind; @@ -17,31 +33,37 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link HasKind} for their - * correctness + * Tests constructor, setter and getter of {@link HasKind} for their correctness * * @author haque * */ public class TestHasKind { private static final ModelingKind MODELING_KIND = ModelingKind.INSTANCE; - + private HasKind hasKind; - + @Before public void buildHasKind() { hasKind = new HasKind(MODELING_KIND); } - + @Test public void testConstructor() { - assertEquals(hasKind.getModelingKind(), MODELING_KIND); + assertEquals(hasKind.getKind(), MODELING_KIND); } @Test public void testSetModelingKind() { ModelingKind newModelingKind = ModelingKind.TEMPLATE; - hasKind.setModelingKind(newModelingKind); - assertEquals(newModelingKind, hasKind.getModelingKind()); + hasKind.setKind(newModelingKind); + assertEquals(newModelingKind, hasKind.getKind()); + } + + @Test + public void testSetModelingKindOfNull() { + // Explicitly set null + hasKind.setKind(null); + assertNull(hasKind.getKind()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java index e2bd6822..7a12d750 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestFormula.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable; @@ -24,8 +39,7 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link Formula} for their - * correctness + * Tests constructor, setter and getter of {@link Formula} for their correctness * * @author haque * @@ -37,20 +51,20 @@ public class TestFormula { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE); private static final Reference REFERENCE = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); - + private Formula formula; - + @Before public void buildFormula() { formula = new Formula(Collections.singleton(REFERENCE)); } - + @Test public void testConstructor() { Collection references = Collections.singleton(REFERENCE); assertEquals(references, formula.getDependsOn()); } - + @Test public void testSetDependsOn() { Reference reference = new Reference(new Identifier(IdentifierType.IRDI, "newId"), KeyElements.BLOB, true); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java index 0ad6c112..6f205a61 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifiable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable; @@ -34,27 +49,27 @@ public class TestQualifiable { private static final Formula FORMULA1 = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI)))); private static final Formula FORMULA2 = new Formula(Collections.singleton(new Reference(new Key(KeyElements.ANNOTATEDRELATIONSHIPELEMENT, true, "TestValue2", IdentifierType.IRDI)))); - + @Test public void testConstructor1() { Qualifiable qualifiable = new Qualifiable(FORMULA1); assertEquals(Collections.singleton(FORMULA1), qualifiable.getQualifiers()); } - + @Test public void testConstructor2() { Collection constraints = new HashSet(); constraints.add(FORMULA1); constraints.add(FORMULA2); - + Qualifiable qualifiable = new Qualifiable(constraints); assertEquals(constraints, qualifiable.getQualifiers()); } - + @Test public void testSetQualifier() { Qualifiable qualifiable = new Qualifiable(FORMULA1); - + qualifiable.setQualifiers(Collections.singleton(FORMULA2)); assertEquals(Collections.singleton(FORMULA2), qualifiable.getQualifiers()); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java index 2e2f0178..97cb27cc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/qualifier/qualifiable/TestQualifier.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.qualifier.qualifiable; import static org.junit.Assert.assertEquals; -import java.util.HashMap; +import java.util.LinkedHashMap; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; @@ -38,14 +53,14 @@ public class TestQualifier { private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; private static final Identifier IDENTIFIER = new Identifier(ID_TYPE, VALUE); private static final Reference VALUE_ID = new Reference(IDENTIFIER, KEY_ELEMENTS, IS_LOCAL); - + private Qualifier qualifier; - + @Before public void buildQualifier() { - qualifier = new Qualifier(TYPE, VALUE, VALUE_TYPE, VALUE_ID); + qualifier = new Qualifier(TYPE, VALUE, VALUE_TYPE, VALUE_ID); } - + @Test public void testConstructor() { assertEquals(TYPE, qualifier.getType()); @@ -53,35 +68,35 @@ public void testConstructor() { assertEquals(ValueTypeHelper.fromName(VALUE_TYPE), qualifier.getValueType()); assertEquals(VALUE_ID, qualifier.getValueId()); } - + @Test public void testSetType() { String newTypeString = "newType"; qualifier.setType(newTypeString); assertEquals(newTypeString, qualifier.getType()); } - + @Test public void testSetValue() { String newValueString = "newValue"; qualifier.setValue(newValueString); assertEquals(newValueString, qualifier.getValue()); } - + @Test public void testSetValueId() { Reference reference = new Reference(new Identifier(IdentifierType.IRI, "newId"), KeyElements.BLOB, true); qualifier.setValueId(reference); assertEquals(reference, qualifier.getValueId()); } - + @Test public void testSetValueType() { ValueType newValueTypeString = ValueType.AnyType; qualifier.setValueType(newValueTypeString); assertEquals(newValueTypeString, qualifier.getValueType()); } - + // Tests if the valueType is correctly converted to a string @Test public void testSetValueCorrectValueType() { @@ -96,11 +111,11 @@ public void testSetSemanticID() { qualifier.setSemanticId(reference); assertEquals(reference, qualifier.getSemanticId()); } - + @SuppressWarnings("unchecked") - @Test - public void testModelType() { - HashMap modelType = (HashMap)qualifier.get(ModelType.MODELTYPE); - assertEquals(Qualifier.MODELTYPE, modelType.get(ModelType.NAME)); - } + @Test + public void testModelType() { + LinkedHashMap modelType = (LinkedHashMap) qualifier.get(ModelType.MODELTYPE); + assertEquals(Qualifier.MODELTYPE, modelType.get(ModelType.NAME)); + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java index a274010d..2ae800ac 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestKey.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.reference; @@ -22,8 +37,7 @@ import org.junit.Test; /** - * Tests constructor, setter and getter of {@link Key} for their - * correctness + * Tests constructor, setter and getter of {@link Key} for their correctness * * @author haque * @@ -34,72 +48,72 @@ public class TestKey { private static final String VALUE = "testValue"; private static final KeyType KEY_TYPE = KeyType.CUSTOM; private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; - + private Key key; - + @Before public void buildKey() { - key = new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, KEY_TYPE); + key = new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, KEY_TYPE); } - + @Test - public void testConstructor1() { - assertEquals(KEY_ELEMENTS, key.getType()); - assertTrue(!key.isLocal()); - assertEquals(VALUE, key.getValue()); - assertEquals(KEY_TYPE, key.getIdType()); + public void testConstructor1() { + assertEquals(KEY_ELEMENTS, key.getType()); + assertTrue(!key.isLocal()); + assertEquals(VALUE, key.getValue()); + assertEquals(KEY_TYPE, key.getIdType()); } - + @Test public void testConstructor2() { - assertEquals(KEY_ELEMENTS, key.getType()); - assertTrue(!key.isLocal()); - assertEquals(VALUE, key.getValue()); - assertEquals(KeyType.fromString(ID_TYPE.toString()), key.getIdType()); + assertEquals(KEY_ELEMENTS, key.getType()); + assertTrue(!key.isLocal()); + assertEquals(VALUE, key.getValue()); + assertEquals(KeyType.fromString(ID_TYPE.toString()), key.getIdType()); } - + @Test public void testIsLocal() { assertTrue(!key.isLocal()); - + } - + @Test public void testSetType() { KeyElements type = KeyElements.ENTITY; key.setType(type); assertEquals(type, key.getType()); } - + @Test public void testSetLocal() { key.setLocal(true); assertTrue(key.isLocal()); } - + @Test public void testSetValue() { key.setValue(null); assertNull(key.getValue()); - + String newValue = "test"; key.setValue(newValue); assertEquals(newValue, key.getValue()); } - + @Test public void testSetIdType() { KeyType type = KeyType.IRI; key.setIdType(type); assertEquals(type, key.getIdType()); } - + @Test public void testIsKey() { assertTrue(Key.isKey(key)); - + key.put(Key.IDTYPE, "nonsense"); - + assertFalse(Key.isKey(key)); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java index 61c2ed17..1850551b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/reference/TestReference.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.reference; @@ -30,7 +45,6 @@ import org.eclipse.basyx.vab.support.TypeDestroyer; import org.junit.Test; - /** * Tests constructor, setter and getter of {@link Reference} for their * correctness @@ -44,15 +58,15 @@ public class TestReference { private static final String VALUE = "testValue"; private static final KeyType KEY_TYPE = KeyType.IRDI; private static final IdentifierType ID_TYPE = IdentifierType.CUSTOM; - + @Test - public void testConstructor1() { + public void testConstructor1() { Identifiable identifiable = new Identifiable("2.0", "5", "testIDShort", "testCategory", new LangStrings("Eng", "test"), IdentifierType.IRI, "newId"); Collection keys = Collections.singletonList(new Key(KEY_ELEMENTS, IS_LOCAL, identifiable.getIdentification().getId(), identifiable.getIdentification().getIdType())); Reference reference = new Reference(identifiable, KEY_ELEMENTS, IS_LOCAL); assertEquals(keys, reference.getKeys()); } - + @Test public void testConstructor2() { Identifier identifier = new Identifier(ID_TYPE, VALUE); @@ -60,46 +74,46 @@ public void testConstructor2() { Collection keys = Collections.singletonList(new Key(KEY_ELEMENTS, IS_LOCAL, identifier.getId(), identifier.getIdType())); assertEquals(keys, reference.getKeys()); } - + @Test public void testConstructor3() { List keysList = new ArrayList(); keysList.add(new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, ID_TYPE)); keysList.add(new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, KEY_TYPE)); - + Reference reference = new Reference(keysList); assertEquals(keysList, reference.getKeys()); } - + @Test public void testConstructor4() { Key key = new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, ID_TYPE); - + Reference reference = new Reference(key); assertEquals(Collections.singletonList(key), reference.getKeys()); } - + @Test public void testSetKeys() { List keysList = new ArrayList(); keysList.add(new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, ID_TYPE)); keysList.add(new Key(KEY_ELEMENTS, IS_LOCAL, VALUE, KEY_TYPE)); - + Reference reference = new Reference(new Identifier(ID_TYPE, VALUE), KEY_ELEMENTS, IS_LOCAL); - reference.setKeys(keysList); + reference.setKeys(keysList); assertEquals(keysList, reference.getKeys()); } - + @Test public void testIsReference() { Identifiable identifiable = new Identifiable("2.0", "5", "testIDShort", "testCategory", new LangStrings("Eng", "test"), IdentifierType.IRI, "newId"); Reference reference = new Reference(identifiable, KEY_ELEMENTS, IS_LOCAL); - + assertTrue(Reference.isReference(reference)); assertTrue(Reference.isReference(TypeDestroyer.destroyType(reference))); - + reference.put(Reference.KEY, "nonsense"); - + assertFalse(Reference.isReference(reference)); assertFalse(Reference.isReference(TypeDestroyer.destroyType(reference))); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java index 0898ed95..05ee7b5d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement; @@ -31,8 +46,7 @@ import org.junit.Test; /** - * Tests constructor and getter of {@link SubmodelElement} for their - * correctness + * Tests constructor and getter of {@link SubmodelElement} for their correctness * * @author haque * @@ -40,21 +54,21 @@ public class TestSubmodelElement { private static final Reference REFERENCE = new Reference(new Identifier(IdentifierType.CUSTOM, "testValue"), KeyElements.ACCESSPERMISSIONRULE, false); private static final Formula FORMULA = new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI)))); - + private SubmodelElement submodelElement; - + @Before public void buidSubmodelElement() { submodelElement = new Property("testIdShort", "testId"); } - + @Test public void testSetDataSpecificationReferences() { Collection refs = Collections.singleton(REFERENCE); submodelElement.setDataSpecificationReferences(refs); assertEquals(refs, submodelElement.getDataSpecificationReferences()); - } - + } + @Test public void testSetEmbeddedDataSpecifications() { EmbeddedDataSpecification embeddedDataSpecification = new EmbeddedDataSpecification(); @@ -62,50 +76,50 @@ public void testSetEmbeddedDataSpecifications() { submodelElement.setEmbeddedDataSpecifications(specifications); assertEquals(specifications, submodelElement.getEmbeddedDataSpecifications()); } - + @Test public void testSetIdShort() { String newIdString = "newId"; submodelElement.setIdShort(newIdString); assertEquals(newIdString, submodelElement.getIdShort()); } - + @Test public void testSetCategory() { String newCategoryString = "newCategory"; submodelElement.setCategory(newCategoryString); assertEquals(newCategoryString, submodelElement.getCategory()); } - + @Test public void testSetDescription() { LangStrings newDescriptionString = new LangStrings("DE", "newTest"); submodelElement.setDescription(newDescriptionString); assertEquals(newDescriptionString, submodelElement.getDescription()); } - + @Test public void testSetParent() { submodelElement.setParent(REFERENCE); assertEquals(REFERENCE, submodelElement.getParent()); } - + @Test public void testSetQualifier() { submodelElement.setQualifiers(Collections.singleton(FORMULA)); assertEquals(Collections.singleton(FORMULA), submodelElement.getQualifiers()); } - + @Test public void testSetSemanticID() { submodelElement.setSemanticId(REFERENCE); assertEquals(REFERENCE, submodelElement.getSemanticId()); } - + @Test public void testSetModelingKind() { ModelingKind newModelingKind = ModelingKind.TEMPLATE; - submodelElement.setModelingKind(newModelingKind); - assertEquals(newModelingKind, submodelElement.getModelingKind()); + submodelElement.setKind(newModelingKind); + assertEquals(newModelingKind, submodelElement.getKind()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java index 27212433..08bb37a6 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/TestSubmodelElementCollection.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement; @@ -13,12 +28,15 @@ import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import org.eclipse.basyx.aas.metamodel.exception.IdShortDuplicationException; import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; @@ -36,6 +54,7 @@ import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; @@ -57,7 +76,7 @@ public class TestSubmodelElementCollection { private Collection elements1; private Collection elements2; private SubmodelElementCollection elementCollection; - + @Before public void buildSubmodelElementCollection() { elements1 = new ArrayList<>(); @@ -66,39 +85,39 @@ public void buildSubmodelElementCollection() { elements2 = new ArrayList(); elements2.add(new Property("idShort1", "testId1")); - elements2.add(new Property("idShort2","testId2")); + elements2.add(new Property("idShort2", "testId2")); elementCollection = new SubmodelElementCollection(elements2, false, false); elementCollection.setIdShort("testCollectionId"); - } + } @Test public void testConstructor() { SubmodelElementCollection elementCollection = new SubmodelElementCollection(elements1, true, true); assertTrue(elementCollection.isAllowDuplicates()); assertTrue(elementCollection.isOrdered()); - + ISubmodelElement checkOperation = elementCollection.getSubmodelElements().get(OPERATION_ID); assertEquals(OPERATION_ID, checkOperation.getIdShort()); - } - + } + @Test public void testAddValue() { Property element = new Property("testProperty"); element.setIdShort("propId"); elementCollection.addSubmodelElement(element); elements2.add(element); - + ISubmodelElement checkProperty = elementCollection.getSubmodelElements().get("propId"); assertEquals(element.getIdShort(), checkProperty.getIdShort()); - } - + } + @Test public void testSetDataSpecificationReferences() { Collection refs = Collections.singleton(REFERENCE); elementCollection.setDataSpecificationReferences(refs); assertEquals(refs, elementCollection.getDataSpecificationReferences()); - } - + } + @Test public void testSetValue() { Collection elements = new ArrayList(); @@ -106,23 +125,36 @@ public void testSetValue() { element.setIdShort("propId"); elements.add(element); elementCollection.setValue(elements); - + ISubmodelElement checkProperty = elementCollection.getSubmodelElements().get("propId"); assertEquals(element.getIdShort(), checkProperty.getIdShort()); - } - + } + @Test public void testSetOrdered() { elementCollection.setOrdered(false); assertTrue(!elementCollection.isOrdered()); - } - + } + @Test public void testSetAllowDuplicates() { elementCollection.setAllowDuplicates(false); assertTrue(!elementCollection.isAllowDuplicates()); - } - + } + + @Test + public void testKeepsOrderWhenOrdered() { + SubmodelElementCollection sec1 = new SubmodelElementCollection("sec1"); + sec1.setOrdered(true); + sec1.addSubmodelElement(new Property("id1", "blub1")); + sec1.addSubmodelElement(new Property("id2", "blub2")); + sec1.addSubmodelElement(new Property("id3", "blub3")); + sec1.addSubmodelElement(new Property("id4", "blub4")); + + List idShortsInOrder = sec1.getValue().stream().map(e -> e.getIdShort()).collect(Collectors.toList()); + assertEquals(Arrays.asList("id1", "id2", "id3", "id4"), idShortsInOrder); + } + @Test public void testSetElements() { String idShort = "testIdShort"; @@ -131,20 +163,19 @@ public void testSetElements() { Formula formula = new Formula(Collections.singleton(reference)); Qualifiable qualifiable = new Qualifiable(formula); ISubmodelElement element = new Property("testId1", new Referable(idShort, "Category", new LangStrings("DE", "Test")), REFERENCE, qualifiable); - Map elementsMap = new HashMap(); + Map elementsMap = new LinkedHashMap(); elementsMap.put(idShort, element); elementCollection.setElements(elementsMap); assertEquals(elementsMap, elementCollection.getSubmodelElements()); - } - + } @Test public void testConstructor1() { SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false); - Map dataElements = new HashMap(); - Map operations = new HashMap(); - Map submodels = new HashMap(); + Map dataElements = new LinkedHashMap(); + Map operations = new LinkedHashMap(); + Map submodels = new LinkedHashMap(); dataElements.put(PROPERTY_ID, getProperty()); operations.put(OPERATION_ID, getOperation()); submodels.putAll(operations); @@ -164,39 +195,62 @@ public void testAddSubmodelElement() { property.put(Referable.IDSHORT, newIdShort); collection.addSubmodelElement(property); assertEquals(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, smCollIdShort, KeyType.IDSHORT)), property.getParent()); - Map submodelElements = new HashMap(); + Map submodelElements = new LinkedHashMap(); submodelElements.put(PROPERTY_ID, getProperty()); submodelElements.put(OPERATION_ID, getOperation()); submodelElements.put(newIdShort, property); assertEquals(submodelElements, collection.getSubmodelElements()); } - + @Test public void testGetSubmodelElement() { SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false); ISubmodelElement retrievedElement = collection.getSubmodelElement(PROPERTY_ID); assertEquals(getProperty(), retrievedElement); } - + @Test(expected = ResourceNotFoundException.class) public void testGetSubmodelElementNotExist() { SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false); collection.getSubmodelElement("Id_Which_Does_Not_Exist"); } - + @Test(expected = ResourceNotFoundException.class) public void testDeleteSubmodelElement() { SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false); collection.deleteSubmodelElement(PROPERTY_ID); collection.getSubmodelElement(PROPERTY_ID); } - + @Test(expected = ResourceNotFoundException.class) public void testDeleteSubmodelElementNotExist() { SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false); collection.deleteSubmodelElement("Id_Which_Does_Not_Exist"); } + @Test + public void testGetValues() { + SubmodelElementCollection collection = new SubmodelElementCollection(elements1, false, false); + collection.setIdShort("smColl"); + Map elements = collection.getValues(); + Property property = getProperty(); + assertEquals(1, elements.size()); + assertTrue(elements.containsKey(PROPERTY_ID)); + assertEquals(property.getValue(), elements.get(PROPERTY_ID)); + + String newKey = "newKey"; + String newValue = "newValue"; + + Property property2 = new Property(newKey, newValue); + property2.setValueType(ValueType.String); + collection.addSubmodelElement(property2); + + elements = collection.getValues(); + assertEquals(2, elements.size()); + assertTrue(elements.containsKey(newKey)); + assertEquals(newValue, elements.get(newKey)); + } + /** * Get a dummy property * @@ -205,8 +259,7 @@ public void testDeleteSubmodelElementNotExist() { private Property getProperty() { Referable referable = new Referable(PROPERTY_ID, "testCategory", new LangStrings("DE", "test")); Reference semanticId = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI)); - Qualifiable qualifiable = new Qualifiable(new Formula(Collections - .singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))))); + Qualifiable qualifiable = new Qualifiable(new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))))); Property property = new Property("testValue", referable, semanticId, qualifiable); return property; } @@ -218,11 +271,34 @@ private Property getProperty() { */ private Operation getOperation() { Property property = new Property("testOpVariableId"); - property.setModelingKind(ModelingKind.TEMPLATE); - List variable = Collections - .singletonList(new OperationVariable(property)); + property.setKind(ModelingKind.TEMPLATE); + List variable = Collections.singletonList(new OperationVariable(property)); Operation operation = new Operation(variable, variable, variable, null); operation.put(Referable.IDSHORT, OPERATION_ID); return operation; } + + @Test(expected = IdShortDuplicationException.class) + public void checkForExceptionWithDuplicateIdShortInSubmodelElementCollection() { + Map faultySubmodelElementCollection = createSubmodelElementCollectionWithDuplicateIdShortProperties(); + + SubmodelElementCollection.createAsFacade(faultySubmodelElementCollection); + } + + private Map createSubmodelElementCollectionWithDuplicateIdShortProperties() { + String duplicateIdShort = "testProp"; + + Property property1 = new Property(duplicateIdShort, 5); + Property property2 = new Property(duplicateIdShort, 7); + + Collection> collection = Arrays.asList(property1, property2); + + String idShort = "submodelElementCollectionIdShort"; + + SubmodelElementCollection submodelElementCollection = new SubmodelElementCollection(idShort); + + submodelElementCollection.setValue(collection); + + return submodelElementCollection; + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java index 953d6492..0005ebc1 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestBlob.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement; @@ -33,12 +48,12 @@ public class TestBlob { protected String testString = "NEW!"; protected byte[] testBytes = testString.getBytes(StandardCharsets.UTF_8); protected String testBase64 = Base64.getEncoder().encodeToString(testBytes); - + @Before public void build() { blob = new Blob("testIdShort", "mimeType"); } - + /** * Tests if getMimeType() returns the correct value */ @@ -65,7 +80,7 @@ public void testSetValue() { assertArrayEquals(testBytes, blob.getByteArrayValue()); assertEquals(testBase64, blob.getValue()); } - + /** * Tests if setUTF8 sets the correct value */ diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java index f5da0763..c862ca0e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestFile.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement; @@ -16,8 +31,7 @@ import org.junit.Test; /** - * Tests constructor and getter of {@link File} for their - * correctness + * Tests constructor and getter of {@link File} for their correctness * * @author haque * @@ -26,30 +40,30 @@ public class TestFile { private static final String VALUE = "testValue"; private static final String MIME_TYPE = "testMime"; private File file; - + @Before public void buildFile() { file = new File(VALUE, MIME_TYPE); - } - + } + @Test public void testConstructor() { assertEquals(VALUE, file.getValue()); assertEquals(MIME_TYPE, file.getMimeType()); assertEquals(File.MODELTYPE, file.getModelType()); - } - + } + @Test public void testSetValue() { String newValue = "testNewValue"; file.setValue(newValue); assertEquals(newValue, file.getValue()); - } + } @Test public void testSetMimeType() { String newMimeType = "testMimeType"; file.setMimeType(newMimeType); assertEquals(newMimeType, file.getMimeType()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java index c5336c56..ff3105e0 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/TestReferenceElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement; @@ -30,24 +45,24 @@ */ public class TestReferenceElement { private static final Reference REFERENCE = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI)); - + private ReferenceElement referenceElement; - + @Before public void buildReferenceElement() { referenceElement = new ReferenceElement(REFERENCE); - } - + } + @Test public void testConstructor() { assertEquals(REFERENCE, referenceElement.getValue()); assertEquals(ReferenceElement.MODELTYPE, referenceElement.getModelType()); - } - + } + @Test public void testSetValue() { Reference newReference = new Reference(new Identifier(IdentifierType.IRI, "testId"), KeyElements.ASSET, true); referenceElement.setValue(newReference); assertEquals(newReference, referenceElement.getValue()); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java index 17891dc2..539e4cfa 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/property/TestProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement.property; @@ -42,7 +57,6 @@ import org.junit.Before; import org.junit.Test; - /** * Tests constructor, getter and setter of {@link Property} for their * correctness @@ -59,16 +73,16 @@ public class TestProperty { public void buildFile() { property = new Property(VALUE); } - + @Test - public void testConstructor1(){ + public void testConstructor1() { assertEquals(VALUE, property.getValue()); assertNull(property.getValueId()); assertEquals(STRING_TYPE, property.getValueType()); - } - + } + @Test - public void testConstructor2(){ + public void testConstructor2() { Referable referable = new Referable("testIdShort", "testCategory", new LangStrings("DE", "test")); Reference semanticId = new Reference(new Key(KeyElements.ASSET, true, "testValue", IdentifierType.IRI)); Qualifiable qualifiable = new Qualifiable(new Formula(Collections.singleton(new Reference(new Key(KeyElements.BLOB, true, "TestValue", IdentifierType.IRI))))); @@ -76,16 +90,16 @@ public void testConstructor2(){ assertEquals(VALUE, property.getValue()); assertNull(property.getValueId()); assertEquals(STRING_TYPE, property.getValueType()); - } - + } + @Test public void testSetValueType() { property.setValueType(ValueType.String); assertEquals(STRING_TYPE, property.getValueType()); - } - + } + @Test - public void testSet() throws DatatypeConfigurationException{ + public void testSet() throws DatatypeConfigurationException { Property booleanProp = new Property(); Boolean isSomething = true; booleanProp.setValue(isSomething); @@ -97,7 +111,7 @@ public void testSet() throws DatatypeConfigurationException{ byteProp.setValue(byteNumber); assertEquals(byteNumber, byteProp.getValue()); assertEquals(ValueType.Int8, byteProp.getValueType()); - + Duration duration = Duration.ofSeconds(10); Property durationProp = new Property(); durationProp.setValue(duration); @@ -117,7 +131,7 @@ public void testSet() throws DatatypeConfigurationException{ bigNumberProp.setValue(bignumber); assertEquals(bignumber, bigNumberProp.getValue()); assertEquals(ValueType.PositiveInteger, bigNumberProp.getValueType()); - + Property dateProp = new Property(); GregorianCalendar dateValue = GregorianCalendar.from(ZonedDateTime.of(birthday, LocalTime.MIDNIGHT, ZoneId.of("UTC"))); XMLGregorianCalendar xmlDateValue = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateValue); @@ -127,7 +141,7 @@ public void testSet() throws DatatypeConfigurationException{ } @Test - public void testSetCustom(){ + public void testSetCustom() { property.set(null, ValueType.String); assertEquals(null, property.getValue()); assertEquals(ValueType.String, property.getValueType()); @@ -139,6 +153,9 @@ public void testSetId() { IReference ref2 = new Reference(new Key(KeyElements.PROPERTY, true, "custom", IdentifierType.CUSTOM)); property.setValueId(ref); assertEquals(ref2, property.getValueId()); + + property.setValueId(null); + assertNull(property.getValueId()); } @Test @@ -149,7 +166,7 @@ public void testAddConceptDescription() { property.addConceptDescription(description); assertEquals(new Reference(description, KeyElements.CONCEPTDESCRIPTION, true), property.getSemanticId()); } - + @Test public void testInitializeWithNullValue() { try { @@ -158,7 +175,7 @@ public void testInitializeWithNullValue() { fail(); } catch (RuntimeException e) { } - + try { // Should not work as valueType can not be set with null as value Property prop = new Property(); @@ -166,7 +183,7 @@ public void testInitializeWithNullValue() { fail(); } catch (RuntimeException e) { } - + Property prop = new Property("id", "value"); // This should work as the valueType is already set prop.setValue(null); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java index d2a6c860..d8af370a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/dataelement/range/TestRange.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.dataelement.range; @@ -17,7 +32,6 @@ import org.junit.Before; import org.junit.Test; - /** * Test for Range * @@ -29,20 +43,20 @@ public class TestRange { private static final int MIN = 0; private static final int MAX = 10; private Range range; - + @Before public void buildRange() { range = new Range(ValueType.Integer, MIN, MAX); } - + @Test public void testGetValue() { assertEquals(MIN, range.getMin()); assertEquals(MAX, range.getMax()); - + RangeValue value = range.getValue(); assertEquals(MIN, value.getMin()); assertEquals(MAX, value.getMax()); - } - + } + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java index 284e0cf1..7076c448 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/AsyncOperationHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; @@ -25,7 +40,7 @@ * */ public class AsyncOperationHelper { - + public static final String ASYNC_OP_ID = "asyncOperation"; public static Collection IN; protected static Collection OUT; @@ -33,23 +48,23 @@ public class AsyncOperationHelper { private Object waitObject = new Object(); private boolean shouldWait = true; - + public AsyncOperationHelper() { IN = new ArrayList(); OUT = new ArrayList(); Property asyncIn1 = new Property("asyncIn1", ""); - asyncIn1.setModelingKind(ModelingKind.TEMPLATE); + asyncIn1.setKind(ModelingKind.TEMPLATE); Property asyncIn2 = new Property("asyncIn2", ""); - asyncIn2.setModelingKind(ModelingKind.TEMPLATE); + asyncIn2.setKind(ModelingKind.TEMPLATE); IN.add(new OperationVariable(asyncIn1)); IN.add(new OperationVariable(asyncIn2)); Property asyncOut = new Property("asyncOut", ""); - asyncOut.setModelingKind(ModelingKind.TEMPLATE); + asyncOut.setKind(ModelingKind.TEMPLATE); OUT.add(new OperationVariable(asyncOut)); } - + private final Function ASYNC_FUNC = (Function) v -> { - int result = (int)v[0] + (int)v[1]; + int result = (int) v[0] + (int) v[1]; synchronized (waitObject) { while (shouldWait) { try { @@ -60,7 +75,7 @@ public AsyncOperationHelper() { } return result; }; - + private final Function ASYNC_EXCEPTION_FUNC = (Function) v -> { NullPointerException ex = new NullPointerException(); synchronized (waitObject) { @@ -73,7 +88,7 @@ public AsyncOperationHelper() { } throw ex; }; - + public Operation getAsyncOperation() { shouldWait = true; Operation op = new Operation(ASYNC_FUNC); @@ -82,25 +97,25 @@ public Operation getAsyncOperation() { op.setOutputVariables(OUT); return op; } - + public Operation getAsyncExceptionOperation() { shouldWait = true; Operation op = new Operation(ASYNC_EXCEPTION_FUNC); op.setIdShort(ASYNC_EXCEPTION_OP_ID); return op; } - + public void releaseWaitingOperation() { shouldWait = false; synchronized (waitObject) { waitObject.notifyAll(); } - + // Give the Operation a bit of time to finish try { Thread.sleep(100); } catch (InterruptedException e) { } } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java index de18ee71..c37ed5c7 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperation.java @@ -1,16 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Collection; @@ -23,7 +37,6 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; import org.eclipse.basyx.submodel.metamodel.map.reference.Key; import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; -import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; import org.junit.Test; @@ -35,59 +48,64 @@ * */ public class TestOperation extends TestOperationSuite { - + private static final String KEY_VALUE = "testKeyValue"; - + + private int setValueForTestSetNoInNoOutFunctionAsInvokable; + @Override protected IOperation prepareOperation(Operation operation) { return operation; } - + @Test public void testOptionalElements() throws Exception { - operation = new Operation(null, null, null, FUNC); - assertEquals(0, operation.getInputVariables().size()); - assertEquals(0, operation.getOutputVariables().size()); - assertEquals(0, operation.getInOutputVariables().size()); + simpleOperation = new Operation(null, null, null, SIMPLE_FUNC); + assertEquals(0, simpleOperation.getInputVariables().size()); + assertEquals(0, simpleOperation.getOutputVariables().size()); + assertEquals(0, simpleOperation.getInOutputVariables().size()); } - - @Test - public void testSetInvocable() throws Exception { - Operation operation = new Operation(IN, OUT, INOUT, FUNC); + + @Test + public void testSetFunctionAsInvokable() throws Exception { + Operation operation = new Operation(TWO_IN, OUT, INOUT, SIMPLE_FUNC); + operation.setIdShort("function"); assertEquals(5, operation.invoke(3, 2)); - + Function newFunction = (Function) v -> { - return (int)v[0] - (int)v[1]; + return (int) v[0] - (int) v[1]; }; operation.setInvokable(newFunction); - - assertEquals(1, operation.invoke(3,2)); + + assertEquals(1, operation.invoke(3, 2)); } - @Override @Test - public void testInvokeWithSubmodelElements() { - Property param1 = new Property("testIn1", 1); - Property param2 = new Property("testIn2", 1); - try { - operation.invoke(param1, param2); - // Only unwrapped invokation is supported for local operations - fail(); - } catch (UnsupportedOperationException e) { - } + public void testSetNoInNoOutFunctionAsInvokable() throws Exception { + Operation operation = new Operation("noInNoOutFunction"); + setValueForTestSetNoInNoOutFunctionAsInvokable = 0; + int expected = 10; + + operation.setInvokable(() -> { + setValueForTestSetNoInNoOutFunctionAsInvokable = expected; + }); + + operation.invokeSimple(); + + assertEquals(expected, setValueForTestSetNoInNoOutFunctionAsInvokable); } @Test public void testSetDataSpecificationReferences() { - Operation operation = new Operation(IN, OUT, INOUT, FUNC); + Operation operation = new Operation(TWO_IN, OUT, INOUT, SIMPLE_FUNC); Collection references = Collections.singleton(new Reference(new Key(KeyElements.ASSET, true, KEY_VALUE, IdentifierType.IRI))); operation.setDataSpecificationReferences(references); - + Collection newReferences = operation.getDataSpecificationReferences(); assertEquals(1, newReferences.size()); - + IReference newReference = new ArrayList<>(newReferences).get(0); - + assertEquals(KEY_VALUE, newReference.getKeys().get(0).getValue()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationInput.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationInput.java new file mode 100644 index 00000000..1d1792b3 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationInput.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; + +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; + +/** + * Tests inputs of {@link Operation} for their correctness + * + * @author espen, fischer + * + */ +public class TestOperationInput extends TestOperationInputSuite { + + @Override + protected IOperation prepareOperation(Operation operation) { + return operation; + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationInputSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationInputSuite.java new file mode 100644 index 00000000..dedfdd81 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationInputSuite.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.function.Function; + +import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.map.reference.Key; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement; +import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for different parameters in operations with submodelElements. + * + * @author espen, fischer + * + */ +public abstract class TestOperationInputSuite { + protected static final String IN_VALUE = "inValue"; + protected static final String IN_IDSHORT1 = "testIn1"; + protected static final String IN_IDSHORT2 = "testIn2"; + protected static final String OUT_VALUE = "outValue"; + protected static final String OUT_IDSHORT = "testOut"; + protected static final String INOUT_VALUE = "inOutValue"; + protected static final String INOUT_IDSHORT = "testInOut"; + protected static final String RELATIONSHIP_ID_SHORT = "relationshipIdShort"; + protected static final String RELATIONSHIP_FIRST_REFERENCE_ID_SHORT = "firstId"; + protected static final String RELATIONSHIP_SECOND_REFERENCE_ID_SHORT = "secondId"; + protected static final String OPERATION_ID_SHORT = "operationIdShort"; + protected static final String OPERATION_PROPERTY_ID_SHORT = "propertyId"; + + protected static Collection TWO_IN; + protected static Collection OUT; + protected static Collection INOUT; + + protected static final Function, SubmodelElement[]> OPERATION_FUNC = (Function, SubmodelElement[]>) inputMap -> { + return new SubmodelElement[] { inputMap.get(OPERATION_ID_SHORT) }; + }; + + protected static final Function SIMPLE_FUNC = (Function) v -> { + return (int) v[0] + (int) v[1]; + }; + + protected IOperation simpleOperation; + protected IOperation operationOperation; + + /** + * Converts an Operation into the IOperation to be tested + */ + protected abstract IOperation prepareOperation(Operation operation); + + @Before + public void setup() { + TWO_IN = createTwoInputVariables(); + OUT = createOutputVariables(); + INOUT = createInOutVariables(); + + operationOperation = createOperationOperation(); + simpleOperation = createAddOperation(); + } + + private IOperation createAddOperation() { + Operation op = new Operation(TWO_IN, OUT, INOUT, SIMPLE_FUNC); + op.setIdShort("SimpleOperation"); + return prepareOperation(op); + } + + private IOperation createOperationOperation() { + Operation op = new Operation("operation"); + op.setInputVariables(createOperationOperationVariable()); + op.setOutputVariables(createOperationOperationVariable()); + op.setWrappedInvokable(OPERATION_FUNC); + + return prepareOperation(op); + } + + private Collection createOperationOperationVariable() { + Operation operation = createOperationForOperationInputVariables(); + + OperationVariable operationVariable = new OperationVariable(operation); + + return Arrays.asList(operationVariable); + } + + private Operation createOperationForOperationInputVariables() { + Property p1 = new Property(OPERATION_PROPERTY_ID_SHORT, ""); + OperationVariable opV = new OperationVariable(p1); + + Operation operation = new Operation("inputOperation"); + operation.setInputVariables(Arrays.asList(opV)); + operation.setIdShort(OPERATION_ID_SHORT); + operation.setKind(ModelingKind.TEMPLATE); + + return operation; + } + + private RelationshipElement createRelationshipElementAsInput(String idShort) { + Reference firstReference = new Reference(new Key(KeyElements.RELATIONSHIPELEMENT, false, RELATIONSHIP_FIRST_REFERENCE_ID_SHORT, KeyType.IDSHORT)); + Reference secondReference = new Reference(new Key(KeyElements.RELATIONSHIPELEMENT, false, RELATIONSHIP_SECOND_REFERENCE_ID_SHORT, KeyType.IDSHORT)); + RelationshipElement relationshipElement = new RelationshipElement(idShort, firstReference, secondReference); + + return relationshipElement; + } + + private Collection createInOutVariables() { + Property inOutProp = new Property(INOUT_IDSHORT, INOUT_VALUE); + inOutProp.setValueType(ValueType.Integer); + inOutProp.setKind(ModelingKind.TEMPLATE); + return Arrays.asList(new OperationVariable(inOutProp)); + } + + private Collection createOutputVariables() { + Property outProp = new Property(OUT_IDSHORT, OUT_VALUE); + outProp.setValueType(ValueType.Integer); + outProp.setKind(ModelingKind.TEMPLATE); + + return Arrays.asList(new OperationVariable(outProp)); + } + + private Collection createTwoInputVariables() { + Property inProp1 = new Property(IN_IDSHORT1, IN_VALUE); + inProp1.setKind(ModelingKind.TEMPLATE); + + Property inProp2 = new Property(IN_IDSHORT2, IN_VALUE); + inProp2.setKind(ModelingKind.TEMPLATE); + + return Arrays.asList(new OperationVariable(inProp1), new OperationVariable(inProp2)); + } + + @Test + public void testInvokeWithInvalidIdShortAndModelType() { + RelationshipElement input = createRelationshipElementAsInput(RELATIONSHIP_ID_SHORT); + + try { + operationOperation.invoke(input); + fail(); + } catch (Exception e) { + // Exceptions from ConnectedOperation are wrapped in ProviderException + assertTrue(e instanceof MalformedRequestException || e.getCause() instanceof MalformedRequestException); + } + } + + @Test + public void testInvokeWithInvalidModelType() { + RelationshipElement input = createRelationshipElementAsInput(OPERATION_ID_SHORT); + + try { + operationOperation.invoke(input); + fail(); + } catch (Exception e) { + // Exceptions from ConnectedOperation are wrapped in ProviderException + assertTrue(e instanceof MalformedRequestException || e.getCause() instanceof MalformedRequestException); + } + } + + @Test + public void testInvokeWithInvalidSubmodelElementType() { + Property invalidInput = new Property(OPERATION_ID_SHORT, 2); + + try { + operationOperation.invoke(invalidInput); + fail(); + } catch (Exception e) { + // Exceptions from ConnectedOperation are wrapped in ProviderException + assertTrue(e instanceof MalformedRequestException || e.getCause() instanceof MalformedRequestException); + } + } + + @Test + public void testSimpleInvokeWithInvalidSubmodelElementType() { + try { + operationOperation.invokeSimple("10"); + fail(); + } catch (Exception e) { + // Exceptions from ConnectedOperation are wrapped in ProviderException + assertTrue(e instanceof MalformedRequestException || e.getCause() instanceof MalformedRequestException); + } + } + + @Test + public void testInvokeSimpleOperationWithInvalidSubmodelElementType() { + RelationshipElement input = createRelationshipElementAsInput(RELATIONSHIP_ID_SHORT); + + try { + simpleOperation.invoke(input, input); + fail(); + } catch (Exception e) { + // Exceptions from ConnectedOperation are wrapped in ProviderException + assertTrue(e instanceof MalformedRequestException || e.getCause() instanceof MalformedRequestException); + } + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationParameter.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationParameter.java new file mode 100644 index 00000000..6db1e330 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationParameter.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; + +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; + +/** + * Tests constructor, getter and setter of {@link Operation} for their + * correctness + * + * @author espen, fischer + * + */ +public class TestOperationParameter extends TestOperationParameterSuite { + + @Override + protected IOperation prepareOperation(Operation operation) { + return operation; + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationParameterSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationParameterSuite.java new file mode 100644 index 00000000..bf2aeacf --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationParameterSuite.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; +import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation; +import org.eclipse.basyx.submodel.metamodel.map.reference.Key; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElement; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for different parameters in operations with submodelElements. + * + * @author espen, fischer + * + */ +public abstract class TestOperationParameterSuite { + protected static final String RELATIONSHIP_ID_SHORT = "relationshipIdShort"; + protected static final String RELATIONSHIP_FIRST_REFERENCE_ID_SHORT = "firstId"; + protected static final String RELATIONSHIP_SECOND_REFERENCE_ID_SHORT = "secondId"; + protected static final String OPERATION_ID_SHORT = "operationIdShort"; + protected static final String OPERATION_PROPERTY_ID_SHORT = "propertyId"; + + protected static final Function, SubmodelElement[]> RELATIONSHIP_FUNC = (Function, SubmodelElement[]>) inputMap -> { + return new SubmodelElement[] { inputMap.get(RELATIONSHIP_ID_SHORT) }; + }; + + protected static final Function, SubmodelElement[]> OPERATION_FUNC = (Function, SubmodelElement[]>) inputMap -> { + return new SubmodelElement[] { inputMap.get(OPERATION_ID_SHORT) }; + }; + + protected IOperation relationshipOperation; + protected IOperation operationOperation; + + /** + * Converts an Operation into the IOperation to be tested + */ + protected abstract IOperation prepareOperation(Operation operation); + + @Before + public void setup() { + relationshipOperation = createRelationshipOperation(); + operationOperation = createOperationOperation(); + } + + protected IOperation createOperationOperation() { + Operation op = new Operation("operation"); + op.setInputVariables(createOperationOperationVariable()); + op.setOutputVariables(createOperationOperationVariable()); + op.setWrappedInvokable(OPERATION_FUNC); + + return prepareOperation(op); + } + + protected IOperation createRelationshipOperation() { + Operation op = new Operation("relationship"); + op.setInputVariables(createRelationshipOperationVariable()); + op.setOutputVariables(createRelationshipOperationVariable()); + op.setWrappedInvokable(RELATIONSHIP_FUNC); + + return prepareOperation(op); + } + + private Collection createRelationshipOperationVariable() { + RelationshipElement relationshipElementAsOperationVariable = createRelationshipElementForOperationInputVariables(); + + OperationVariable relationshipElementVariable = new OperationVariable(relationshipElementAsOperationVariable); + + return Arrays.asList(relationshipElementVariable); + } + + private RelationshipElement createRelationshipElementForOperationInputVariables() { + Reference firstReference = new Reference(new Key(KeyElements.RELATIONSHIPELEMENT, false, "", KeyType.IDSHORT)); + Reference secondReference = new Reference(new Key(KeyElements.RELATIONSHIPELEMENT, false, "", KeyType.IDSHORT)); + RelationshipElement relationshipElementAsOperationVariable = new RelationshipElement(RELATIONSHIP_ID_SHORT, firstReference, secondReference); + + relationshipElementAsOperationVariable.setKind(ModelingKind.TEMPLATE); + + return relationshipElementAsOperationVariable; + } + + private Collection createOperationOperationVariable() { + Operation operation = createOperationForOperationInputVariables(); + + OperationVariable operationVariable = new OperationVariable(operation); + + return Arrays.asList(operationVariable); + } + + private Operation createOperationForOperationInputVariables() { + Property p1 = new Property(OPERATION_PROPERTY_ID_SHORT, ""); + OperationVariable opV = new OperationVariable(p1); + + Operation operation = new Operation("inputOperation"); + operation.setInputVariables(Arrays.asList(opV)); + operation.setIdShort(OPERATION_ID_SHORT); + operation.setKind(ModelingKind.TEMPLATE); + + return operation; + } + + @Test + public void testInvokeSubmodelElementWithValues() { + RelationshipElement input = createRelationshipElementAsInput(); + SubmodelElement[] responseArray = relationshipOperation.invoke(input); + RelationshipElement responseRelationship = (RelationshipElement) responseArray[0]; + checkRelationshipElementOutput(responseRelationship); + } + + private RelationshipElement createRelationshipElementAsInput() { + Reference firstReference = new Reference(new Key(KeyElements.RELATIONSHIPELEMENT, false, RELATIONSHIP_FIRST_REFERENCE_ID_SHORT, KeyType.IDSHORT)); + Reference secondReference = new Reference(new Key(KeyElements.RELATIONSHIPELEMENT, false, RELATIONSHIP_SECOND_REFERENCE_ID_SHORT, KeyType.IDSHORT)); + RelationshipElement relationshipElement = new RelationshipElement(RELATIONSHIP_ID_SHORT, firstReference, secondReference); + + return relationshipElement; + } + + private void checkRelationshipElementOutput(RelationshipElement responseRelationship) { + List firstReferenceKeys = responseRelationship.getFirst().getKeys(); + List secondReferenceKeys = responseRelationship.getSecond().getKeys(); + + IKey lastKeyFirstReference = firstReferenceKeys.get(firstReferenceKeys.size() - 1); + IKey lastKeySecondReference = secondReferenceKeys.get(firstReferenceKeys.size() - 1); + + assertEquals(RELATIONSHIP_ID_SHORT, responseRelationship.getIdShort()); + assertEquals(RELATIONSHIP_FIRST_REFERENCE_ID_SHORT, lastKeyFirstReference.getValue()); + assertEquals(RELATIONSHIP_SECOND_REFERENCE_ID_SHORT, lastKeySecondReference.getValue()); + } + + @Test + public void testInvokeSubmodelElementWithoutValues() { + Operation input = createOperationAsInput(); + SubmodelElement[] responseArray = operationOperation.invoke(input); + Operation responseOperation = (Operation) responseArray[0]; + checkOperationOutput(responseOperation); + } + + private Operation createOperationAsInput() { + Operation operation = new Operation("inputOperation"); + operation.setIdShort(OPERATION_ID_SHORT); + + return operation; + } + + private void checkOperationOutput(Operation responseOperation) { + assertEquals(OPERATION_ID_SHORT, responseOperation.getIdShort()); + assertTrue(responseOperation.getInputVariables().isEmpty()); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java index 6eeb59dc..22830f88 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationSuite.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors + * + * 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: * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; @@ -15,8 +30,12 @@ import static org.junit.Assert.fail; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Map; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IAsyncInvocation; @@ -34,100 +53,318 @@ /** * Tests for IOperation - * - * @author conradi + * + * @author conradi, fischer * */ public abstract class TestOperationSuite { - protected static final String IN_VALUE = "inValue"; + protected static final String IN_IDSHORT1 = "testIn1"; + protected static final String IN_IDSHORT2 = "testIn2"; protected static final String OUT_VALUE = "outValue"; + protected static final String OUT_IDSHORT = "testOut"; protected static final String INOUT_VALUE = "inOutValue"; - protected static Collection IN; + protected static final String INOUT_IDSHORT = "testInOut"; + protected static final String SUPPLIER_RETURN_VALUE = "10"; + protected static final boolean RUNNABLE_FLAG = true; + + protected static Collection ONE_IN; + protected static Collection TWO_IN; protected static Collection OUT; protected static Collection INOUT; - - protected static final Function FUNC = (Function) v -> { - return (int)v[0] + (int)v[1]; + protected static int expectedResultForSimpleConsumerTest; + protected static int expectedResultForSimpleConsumerWithPropertiesTest; + protected static int expectedResultForPropertyConsumerTest; + protected static int expectedResultForPropertyConsumerWithPropertiesTest; + + protected static boolean expectedResultForSimpleRunnableTest; + protected static boolean expectedResultForSimpleRunnableWithPropertiesTest; + protected static SubmodelElement[] expectedResultForPropertyRunnableTest; + + protected static final Function, SubmodelElement[]> PROPERTY_FUNC = (Function, SubmodelElement[]>) inputMap -> { + Property p1 = (Property) inputMap.get(IN_IDSHORT1); + Property p2 = (Property) inputMap.get(IN_IDSHORT2); + int value1 = (int) p1.getValue(); + int value2 = (int) p2.getValue(); + + int resultValue = value2 - value1; + return new SubmodelElement[] { new Property(OUT_IDSHORT, resultValue) }; }; - + + protected static final Function SIMPLE_FUNC = (Function) v -> { + return (int) v[0] + (int) v[1]; + }; + protected static final Function EXCEPTION_FUNC = (Function) v -> { throw new NullPointerException(); }; - - protected IOperation operation; - protected IOperation operationException; + + protected static final Function, SubmodelElement[]> PROPERTY_EXCEPTION_FUNC = (Function, SubmodelElement[]>) inputMap -> { + throw new NullPointerException(); + }; + + protected static final Supplier SIMPLE_SUPPLIER_FUNC = (Supplier) () -> SUPPLIER_RETURN_VALUE; + + protected static final Supplier PROPERTY_SUPPLIER_FUNC = (Supplier) () -> { + return new SubmodelElement[] { new Property(OUT_IDSHORT, SUPPLIER_RETURN_VALUE) }; + }; + + protected static final Consumer SIMPLE_CONSUMER_FUNC = (Consumer) (simpleInput) -> { + expectedResultForSimpleConsumerTest = (Integer) simpleInput[0]; + }; + + protected static final Consumer SIMPLE_CONSUMER_WITH_PROPERTIES_FUNC = (Consumer) (simpleInput) -> { + expectedResultForSimpleConsumerWithPropertiesTest = (Integer) simpleInput[0]; + }; + + protected static final Consumer> PROPERTY_CONSUMER_FUNC = (Consumer>) inputMap -> { + expectedResultForPropertyConsumerTest = (Integer) inputMap.get(IN_IDSHORT1).getValue(); + }; + + protected static final Consumer> PROPERTY_CONSUMER_WITH_PROPERTIES_FUNC = (Consumer>) inputMap -> { + expectedResultForPropertyConsumerWithPropertiesTest = (Integer) inputMap.get(IN_IDSHORT1).getValue(); + }; + + protected static final Runnable SIMPLE_RUNNABLE_FUNC = () -> { + expectedResultForSimpleRunnableTest = RUNNABLE_FLAG; + }; + + protected static final Runnable SIMPLE_RUNNABLE_WITH_PROPERTIES_FUNC = () -> { + expectedResultForSimpleRunnableWithPropertiesTest = RUNNABLE_FLAG; + }; + + protected IOperation simpleOperation; + protected IOperation propertyOperation; + protected IOperation simpleOperationException; + protected IOperation propertyOperationException; + protected IOperation simpleSupplierOperation; + protected IOperation propertySupplierOperation; + protected IOperation simpleConsumerOperation; + protected IOperation simpleConsumerOperationWithProperties; + protected IOperation propertyConsumerOperation; + protected IOperation propertyConsumerOperationWithProperties; + protected IOperation simpleRunnableOperation; + protected IOperation simpleRunnableOperationWithProperties; /** * Converts an Operation into the IOperation to be tested */ protected abstract IOperation prepareOperation(Operation operation); - + @Before public void setup() { - IN = new ArrayList(); - OUT = new ArrayList(); - INOUT = new ArrayList(); - Property inProp1 = new Property("testIn1", IN_VALUE); - inProp1.setModelingKind(ModelingKind.TEMPLATE); - Property inProp2 = new Property("testIn2", IN_VALUE); - inProp2.setModelingKind(ModelingKind.TEMPLATE); - Property outProp = new Property("testId2", OUT_VALUE); - outProp.setModelingKind(ModelingKind.TEMPLATE); - Property inOutProp = new Property("testId3", INOUT_VALUE); - inOutProp.setModelingKind(ModelingKind.TEMPLATE); - IN.add(new OperationVariable(inProp1)); - IN.add(new OperationVariable(inProp2)); - OUT.add(new OperationVariable(outProp)); - INOUT.add(new OperationVariable(inOutProp)); - - Operation op1 = new Operation(IN, OUT, INOUT, FUNC); - op1.setIdShort("op1"); - operation = prepareOperation(op1); - - Operation op2 = new Operation(IN, OUT, INOUT, EXCEPTION_FUNC); - op2.setIdShort("op2"); - operationException = prepareOperation(op2); - } - - @Test - public void testInvoke() throws Exception { - assertEquals(5, operation.invoke(2, 3)); - } - - @Test - public void testInvokeException() throws Exception { + ONE_IN = createOneInputVariables(); + TWO_IN = createTwoInputVariables(); + OUT = createOutputVariables(); + INOUT = createInOutVariables(); + + propertyOperation = createPropertyOperation(); + propertyOperationException = createPropertyExceptionOperation(); + simpleOperation = createAddOperation(); + simpleOperationException = createSimpleExceptionOperation(); + simpleSupplierOperation = createSimpleSupplierOperation(); + propertySupplierOperation = createPropertySupplierOperation(); + simpleConsumerOperation = createSimpleConsumerOperation(); + simpleConsumerOperationWithProperties = createSimpleConsumerOperationWithProperties(); + propertyConsumerOperation = createPropertyConsumerOperation(); + propertyConsumerOperationWithProperties = createPropertyConsumerOperationWithProperties(); + simpleRunnableOperation = createSimpleRunnableOperation(); + simpleRunnableOperationWithProperties = createSimpleRunnableOperationWithProperties(); + } + + private IOperation createPropertyOperation() { + Operation op = new Operation(TWO_IN, OUT, INOUT); + op.setWrappedInvokable(PROPERTY_FUNC); + op.setIdShort("PropertyOperation"); + return prepareOperation(op); + } + + private IOperation createPropertyExceptionOperation() { + Operation op = new Operation(TWO_IN, OUT, INOUT); + op.setWrappedInvokable(PROPERTY_EXCEPTION_FUNC); + op.setIdShort("PropertyExceptionOperation"); + return prepareOperation(op); + } + + private IOperation createAddOperation() { + Operation op = new Operation(TWO_IN, OUT, INOUT, SIMPLE_FUNC); + op.setIdShort("SimpleOperation"); + return prepareOperation(op); + } + + private IOperation createSimpleExceptionOperation() { + Operation op = new Operation(TWO_IN, OUT, INOUT, EXCEPTION_FUNC); + op.setIdShort("SimpleExceptionOperation"); + return prepareOperation(op); + } + + private IOperation createSimpleSupplierOperation() { + Operation op = new Operation("SimpleSupplier"); + op.setOutputVariables(OUT); + op.setInvokable(SIMPLE_SUPPLIER_FUNC); + + return prepareOperation(op); + } + + private IOperation createPropertySupplierOperation() { + Operation op = new Operation("PropertySupplier"); + op.setOutputVariables(OUT); + op.setWrappedInvokable(PROPERTY_SUPPLIER_FUNC); + + return prepareOperation(op); + } + + private IOperation createSimpleConsumerOperation() { + Operation op = new Operation("consumer"); + op.setInputVariables(ONE_IN); + op.setInvokable(SIMPLE_CONSUMER_FUNC); + + return prepareOperation(op); + } + + private IOperation createSimpleConsumerOperationWithProperties() { + Operation op = new Operation("SimpleConsumerWithProperties"); + op.setInputVariables(ONE_IN); + op.setInvokable(SIMPLE_CONSUMER_WITH_PROPERTIES_FUNC); + + return prepareOperation(op); + } + + private IOperation createPropertyConsumerOperation() { + Operation op = new Operation("PropertyConsumer"); + op.setInputVariables(ONE_IN); + op.setWrappedInvokable(PROPERTY_CONSUMER_FUNC); + + return prepareOperation(op); + } + + private IOperation createPropertyConsumerOperationWithProperties() { + Operation op = new Operation("PropertyConsumerWithProperties"); + op.setInputVariables(ONE_IN); + op.setWrappedInvokable(PROPERTY_CONSUMER_WITH_PROPERTIES_FUNC); + + return prepareOperation(op); + } + + private IOperation createSimpleRunnableOperation() { + Operation op = new Operation("SimpleRunnable"); + op.setInvokable(SIMPLE_RUNNABLE_FUNC); + + return prepareOperation(op); + } + + private IOperation createSimpleRunnableOperationWithProperties() { + Operation op = new Operation("SimpleRunnableWithProperties"); + op.setInvokable(SIMPLE_RUNNABLE_WITH_PROPERTIES_FUNC); + + return prepareOperation(op); + } + + private Collection createInOutVariables() { + Property inOutProp = new Property(INOUT_IDSHORT, INOUT_VALUE); + inOutProp.setKind(ModelingKind.TEMPLATE); + return Arrays.asList(new OperationVariable(inOutProp)); + } + + private Collection createOutputVariables() { + Property outProp = new Property(OUT_IDSHORT, OUT_VALUE); + outProp.setKind(ModelingKind.TEMPLATE); + return Arrays.asList(new OperationVariable(outProp)); + } + + private Collection createOneInputVariables() { + Property inProp1 = new Property(IN_IDSHORT1, IN_VALUE); + inProp1.setKind(ModelingKind.TEMPLATE); + + return Arrays.asList(new OperationVariable(inProp1)); + } + + private Collection createTwoInputVariables() { + Property inProp1 = new Property(IN_IDSHORT1, IN_VALUE); + inProp1.setKind(ModelingKind.TEMPLATE); + + Property inProp2 = new Property(IN_IDSHORT2, IN_VALUE); + inProp2.setKind(ModelingKind.TEMPLATE); + + return Arrays.asList(new OperationVariable(inProp1), new OperationVariable(inProp2)); + } + + @Test + public void testInvokeSimpleOperation() throws Exception { + assertEquals(5, simpleOperation.invokeSimple(2, 3)); + } + + @Test + public void testInvokeSimpleOperationWithProperties() throws Exception { + Property p1 = new Property(IN_IDSHORT1, 2); + Property p2 = new Property(IN_IDSHORT2, 3); + SubmodelElement[] directResult = simpleOperation.invoke(p1, p2); + Property propertyResult = (Property) directResult[0]; + + assertEquals(OUT_IDSHORT, propertyResult.getIdShort()); + assertEquals(5, propertyResult.getValue()); + } + + @Test + public void testInvokePropertyOperation() throws Exception { + assertEquals(1, propertyOperation.invokeSimple(2, 3)); + } + + @Test + public void testInvokePropertyOperationWithProperties() { + Property p1 = new Property(IN_IDSHORT1, 2); + Property p2 = new Property(IN_IDSHORT2, 3); + SubmodelElement[] directResult = propertyOperation.invoke(p1, p2); + Property propertyResult = (Property) directResult[0]; + + assertEquals(OUT_IDSHORT, propertyResult.getIdShort()); + assertEquals(1, propertyResult.getValue()); + } + + @Test + public void testInvokeSimpleOperationException() { try { - // Ensure the operation is invoked directly - operationException.invoke(1, 2); + simpleOperationException.invokeSimple(1, 2); fail(); } catch (Exception e) { // Exceptions from ConnectedOperation are wrapped in ProviderException - assertTrue(e instanceof NullPointerException - || e.getCause() instanceof NullPointerException); + assertTrue(e instanceof NullPointerException || e.getCause() instanceof NullPointerException); } } - + @Test - public void testInvokeWithSubmodelElements() { - Property param1 = new Property("testIn1", 2); - param1.setModelingKind(ModelingKind.TEMPLATE); - Property param2 = new Property("testIn2", 4); - param2.setModelingKind(ModelingKind.TEMPLATE); - SubmodelElement[] result = operation.invoke(param1, param2); - assertEquals(1, result.length); - assertEquals(6, result[0].getValue()); + public void testInvokeSimpleOperationExceptionWithProperties() { + try { + Property param1 = new Property(IN_IDSHORT1, 1); + Property param2 = new Property(IN_IDSHORT2, 1); + + simpleOperationException.invoke(param1, param2); + fail(); + } catch (Exception e) { + assertTrue(e instanceof NullPointerException || e.getCause() instanceof NullPointerException); + } } @Test - public void testInvokeParametersException() throws Exception { + public void testInvokePropertyOperationExceptionWithProperties() { try { - operation.invoke(1); + Property p1 = new Property(IN_IDSHORT1, 2); + Property p2 = new Property(IN_IDSHORT2, 3); + propertyOperationException.invoke(p1, p2); fail(); } catch (Exception e) { // Exceptions from ConnectedOperation are wrapped in ProviderException - assertTrue(e instanceof WrongNumberOfParametersException - || e.getCause() instanceof WrongNumberOfParametersException); + assertTrue(e instanceof NullPointerException || e.getCause() instanceof NullPointerException); + } + } + + @Test + public void testInvokeSimpleOperationParameterException() { + try { + simpleOperation.invokeSimple(1); + fail(); + } catch (Exception e) { + assertTrue(e instanceof WrongNumberOfParametersException || e.getCause() instanceof WrongNumberOfParametersException); } } @@ -137,15 +374,15 @@ public void testInvokeAsync() throws Exception { IOperation operation = prepareOperation(helper.getAsyncOperation()); IAsyncInvocation invocation = operation.invokeAsync(3, 2); - + assertFalse(invocation.isFinished()); - + helper.releaseWaitingOperation(); assertTrue(invocation.isFinished()); assertEquals(5, invocation.getResult()); } - + @Test public void testInvokeMultipleAsync() throws Exception { AsyncOperationHelper helper = new AsyncOperationHelper(); @@ -165,12 +402,11 @@ public void testInvokeMultipleAsync() throws Exception { assertEquals(8, invocation2.getResult()); } - @Test + @Test(expected = OperationExecutionTimeoutException.class) public void testInvokeAsyncTimeout() throws Exception { AsyncOperationHelper helper = new AsyncOperationHelper(); IOperation operation = prepareOperation(helper.getAsyncOperation()); - // timeout of 1ms IAsyncInvocation invocation = operation.invokeAsyncWithTimeout(1, 3, 2); // Should be more than enough to trigger the timeout exception @@ -178,33 +414,104 @@ public void testInvokeAsyncTimeout() throws Exception { helper.releaseWaitingOperation(); assertTrue(invocation.isFinished()); - try { - invocation.getResult(); - fail(); - } catch (OperationExecutionTimeoutException e) { - } + invocation.getResult(); } - @Test - public void testInvokeExceptionAsync() throws Exception { + @Test(expected = OperationExecutionErrorException.class) + public void testInvokeAsyncException() throws Exception { AsyncOperationHelper helper = new AsyncOperationHelper(); IOperation operationException = prepareOperation(helper.getAsyncExceptionOperation()); IAsyncInvocation invocation = operationException.invokeAsync(); assertFalse(invocation.isFinished()); - + helper.releaseWaitingOperation(); - - try { - invocation.getResult(); - fail(); - } catch (OperationExecutionErrorException e) { - } + invocation.getResult(); + } + + @Test + public void testInvokeSimpleSupplier() { + assertEquals(SUPPLIER_RETURN_VALUE, simpleSupplierOperation.invokeSimple()); + } + + @Test + public void testInvokeSimpleSupplierWithProperties() { + Property propertyResult = (Property) simpleSupplierOperation.invoke()[0]; + + assertEquals(OUT_IDSHORT, propertyResult.getIdShort()); + assertEquals(SUPPLIER_RETURN_VALUE, propertyResult.getValue()); + } + + @Test + public void testInvokePropertySupplier() { + String operationResult = (String) propertySupplierOperation.invokeSimple(); + + assertEquals(SUPPLIER_RETURN_VALUE, operationResult); + } + + @Test + public void testInvokePropertySupplierWithProperties() { + Property propertyResult = (Property) propertySupplierOperation.invoke()[0]; + + assertEquals(OUT_IDSHORT, propertyResult.getIdShort()); + assertEquals(SUPPLIER_RETURN_VALUE, propertyResult.getValue()); + } + + @Test + public void testInvokeSimpleConsumer() { + int expected = 5; + + simpleConsumerOperation.invokeSimple(expected); + + assertEquals(expected, expectedResultForSimpleConsumerTest); + } + + @Test + public void testInvokeSimpleConsumerWithProperties() { + int expected = 15; + Property p1 = new Property(IN_IDSHORT1, expected); + + simpleConsumerOperationWithProperties.invoke(p1); + + assertEquals(expected, expectedResultForSimpleConsumerWithPropertiesTest); + } + + @Test + public void testInvokePropertyConsumer() { + int expected = 23; + + propertyConsumerOperation.invokeSimple(expected); + + assertEquals(expected, expectedResultForPropertyConsumerTest); } - + + @Test + public void testInvokePropertyConsumerWithProperties() { + int expected = 2; + Property p1 = new Property(IN_IDSHORT1, expected); + + propertyConsumerOperationWithProperties.invoke(p1); + + assertEquals(expected, expectedResultForPropertyConsumerWithPropertiesTest); + } + + @Test + public void testInvokeSimpleRunnable() { + simpleRunnableOperation.invokeSimple(); + + assertEquals(RUNNABLE_FLAG, expectedResultForSimpleRunnableTest); + } + + @Test + public void testInvokeSimpleRunnableWithProperties() { + simpleRunnableOperationWithProperties.invoke(); + + assertEquals(RUNNABLE_FLAG, expectedResultForSimpleRunnableWithPropertiesTest); + } + @Test public void testInputVariables() { - Collection inputVariables = operation.getInputVariables(); + Collection inputVariables = simpleOperation.getInputVariables(); assertEquals(2, inputVariables.size()); Object value = getValueFromOpVariable(inputVariables); assertEquals(IN_VALUE, value); @@ -212,26 +519,24 @@ public void testInputVariables() { @Test public void testOutputVariables() { - Collection outputVariables = operation.getOutputVariables(); - assertEquals(1, outputVariables.size()); + Collection outputVariables = simpleOperation.getOutputVariables(); + Object value = getValueFromOpVariable(outputVariables); assertEquals(OUT_VALUE, value); + assertEquals(1, outputVariables.size()); } @Test public void testInOutputVariables() { - Collection inoutVariables = operation.getInOutputVariables(); + Collection inoutVariables = simpleOperation.getInOutputVariables(); assertEquals(1, inoutVariables.size()); Object value = getValueFromOpVariable(inoutVariables); assertEquals(INOUT_VALUE, value); } - - /** - * Gets the Value from the OperationVariable in a collection - */ + private Object getValueFromOpVariable(Collection vars) { IOperationVariable var = new ArrayList<>(vars).get(0); return var.getValue().getValue(); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java index 60f9ed79..af76d9da 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/operation/TestOperationVariable.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.operation; @@ -27,33 +42,35 @@ */ public class TestOperationVariable { private static final Property PROPERTY = new Property("testIdShort", "testOpVariable"); - + private OperationVariable operationVariable; + @Before public void buildOperationVariable() { - PROPERTY.setModelingKind(ModelingKind.TEMPLATE); + PROPERTY.setKind(ModelingKind.TEMPLATE); operationVariable = new OperationVariable(PROPERTY); - } - + } + @Test public void testConstructor() { assertEquals(PROPERTY, operationVariable.getValue()); - } - + } + @Test public void testSetValue() { Property property = new Property("testIdShort", ValueType.String); - property.setModelingKind(ModelingKind.TEMPLATE); + property.setKind(ModelingKind.TEMPLATE); operationVariable.setValue(property); assertEquals(property, operationVariable.getValue()); } - + @Test - // TODO: Change with 1.0 Release when ModelingKind.Template is obligatory for OperationVariables + // TODO: Change with 1.0 Release when ModelingKind.Template is obligatory for + // OperationVariables public void testSetValueChangedModelingKind() { Property property = new Property("testIdShort", ValueType.String); - property.setModelingKind(ModelingKind.INSTANCE); + property.setKind(ModelingKind.INSTANCE); operationVariable.setValue(property); - assertEquals(ModelingKind.TEMPLATE, operationVariable.getValue().getModelingKind()); + assertEquals(ModelingKind.TEMPLATE, operationVariable.getValue().getKind()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java index 79bf0a2b..9174e8c9 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestAnnotatedRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.relationship; @@ -28,7 +43,8 @@ import org.junit.Test; /** - * Tests constructor, getter and setter of {@link AnnotatedRelationshipElement} for correctness + * Tests constructor, getter and setter of {@link AnnotatedRelationshipElement} + * for correctness * * @author conradi * @@ -36,9 +52,9 @@ public class TestAnnotatedRelationshipElement { private static final Reference FIRST = new Reference(new Key(KeyElements.ASSET, true, "firstValue", IdentifierType.IRI)); private static final Reference SECOND = new Reference(new Identifier(IdentifierType.CUSTOM, "secondId"), KeyElements.BLOB, false); - + private AnnotatedRelationshipElement element; - + @Before public void buildElement() { element = new AnnotatedRelationshipElement("testId", FIRST, SECOND); @@ -46,20 +62,20 @@ public void buildElement() { List annotations = new ArrayList<>(); annotations.add(property); element.setAnnotation(annotations); - } - + } + @Test public void testConstructor() { assertEquals(FIRST, element.getFirst()); assertEquals(SECOND, element.getSecond()); - } - + } + @Test public void testSetFirst() { Reference newFirst = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI)); element.setFirst(newFirst); assertEquals(newFirst, element.getFirst()); - } + } @Test public void testSetSecond() { @@ -67,21 +83,21 @@ public void testSetSecond() { element.setSecond(newSecond); assertEquals(newSecond, element.getSecond()); } - + @Test public void testGetValue() { RelationshipElementValue value = element.getValue(); assertEquals(FIRST.getKeys().get(0).getValue(), value.getFirst().getKeys().get(0).getValue()); assertEquals(SECOND.getKeys().get(0).getValue(), value.getSecond().getKeys().get(0).getValue()); } - + @Test public void testGetAnnotations() { Collection annotations = element.getValue().getAnnotations(); assertEquals(1, annotations.size()); - + // Check the element - for (IDataElement element: annotations) { + for (IDataElement element : annotations) { assertEquals("PropertyId", element.getIdShort()); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java index 30cbcdf5..0e4aae06 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/submodelelement/relationship/TestRelationshipElement.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.submodelelement.relationship; @@ -31,26 +46,26 @@ public class TestRelationshipElement { private static final Reference FIRST = new Reference(new Key(KeyElements.ASSET, true, "firstValue", IdentifierType.IRI)); private static final Reference SECOND = new Reference(new Identifier(IdentifierType.CUSTOM, "secondId"), KeyElements.BLOB, false); - + private RelationshipElement relationshipElement; - + @Before public void buildRelationshipElement() { relationshipElement = new RelationshipElement(FIRST, SECOND); - } - + } + @Test public void testConstructor() { assertEquals(FIRST, relationshipElement.getFirst()); assertEquals(SECOND, relationshipElement.getSecond()); - } - + } + @Test public void testSetFirst() { Reference newFirst = new Reference(new Key(KeyElements.CAPABILITY, false, "newFirst", IdentifierType.IRI)); relationshipElement.setFirst(newFirst); assertEquals(newFirst, relationshipElement.getFirst()); - } + } @Test public void testSetSecond() { @@ -58,12 +73,12 @@ public void testSetSecond() { relationshipElement.setSecond(newSecond); assertEquals(newSecond, relationshipElement.getSecond()); } - + @Test public void testGetValue() { RelationshipElementValue value = relationshipElement.getValue(); assertEquals(FIRST.getKeys().get(0).getValue(), value.getFirst().getKeys().get(0).getValue()); assertEquals(SECOND.getKeys().get(0).getValue(), value.getSecond().getKeys().get(0).getValue()); } - + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java index 3f02b71e..c900c522 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/metamodel/map/support/TestAASLambdaPropertyHelper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.metamodel.map.support; @@ -38,7 +53,7 @@ public void testSettingLambdaValue() throws Exception { AASLambdaPropertyHelper.setLambdaValue(temperature, () -> testValue, v -> { testValue = (double) v; }); - + // Wrap in provider SubmodelElementProvider provider = new SubmodelElementProvider(new VABLambdaProvider(temperature)); ConnectedProperty connectedProperty = new ConnectedProperty(new VABElementProxy("", provider)); @@ -46,11 +61,11 @@ public void testSettingLambdaValue() throws Exception { // Check correct property type ValueType expectedType = ValueType.Double; assertEquals(expectedType, connectedProperty.getValueType()); - + // Check value is correctly retrievable by property testValue = 10; assertEquals(testValue, connectedProperty.getValue()); - + // Check value is correctly written by property double expectedValue = 2.1; connectedProperty.setValue(expectedValue); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/OperationProviderTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/OperationProviderTest.java new file mode 100644 index 00000000..7fd81d91 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/OperationProviderTest.java @@ -0,0 +1,307 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.submodel.restapi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; +import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperationVariable; +import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.OperationVariable; +import org.eclipse.basyx.submodel.restapi.OperationProvider; +import org.eclipse.basyx.submodel.restapi.operation.CallbackResponse; +import org.eclipse.basyx.submodel.restapi.operation.DelegatedInvocationManager; +import org.eclipse.basyx.submodel.restapi.operation.InvocationRequest; +import org.eclipse.basyx.submodel.restapi.operation.InvocationResponse; +import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; +import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; +import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider; +import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext; +import org.eclipse.basyx.vab.protocol.http.server.BaSyxHTTPServer; +import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Tests for the OperationProvider + * + * @author conradi + * + */ +public class OperationProviderTest { + private static final String SERVER = "localhost"; + private static final int PORT = 4000; + private static final String CONTEXT_PATH = "operation"; + + private static final String OPID_IN = "opIn"; + private static final String OPID_OUT = "opOut"; + + private static final String API_INVOKE_URL = "http://" + SERVER + ":" + PORT + "/" + CONTEXT_PATH + "/" + OPID_OUT + "/invoke"; + + private static Integer requestId = 0; + + private static final Function NULL_RETURN_FUNC = (Function) v -> { + // Do nothing, just return + // This is a function with return type "void" + return null; + }; + + private static final Function SUB_RETURN_FUNC = (Function) v -> { + return (Integer) v[0] - (Integer) v[1]; + }; + + private static OperationProvider opProviderIn; + private static OperationProvider opProviderOut; + + @BeforeClass + public static void setup() { + + Collection in = getInVariables(); + Collection out = getOutVariables(); + + Operation inOperation = createOperation(OPID_IN, in, new ArrayList<>(), NULL_RETURN_FUNC); + opProviderIn = new OperationProvider(new VABLambdaProvider(inOperation)); + + Operation outOperation = createOperation(OPID_OUT, in, out, SUB_RETURN_FUNC); + opProviderOut = new OperationProvider(new VABLambdaProvider(outOperation)); + + } + + private static Operation createOperation(String id, Collection in, Collection out, Function func) { + Operation operation = new Operation(id); + operation.setInputVariables(in); + operation.setOutputVariables(out); + operation.setInvokable(func); + return operation; + } + + private static Collection getInVariables() { + Collection in = new ArrayList<>(); + + Property inProp1 = new Property("testIn1", 0); + inProp1.setKind(ModelingKind.TEMPLATE); + Property inProp2 = new Property("testIn2", 0); + inProp1.setKind(ModelingKind.TEMPLATE); + + in.add(new OperationVariable(inProp1)); + in.add(new OperationVariable(inProp2)); + + return in; + } + + private static Collection getOutVariables() { + Collection out = new ArrayList<>(); + + Property outProp = new Property("testOut", 0); + outProp.setKind(ModelingKind.TEMPLATE); + + out.add(new OperationVariable(outProp)); + + return out; + } + + /** + * Tests an Operation call with non wrapped parameters Operation has no return + * value + */ + @Test + public void testNonWrappedInputWithoutOutput() { + opProviderIn.invokeOperation("invoke", 1, 2); + } + + /** + * Tests an Operation call with an InvocationRequest Operation has no return + * value + */ + @Test + public void testInvocationRequestInputWithoutOutput() { + Property inProp1 = new Property("testIn1", 10); + Property inProp2 = new Property("testIn2", 6); + InvocationRequest request = getInvocationRequest(inProp1, inProp2); + invokeSync(opProviderIn, request); + } + + /** + * Tests an Operation call with non wrapped parameters Operation returns the + * given parameter + */ + @Test + public void testNonWrappedInputWithOutput() { + assertEquals(4, opProviderOut.invokeOperation("invoke", 10, 6)); + } + + /** + * Tests an Operation call with an InvocationRequest Operation returns the given + * parameter + */ + @Test + public void testInvocationRequestInputWithOutput() throws Exception { + + Property inProp1 = new Property("testIn1", 10); + Property inProp2 = new Property("testIn2", 6); + InvocationRequest request = getInvocationRequest(inProp1, inProp2); + + Collection outResponseSync = invokeSync(opProviderOut, request); + Collection outResponseAsync = invokeAsync(opProviderOut, request); + assertEquals(1, outResponseSync.size()); + assertEquals(1, outResponseAsync.size()); + + Property propSync = (Property) outResponseSync.iterator().next().getValue(); + Property propAsync = (Property) outResponseAsync.iterator().next().getValue(); + + assertEquals(4, propSync.getValue()); + assertEquals(4, propAsync.getValue()); + } + + /** + * Swap the parameters in request to check if they are sorted by id + */ + @Test + public void testInvocationRequestWithSwappedParameters() throws Exception { + + Property inProp1 = new Property("testIn1", 10); + Property inProp2 = new Property("testIn2", 6); + InvocationRequest request = getInvocationRequest(inProp2, inProp1); + + Collection outResponseSync = invokeSync(opProviderOut, request); + Collection outResponseAsync = invokeAsync(opProviderOut, request); + assertEquals(1, outResponseSync.size()); + assertEquals(1, outResponseAsync.size()); + + Property propSync = (Property) outResponseSync.iterator().next().getValue(); + Property propAsync = (Property) outResponseAsync.iterator().next().getValue(); + + assertEquals(4, propSync.getValue()); + assertEquals(4, propAsync.getValue()); + } + + /** + * Tests to call an Operation expecting 2 parameters with only 1 + */ + @Test + public void testInvocationRequestWithTooFewParameters() throws Exception { + Property inProp1 = new Property("testIn1", 5); + + InvocationRequest request = getInvocationRequest(inProp1); + + try { + invokeSync(opProviderOut, request); + fail(); + } catch (MalformedRequestException e) { + } + + try { + invokeAsync(opProviderOut, request); + fail(); + } catch (MalformedRequestException e) { + } + } + + /** + * Tests to call Operation with right number of parameters but a wrong id + */ + @Test + public void testInvocationRequestWithWrongParamId() throws Exception { + Property inProp1 = new Property("testIn1", 10); + Property inProp2 = new Property("testIn3", 6); + + InvocationRequest request = getInvocationRequest(inProp1, inProp2); + + try { + invokeSync(opProviderOut, request); + fail(); + } catch (MalformedRequestException e) { + } + + try { + invokeAsync(opProviderOut, request); + fail(); + } catch (MalformedRequestException e) { + } + } + + @Test + public void testInvocationDelegation() { + // Start an http server with an operation + BaSyxContext context = new BaSyxContext("/" + CONTEXT_PATH, "", SERVER, PORT); + context.addServletMapping("/" + OPID_OUT + "/*", new VABHTTPInterface(opProviderOut)); + BaSyxHTTPServer server = new BaSyxHTTPServer(context); + server.start(); + + Operation delegatedOperation = createOperation("delegatedOperation", null, null, null); + + // Create a delegated qualifier and add to the operation + Qualifier qualifier = DelegatedInvocationManager.createDelegationQualifier(API_INVOKE_URL); + delegatedOperation.setQualifiers(Arrays.asList(qualifier)); + + OperationProvider delegatedOpProvider = new OperationProvider(new VABLambdaProvider(delegatedOperation)); + + assertEquals(4, delegatedOpProvider.invokeOperation("invoke", 10, 6)); + + server.shutdown(); + } + + @SuppressWarnings("unchecked") + private Collection invokeSync(OperationProvider provider, InvocationRequest request) { + InvocationResponse response = InvocationResponse.createAsFacade((Map) provider.invokeOperation("invoke", request)); + return response.getOutputArguments(); + } + + @SuppressWarnings("unchecked") + private Collection invokeAsync(OperationProvider provider, InvocationRequest request) throws Exception { + Object response = provider.invokeOperation("invoke?async=true", request); + assertTrue(response instanceof CallbackResponse); + Thread.sleep(10); + + InvocationResponse invokeResponse = InvocationResponse.createAsFacade((Map) provider.getValue("/invocationList/" + request.getRequestId())); + return invokeResponse.getOutputArguments(); + } + + /** + * Builds an InvocationRequest with given parameters + * + * @param in + * the parameters for the InvocationRequest + * @return the InvocationRequest + */ + private InvocationRequest getInvocationRequest(Property... in) { + Collection inout = new ArrayList<>(); + + Collection inVariables = Arrays.asList(in).stream().map(i -> new OperationVariable(i)).collect(Collectors.toList()); + + return new InvocationRequest((requestId++).toString(), inout, inVariables, 100); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java index c6c89492..d66e8e69 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SimpleAASSubmodel.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.restapi; @@ -35,11 +50,11 @@ public class SimpleAASSubmodel extends Submodel { public static final String INTPROPIDSHORT = "integerProperty"; public static final String OPERATIONSIMPLEIDSHORT = "simple"; - public static final List KEYWORDS = Collections.unmodifiableList(Arrays.asList( - Property.MODELTYPE, Property.VALUETYPE, Property.VALUE, Property.VALUEID, - Submodel.MODELTYPE, Submodel.SUBMODELELEMENT, - Operation.MODELTYPE, Operation.INVOKE, Operation.OUT, Operation.IN, Operation.INOUT, Operation.INVOKABLE, - SubmodelElementCollection.MODELTYPE, SubmodelElementCollection.ALLOWDUPLICATES, SubmodelElementCollection.ORDERED)); + + public static final String EXCEPTION_MESSAGE = "Exception description"; + + public static final List KEYWORDS = Collections.unmodifiableList(Arrays.asList(Property.MODELTYPE, Property.VALUETYPE, Property.VALUE, Property.VALUEID, Submodel.MODELTYPE, Submodel.SUBMODELELEMENT, Operation.MODELTYPE, + Operation.INVOKE, Operation.OUT, Operation.IN, Operation.INOUT, Operation.INVOKABLE, SubmodelElementCollection.MODELTYPE, SubmodelElementCollection.ALLOWDUPLICATES, SubmodelElementCollection.ORDERED)); public SimpleAASSubmodel() { this("SimpleAASSubmodel"); @@ -71,13 +86,12 @@ public SimpleAASSubmodel(String idShort) { return (int) v[0] - (int) v[1]; }); Property inProp1 = new Property("complexIn1", 0); - inProp1.setModelingKind(ModelingKind.TEMPLATE); + inProp1.setKind(ModelingKind.TEMPLATE); Property inProp2 = new Property("complexIn2", 0); - inProp2.setModelingKind(ModelingKind.TEMPLATE); + inProp2.setKind(ModelingKind.TEMPLATE); Property outProp = new Property("complexOut", 0); - outProp.setModelingKind(ModelingKind.TEMPLATE); - complex.setInputVariables(Arrays.asList(new OperationVariable(inProp1), - new OperationVariable(inProp2))); + outProp.setKind(ModelingKind.TEMPLATE); + complex.setInputVariables(Arrays.asList(new OperationVariable(inProp1), new OperationVariable(inProp2))); complex.setOutputVariables(Collections.singleton(new OperationVariable(outProp))); complex.setIdShort("complex"); addSubmodelElement(complex); @@ -98,7 +112,7 @@ public SimpleAASSubmodel(String idShort) { // - Contained operation that throws VAB exception Operation exception2 = new Operation((Function) elId -> { - throw new ProviderException("Exception description"); + throw new ProviderException(EXCEPTION_MESSAGE); }); exception2.setIdShort("exception2"); addSubmodelElement(exception2); @@ -107,7 +121,7 @@ public SimpleAASSubmodel(String idShort) { return 123; }); opInCollection.setIdShort("operationId"); - + SubmodelElementCollection containerProp = new SubmodelElementCollection(); containerProp.setIdShort("container"); containerProp.addSubmodelElement(intProp); @@ -121,6 +135,6 @@ public SimpleAASSubmodel(String idShort) { // Create various submodel elements with keywords in their idShorts SubmodelElementCollection containerKeywords = new SubmodelElementCollection(); containerKeywords.setIdShort("keywords"); - addSubmodelElement(containerKeywords); + addSubmodelElement(containerKeywords); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java index 2d2d07b3..185f4f7e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/SubmodelProviderTest.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.restapi; @@ -17,10 +32,9 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Iterator; import java.util.Map; -import java.util.function.Function; import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement; import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter; @@ -68,47 +82,48 @@ protected IModelProvider createProvider(String addr) { } /** - * Tests all basic submodel operations with idShorts composed of various keywords. + * Tests all basic submodel operations with idShorts composed of various + * keywords. * *

* The test counts as successful if it finished without any exceptions thrown. */ public void testPropertyIdShortsWithKeywords() { - final String base_path = SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/keywords/"; - VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - - for (String keyword : SimpleAASSubmodel.KEYWORDS) { - Property prop = new Property(); - prop.setIdShort(keyword + "Property"); - prop.setValueType(ValueType.String); - prop.setValue(null); - - String path = base_path + prop.getIdShort(); - submodelElement.setValue(path, prop); - submodelElement.getValue(path); - submodelElement.setValue(path + "/value", "Test"); - submodelElement.deleteValue(path); - } + final String base_path = SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/keywords/"; + VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); + + for (String keyword : SimpleAASSubmodel.KEYWORDS) { + Property prop = new Property(); + prop.setIdShort(keyword + "Property"); + prop.setValueType(ValueType.String); + prop.setValue(null); + + String path = base_path + prop.getIdShort(); + submodelElement.setValue(path, prop); + submodelElement.getValue(path); + submodelElement.setValue(path + "/value", "Test"); + submodelElement.deleteValue(path); + } } public void testOperationIdShortsWithKeywords() { final String base_path = SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/keywords/"; VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - for (String keyword : SimpleAASSubmodel.KEYWORDS) { - Operation op = new Operation(); - op.setIdShort(keyword + "Operation"); - op.setInvokable((Function) x -> { - return null; - }); - - Map param = wrapParameter("argument", 5); - - String path = base_path + op.getIdShort(); - submodelElement.setValue(path, op); - submodelElement.getValue(path); - submodelElement.invokeOperation(path + "/invoke", param); - submodelElement.deleteValue(path); - } + for (String keyword : SimpleAASSubmodel.KEYWORDS) { + Operation op = new Operation(); + op.setIdShort(keyword + "Operation"); + op.setInvokable(() -> { + // Do nothing + }); + + Map param = wrapParameter("argument", 5); + + String path = base_path + op.getIdShort(); + submodelElement.setValue(path, op); + submodelElement.getValue(path); + submodelElement.invokeOperation(path + "/invoke", param); + submodelElement.deleteValue(path); + } } @Test @@ -116,24 +131,25 @@ public void testSMElementCollectionIdShortWithKeywords() { final String base_path = SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/keywords/"; VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - for (String keyword : SimpleAASSubmodel.KEYWORDS) { - SubmodelElementCollection smc = new SubmodelElementCollection(); - smc.setIdShort(keyword + "Property"); + for (String keyword : SimpleAASSubmodel.KEYWORDS) { + SubmodelElementCollection smc = new SubmodelElementCollection(); + smc.setIdShort(keyword + "Property"); - Property prop = new Property(500); - prop.setIdShort("testProp"); + Property prop = new Property(500); + prop.setIdShort("testProp"); - String path = base_path + smc.getIdShort(); - submodelElement.setValue(path, smc); - submodelElement.setValue(path + "/" + prop.getIdShort(), prop); - submodelElement.getValue(path); - submodelElement.deleteValue(path); - } + String path = base_path + smc.getIdShort(); + submodelElement.setValue(path, smc); + submodelElement.setValue(path + "/" + prop.getIdShort(), prop); + submodelElement.getValue(path); + submodelElement.deleteValue(path); + } } /** * Tests accessing different paths that should be supported - * @throws Exception + * + * @throws Exception */ @Test public void testPathsRaw() throws Exception { @@ -152,7 +168,6 @@ public void testInvalidGetPath() { } } - /** * Test creating single property */ @@ -166,8 +181,7 @@ public void testCreateProperty() { submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop); // Read back value - Integer result = (Integer) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value"); + Integer result = (Integer) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value"); assertEquals(500, result.intValue()); } @@ -205,15 +219,13 @@ public void testUpdateFullProperty() { // Create element Property prop = new Property("newProperty", 500); submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", prop); - + // Update element Property updatedProp = new Property("newProperty", 400); - submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", - updatedProp); + submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty", updatedProp); // Read back value - Integer result = (Integer) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value"); + Integer result = (Integer) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/newProperty/value"); assertEquals(400, result.intValue()); } @@ -223,28 +235,20 @@ public void testUpdateFullProperty() { @Test public void testCreatePropertyInCollection() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - + // Create element Property prop = new Property(500); prop.setIdShort("newProperty"); - submodelElement.setValue( - SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty", prop); - + submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty", prop); + // Read back value - Integer result = (Integer) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS - + "/containerRoot/newProperty/value"); + Integer result = (Integer) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/newProperty/value"); assertEquals(500, result.intValue()); - - submodelElement.setValue( - SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", - prop); + submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop); // Read back value - result = (Integer) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS - + "/containerRoot/container/newProperty/value"); + result = (Integer) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value"); assertEquals(500, result.intValue()); } @@ -254,20 +258,14 @@ public void testUpdatePropertyInCollection() { // Create element Property prop = new Property("newProperty", 500); - submodelElement.setValue( - SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", - prop); + submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop); // Update element Property prop2 = new Property("newProperty", 400); - submodelElement.setValue( - SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", - prop2); + submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty", prop2); // Read back value - Integer result = (Integer) submodelElement.getValue( - SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS - + "/containerRoot/container/newProperty/value"); + Integer result = (Integer) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/containerRoot/container/newProperty/value"); assertEquals(400, result.intValue()); } @@ -286,41 +284,36 @@ public void testReadProperty() { assertEquals(123, property.get(Property.VALUE)); // Read whole property - result = submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); + result = submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); property = (Map) result; assertEquals(123, property.get(Property.VALUE)); // Read idShort - result = submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty"); + result = submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty"); property = (Map) result; assertEquals("stringProperty", property.get(Identifiable.IDSHORT)); // Read single value - String resString = (String) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty/value"); + String resString = (String) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/stringProperty/value"); assertEquals("Test", resString); // Read null value - Object resObject = submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/nullProperty/value"); + Object resObject = submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/nullProperty/value"); assertEquals(null, resObject); // Read container property - Collection resSet = (Collection) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/containerRoot/value"); + Collection resSet = (Collection) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/containerRoot/value"); assertEquals(1, resSet.size()); - + // Get Collection from root-Collection Map container = (Map) resSet.iterator().next(); - + assertEquals("container", container.get(Referable.IDSHORT)); assertTrue(container.get(Property.VALUE) instanceof Collection); - + // Get Value of nested Collection Map containerValue = SubmodelElementMapCollectionConverter.convertCollectionToIDMap(container.get(Property.VALUE)); - + // Check content of nested Collection assertTrue(containerValue.containsKey("operationId")); assertTrue(containerValue.containsKey("integerProperty")); @@ -343,15 +336,13 @@ public void testUpdateProperty() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); // Update element - submodelElement - .setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 3); + submodelElement.setValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty/value", 3); // Check result - Map result = (Map) submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); + Map result = (Map) submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); assertEquals(3, result.get(Property.VALUE)); } - + /** * Test updating a SubmodelElementCollection */ @@ -359,40 +350,37 @@ public void testUpdateProperty() { @Test public void testUpdateSmElementCollection() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - + Collection smElements = new ArrayList<>(); Property newProperty = new Property("propValue"); newProperty.setIdShort("propIdShort"); smElements.add(newProperty); - + // update value of smElemCollection - String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - "containerRoot"); + String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, "containerRoot"); submodelElement.setValue(path + "/value", smElements); - + // read back the collection - Map map = (Map) submodelElement - .getValue(path); - + Map map = (Map) submodelElement.getValue(path); + assertTrue(map.get(Property.VALUE) instanceof Collection); - + Collection> elements = (Collection>) map.get(Property.VALUE); assertEquals(1, elements.size()); - + Iterator> i = elements.iterator(); - + assertEquals("propIdShort", i.next().get(Referable.IDSHORT)); } /** - * Test updating a Property inside a SubmodelElementCollection + * Test updating a Property inside a SubmodelElementCollection */ @Test public void testUpdateElementInSmElementCollection() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - "containerRoot", "container", "integerProperty", "value"); + String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, "containerRoot", "container", "integerProperty", "value"); Integer value = (Integer) submodelElement.getValue(path); assertEquals(123, value.intValue()); @@ -410,10 +398,9 @@ public void testUpdateElementInSmElementCollection() { @Test public void testReadSingleOperation() { VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr); - Map operation = (Map) submodel - .getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/simple"); + Map operation = (Map) submodel.getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/simple"); assertEquals("simple", operation.get(Identifiable.IDSHORT)); - + try { submodel.getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/simple/value"); fail(); @@ -441,8 +428,7 @@ public void testReadSubmodelCheckElementsInCollection() { @Test public void testReadSubmodelElements() { VABElementProxy submodel = getConnectionManager().connectToVABElement(submodelAddr); - Collection> set = (Collection>) submodel - .getValue(SMPROVIDER_PATH_PREFIX + "submodelElements"); + Collection> set = (Collection>) submodel.getValue(SMPROVIDER_PATH_PREFIX + "submodelElements"); assertEquals(9, set.size()); } @@ -461,15 +447,14 @@ public void testDeleteSingleProperty() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); // Delete property - submodelElement - .deleteValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); + submodelElement.deleteValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); // Test, if it has been deleted try { - submodelElement - .getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); + submodelElement.getValue(SMPROVIDER_PATH_PREFIX + MultiSubmodelElementProvider.ELEMENTS + "/integerProperty"); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } } /** @@ -486,9 +471,10 @@ public void testDeleteOperation() { try { submodelElement.getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/simple"); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } } - + /** * Test deleting a single property from a SubmodelElementCollection */ @@ -496,14 +482,13 @@ public void testDeleteOperation() { public void testDeletePropertyFromCollection() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - "containerRoot", "container", "integerProperty"); - + String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, "containerRoot", "container", "integerProperty"); + assertNotNull(submodelElement.getValue(path)); // Delete property submodelElement.deleteValue(path); - + // Test if parent Collection is still there assertNotNull(submodelElement.getValue(VABPathTools.getParentPath(path))); @@ -511,14 +496,15 @@ public void testDeletePropertyFromCollection() { try { submodelElement.getValue(path); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Test delete the Collection "container" path = VABPathTools.getParentPath(path); - + // Delete property submodelElement.deleteValue(path); - + // Test if parent Collection is still there assertNotNull(submodelElement.getValue(VABPathTools.getParentPath(path))); @@ -526,7 +512,8 @@ public void testDeletePropertyFromCollection() { try { submodelElement.getValue(path); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } } @Test @@ -538,15 +525,14 @@ public void testInvokeOperation() { Map param2 = wrapParameter("SecondNumber", 2); // Invoke operation with wrapped parameters and check result - Object result = submodelElement.invokeOperation(SMPROVIDER_PATH_PREFIX + "submodelElements/complex/invoke", - param1, param2); + Object result = submodelElement.invokeOperation(SMPROVIDER_PATH_PREFIX + "submodelElements/complex/invoke", param1, param2); assertEquals(3, result); // Invoke operation on parent element result = submodelElement.invokeOperation(SMPROVIDER_PATH_PREFIX + "submodelElements/simple/invoke"); assertTrue((boolean) result); } - + @Test public void testInvalidInvokePath() { VABElementProxy smProxy = getConnectionManager().connectToVABElement(submodelAddr); @@ -563,14 +549,13 @@ public void testInvalidInvokePath() { @Test public void testInvokeOperationInCollection() { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); - - String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - "containerRoot", "container", "operationId", "invoke"); - + + String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, "containerRoot", "container", "operationId", "invoke"); + Object result = submodelElement.invokeOperation(path); assertEquals(123, result); } - + /** * Test getting /values of the Submodel */ @@ -585,66 +570,63 @@ public void testGetValues() { // Check if all expected Values are present assertTrue(values.containsKey("containerRoot")); Map collection1 = (Map) values.get("containerRoot"); - + assertTrue(collection1.containsKey("container")); Map collection2 = (Map) collection1.get("container"); - + // Check the Value in /containerRoot/container/integerProperty assertEquals(123, collection2.get("integerProperty")); - + assertEquals("Test", values.get("stringProperty")); assertEquals(123, values.get("integerProperty")); assertEquals(null, values.get("nullProperty")); } - + @SuppressWarnings("unchecked") @Test public void testInvokeAsync() throws Exception { VABElementProxy elementProxy = getConnectionManager().connectToVABElement(submodelAddr); AsyncOperationHelper helper = new AsyncOperationHelper(); - - String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - AsyncOperationHelper.ASYNC_OP_ID); + + String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID); elementProxy.setValue(path, helper.getAsyncOperation()); - + // Wrap parameters before invoking add-operation Map param1 = wrapParameter("FirstNumber", 5); Map param2 = wrapParameter("SecondNumber", 2); - + path = VABPathTools.concatenatePaths("submodel", MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, "invoke?async=true"); - + CallbackResponse response = CallbackResponse.createAsFacade((Map) elementProxy.invokeOperation(path, param1, param2)); String requestId = response.getRequestId(); - String listPath = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, - MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, - OperationProvider.INVOCATION_LIST); - + String listPath = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_OP_ID, OperationProvider.INVOCATION_LIST); + // Try correct operationId, wrong requestId try { elementProxy.getValue(VABPathTools.append(listPath, "nonexistent")); fail(); } catch (ResourceNotFoundException e) { } - + // Try wrong operationId, correct requestId try { elementProxy.getValue(SMPROVIDER_PATH_PREFIX + "submodelElements/simple/invocationList/" + requestId); fail(); } catch (ResourceNotFoundException e) { } - + String requestPath = VABPathTools.append(listPath, requestId); - + // Check that it has not finished yet InvocationResponse result = (InvocationResponse) elementProxy.getValue(requestPath); assertEquals(ExecutionState.INITIATED, result.getExecutionState()); - + helper.releaseWaitingOperation(); - + result = (InvocationResponse) elementProxy.getValue(requestPath); assertEquals(7, result.getFirstOutput()); - + // Check if the async-invocation is deleted after retrieving its result try { elementProxy.getValue(requestPath); @@ -652,50 +634,43 @@ public void testInvokeAsync() throws Exception { } catch (ResourceNotFoundException e) { } } - + @SuppressWarnings("unchecked") @Test public void testInvokeAsyncException() throws Exception { VABElementProxy submodelElement = getConnectionManager().connectToVABElement(submodelAddr); AsyncOperationHelper helper = new AsyncOperationHelper(); - - String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID); + + String path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID); submodelElement.setValue(path, helper.getAsyncExceptionOperation()); - path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, - AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, "invoke?async=true"); - + path = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, "invoke?async=true"); + CallbackResponse response = (CallbackResponse) submodelElement.invokeOperation(path); String requestId = response.getRequestId(); - - String requestPath = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, - MultiSubmodelElementProvider.ELEMENTS, - AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, OperationProvider.INVOCATION_LIST, requestId); - + + String requestPath = VABPathTools.concatenatePaths(SubmodelProvider.SUBMODEL, MultiSubmodelElementProvider.ELEMENTS, AsyncOperationHelper.ASYNC_EXCEPTION_OP_ID, OperationProvider.INVOCATION_LIST, requestId); + // Check that it has not finished yet - InvocationResponse invResp = InvocationResponse - .createAsFacade((Map) submodelElement.getValue(requestPath)); + InvocationResponse invResp = InvocationResponse.createAsFacade((Map) submodelElement.getValue(requestPath)); assertNotEquals(ExecutionState.COMPLETED, invResp.getExecutionState()); assertNotEquals(ExecutionState.FAILED, invResp.getExecutionState()); - + helper.releaseWaitingOperation(); - - invResp = InvocationResponse - .createAsFacade((Map) submodelElement.getValue(requestPath)); + invResp = InvocationResponse.createAsFacade((Map) submodelElement.getValue(requestPath)); assertEquals(ExecutionState.FAILED, invResp.getExecutionState()); - + // Check if the async-invocation is deleted after retrieving its result try { submodelElement.getValue(requestPath); fail(); } catch (ResourceNotFoundException e) { - } + } } - + protected Map wrapParameter(String name, Object value) { - Map param = new HashMap<>(); + Map param = new LinkedHashMap<>(); param.put(Identifiable.IDSHORT, name); param.put(Property.VALUE, value); param.put(Property.VALUETYPE, ValueTypeHelper.getType(value).toString()); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestSubmodelElementCollectionProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestSubmodelElementCollectionProvider.java new file mode 100644 index 00000000..02776ac1 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/TestSubmodelElementCollectionProvider.java @@ -0,0 +1,122 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. + +* +* SPDX-License-Identifier: MIT +******************************************************************************/ + +package org.eclipse.basyx.testsuite.regression.submodel.restapi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetype.ValueType; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider; +import org.eclipse.basyx.submodel.restapi.SubmodelElementCollectionProvider; +import org.eclipse.basyx.submodel.restapi.SubmodelProvider; +import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaProvider; +import org.junit.Before; +import org.junit.Test; + +public class TestSubmodelElementCollectionProvider { + private static final String PROP_ID1 = "prop1"; + private static final String PROP_VALUE1 = "value1"; + private static final String PROP_ID2 = "prop2"; + private static final String PROP_VALUE2 = "value2"; + private static final String OP_ID1 = "op1"; + private static final String COL_ID1 = "col1"; + + private static SubmodelElementCollectionProvider colProvider; + + @Before + public void setup() { + Property prop1 = new Property(PROP_ID1, PROP_VALUE1); + prop1.setKind(ModelingKind.TEMPLATE); + prop1.setValueType(ValueType.String); + + Property prop2 = new Property(PROP_ID2, PROP_VALUE2); + prop2.setKind(ModelingKind.TEMPLATE); + prop2.setValueType(ValueType.String); + + Operation op = new Operation(OP_ID1); + + SubmodelElementCollection smCol = new SubmodelElementCollection(COL_ID1); + smCol.addSubmodelElement(prop1); + smCol.addSubmodelElement(prop2); + smCol.addSubmodelElement(op); + + colProvider = new SubmodelElementCollectionProvider(new VABLambdaProvider(smCol)); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetValuesByEmptyPath() { + Map values = (Map) colProvider.getValue(""); + SubmodelElementCollection retrievedCol = SubmodelElementCollection.createAsFacade(values); + assertEquals(COL_ID1, retrievedCol.getIdShort()); + assertEquals(1, retrievedCol.getOperations().size()); + assertEquals(2, retrievedCol.getProperties().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetValuesByValuesCall() { + Map values = (Map) colProvider.getValue("/" + SubmodelProvider.VALUES + "/"); + assertEquals(2, values.size()); + assertTrue(values.containsKey(PROP_ID1)); + assertTrue(values.containsKey(PROP_ID2)); + assertEquals(PROP_VALUE1, values.get(PROP_ID1)); + assertEquals(PROP_VALUE2, values.get(PROP_ID2)); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetValuesByValueCall() { + Collection> colElements = (Collection>) colProvider.getValue("/" + MultiSubmodelElementProvider.VALUE + "/"); + assertEquals(3, colElements.size()); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetValuesByIdShortCall() { + Map elemMap = (Map) colProvider.getValue("/" + PROP_ID1); + Property propElem1 = Property.createAsFacade(elemMap); + assertEquals(PROP_ID1, propElem1.getIdShort()); + assertEquals(PROP_VALUE1, propElem1.getValue()); + + elemMap = (Map) colProvider.getValue("/" + PROP_ID2); + Property propElem2 = Property.createAsFacade(elemMap); + assertEquals(PROP_ID2, propElem2.getIdShort()); + assertEquals(PROP_VALUE2, propElem2.getValue()); + + elemMap = (Map) colProvider.getValue("/" + OP_ID1); + Operation opElem = Operation.createAsFacade(elemMap); + assertEquals(OP_ID1, opElem.getIdShort()); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/observing/ObservableSubmodelAPITest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/observing/ObservableSubmodelAPITest.java new file mode 100644 index 00000000..6e6f2ca0 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/restapi/observing/ObservableSubmodelAPITest.java @@ -0,0 +1,152 @@ +/******************************************************************************* +* Copyright (C) 2021 the Eclipse BaSyx Authors +* + * 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. +* +* SPDX-License-Identifier: MIT +******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.submodel.restapi.observing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType; +import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements; +import org.eclipse.basyx.submodel.metamodel.map.Submodel; +import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier; +import org.eclipse.basyx.submodel.metamodel.map.reference.Key; +import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property; +import org.eclipse.basyx.submodel.restapi.observing.ISubmodelAPIObserver; +import org.eclipse.basyx.submodel.restapi.observing.ObservableSubmodelAPI; +import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI; +import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; +import org.junit.Before; +import org.junit.Test; + +/** + * Test for ObservableSubmodelAPI + * + * @author conradi + * + */ +public class ObservableSubmodelAPITest { + + private static final String AAS_ID = "testaasid"; + private static final String SUBMODEL_ID = "testsubmodelid"; + private static final String PROPERTY_ID = "testpropertyid"; + + private ObservableSubmodelAPI api; + private MockObserver observer; + + @Before + public void setup() { + // Create submodel + Submodel sm = new Submodel(SUBMODEL_ID, new Identifier(IdentifierType.CUSTOM, SUBMODEL_ID)); + Reference parentRef = new Reference(new Key(KeyElements.ASSETADMINISTRATIONSHELL, true, AAS_ID, IdentifierType.IRDI)); + sm.setParent(parentRef); + + // Create Property + Property prop = new Property(PROPERTY_ID, 1); + sm.addSubmodelElement(prop); + + // Create an Observer + observer = new MockObserver(); + + // Create ObservableAPI + VABSubmodelAPI vabAPI = new VABSubmodelAPI(new VABMapProvider(sm)); + api = new ObservableSubmodelAPI(vabAPI); + + // Register the observer at the API + api.addObserver(observer); + } + + @Test + public void testAddElement() { + Property prop1 = new Property("newProperty1", "newtest1"); + api.addSubmodelElement(prop1); + assertTrue(observer.addedNotified); + assertEquals(prop1.getIdShort(), observer.idShortPath); + assertEquals(prop1.getValue(), observer.newValue); + + observer.addedNotified = false; + + Property prop2 = new Property("newProperty2", "newtest2"); + api.addSubmodelElement(prop2.getIdShort(), prop2); + assertTrue(observer.addedNotified); + assertEquals(prop2.getIdShort(), observer.idShortPath); + assertEquals(prop2.getValue(), observer.newValue); + } + + @Test + public void testDeleteElement() { + api.deleteSubmodelElement(PROPERTY_ID); + assertTrue(observer.deletedNotified); + assertEquals(PROPERTY_ID, observer.idShortPath); + } + + @Test + public void testUpdateElement() { + api.updateSubmodelElement(PROPERTY_ID, 2); + assertTrue(observer.updatedNotified); + assertEquals(PROPERTY_ID, observer.idShortPath); + assertEquals(2, observer.newValue); + } + + @Test + public void testRemoveObserver() { + assertTrue(api.removeObserver(observer)); + api.deleteSubmodelElement(PROPERTY_ID); + assertFalse(observer.deletedNotified); + } + + private class MockObserver implements ISubmodelAPIObserver { + + public boolean addedNotified = false; + public boolean deletedNotified = false; + public boolean updatedNotified = false; + + public String idShortPath = ""; + public Object newValue = null; + + @Override + public void elementAdded(String idShortPath, Object newValue) { + addedNotified = true; + this.idShortPath = idShortPath; + this.newValue = newValue; + } + + @Override + public void elementDeleted(String idShortPath) { + deletedNotified = true; + this.idShortPath = idShortPath; + } + + @Override + public void elementUpdated(String idShortPath, Object newValue) { + updatedNotified = true; + this.idShortPath = idShortPath; + this.newValue = newValue; + } + + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java index 70452295..bdfc636f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/TestDigitalNameplateSubmodel.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate; @@ -13,7 +28,7 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -47,8 +62,8 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link DigitalNameplateSubmodel} for their - * correctness + * Tests createAsFacade and isValid of {@link DigitalNameplateSubmodel} for + * their correctness * * @author haque * @@ -63,8 +78,8 @@ public class TestDigitalNameplateSubmodel { public static Markings markings; public static AssetSpecificProperties assetSpecificProperties = new AssetSpecificProperties(Collections.singletonList(TestAssetSpecificProperties.guidelineSpecificProperties)); public static Identifier identifier = new Identifier(IdentifierType.IRI, "https://admin-shell.io/zvei/nameplate/1/0/Nameplate"); - private Map submodelMap = new HashMap(); - + private Map submodelMap = new LinkedHashMap(); + @Before public void buildFax() { manufacturerName.setValue(new LangStrings(new LangString("DE", "Test Manufacturer"))); @@ -72,7 +87,7 @@ public void buildFax() { productFamily.setValue(new LangStrings(new LangString("DE", "Test Product Family"))); serialNumber.setValue("123456"); yearsOfConstruction.setValue("2020"); - + TestMarking.markingFile.setIdShort(Marking.MARKINGFILEID); TestMarking.markingName.setValue("0173-1#07-DAA603#004"); TestMarkings.marking = new Marking(TestMarking.IDSHORT, TestMarking.markingName, TestMarking.markingFile); @@ -80,12 +95,12 @@ public void buildFax() { TestMarkings.markings = new ArrayList(); TestMarkings.markings.add(TestMarkings.marking); markings = new Markings(TestMarkings.markings); - + TestAddress.street.setValue(new LangStrings(new LangString("DE", "musterstraße 1"))); TestAddress.zipCode.setValue(new LangStrings(new LangString("DE", "12345"))); TestAddress.cityTown.setValue(new LangStrings(new LangString("DE", "MusterStadt"))); TestAddress.nationalCode.setValue(new LangStrings(new LangString("DE", "DE"))); - + List elements = new ArrayList(); elements.add(manufacturerName); elements.add(designation); @@ -116,55 +131,55 @@ public void testCreateAsFacade() { assertEquals(DigitalNameplateSubmodel.SUBMODELID, submodelFromMap.getIdShort()); assertEquals(identifier, submodelFromMap.getIdentification()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { submodelMap.remove(Referable.IDSHORT); DigitalNameplateSubmodel.createAsFacade(submodelMap); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdentifier() { submodelMap.remove(Identifiable.IDENTIFICATION); DigitalNameplateSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionManufacturerName() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(manufacturerName); DigitalNameplateSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionZearsOfConstruction() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(yearsOfConstruction); DigitalNameplateSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionManufacturerProductDesignation() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(designation); DigitalNameplateSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionAddress() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(address); DigitalNameplateSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionManufacturerProductFamily() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(productFamily); DigitalNameplateSubmodel.createAsFacade(submodelMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java index 9da5fca2..58d56251 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestAddress.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address; import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -34,8 +49,7 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link Address} for their - * correctness + * Tests createAsFacade and isValid of {@link Address} for their correctness * * @author haque * @@ -59,10 +73,9 @@ public class TestAddress { public static Fax fax2 = new Fax("Fax02", new LangString("DE", "123456711")); public static Email email1 = new Email("Email01", new Property(Email.EMAILADDRESSID, "abc@test.com")); public static Email email2 = new Email("Email02", new Property(Email.EMAILADDRESSID, "abcd@test.com")); - - private Map addressMap = new HashMap(); - + private Map addressMap = new LinkedHashMap(); + @Before public void buildFax() { department.setValue(new LangStrings(new LangString("DE", "Dept Test"))); @@ -76,7 +89,7 @@ public void buildFax() { vatNumber.setValue(new LangStrings(new LangString("DE", "123456"))); addressRemarks.setValue(new LangStrings(new LangString("DE", "test remarks"))); additLink.setValue("test.com"); - + List elements = new ArrayList(); elements.add(department); elements.add(street); @@ -95,12 +108,12 @@ public void buildFax() { elements.add(fax2); elements.add(email1); elements.add(email2); - + addressMap.put(Referable.IDSHORT, IDSHORT); addressMap.put(HasSemantics.SEMANTICID, Address.SEMANTICID); addressMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { Address addressFromMap = Address.createAsFacade(addressMap); @@ -118,53 +131,53 @@ public void testCreateAsFacade() { assertEquals(addressRemarks, addressFromMap.getAddressRemarks()); assertEquals(additLink, addressFromMap.getAddressOfAdditionalLink()); List phones = new ArrayList(); - phones.add(phone2); phones.add(phone1); + phones.add(phone2); List faxes = new ArrayList(); faxes.add(fax1); faxes.add(fax2); List emails = new ArrayList(); - emails.add(email2); emails.add(email1); + emails.add(email2); assertEquals(phones, addressFromMap.getPhone()); assertEquals(faxes, addressFromMap.getFax()); assertEquals(emails, addressFromMap.getEmail()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { addressMap.remove(Referable.IDSHORT); Address.createAsFacade(addressMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionStreet() { - List elements = (List)addressMap.get(Property.VALUE); + List elements = (List) addressMap.get(Property.VALUE); elements.remove(street); Address.createAsFacade(addressMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionZipCode() { - List elements = (List)addressMap.get(Property.VALUE); + List elements = (List) addressMap.get(Property.VALUE); elements.remove(zipCode); Address.createAsFacade(addressMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionCityTown() { - List elements = (List)addressMap.get(Property.VALUE); + List elements = (List) addressMap.get(Property.VALUE); elements.remove(cityTown); Address.createAsFacade(addressMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionNationalCode() { - List elements = (List)addressMap.get(Property.VALUE); + List elements = (List) addressMap.get(Property.VALUE); elements.remove(nationalCode); Address.createAsFacade(addressMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java index 7397b47a..76a4f73b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestEmail.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address; import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,8 +47,7 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link Email} for their - * correctness + * Tests createAsFacade and isValid of {@link Email} for their correctness * * @author haque * @@ -45,8 +59,8 @@ public class TestEmail { public static Property typeOfEmailAddress = new Property(Email.TYPEOFEMAILADDRESSID, ValueType.String); public static MultiLanguageProperty typeOfPublicKey = new MultiLanguageProperty(Email.TYPEOFPUBLICKEYID); - private Map emailMap = new HashMap(); - + private Map emailMap = new LinkedHashMap(); + @Before public void buildFax() { emailAddress.setValue("test@muster-ag.de"); @@ -62,7 +76,7 @@ public void buildFax() { emailMap.put(HasSemantics.SEMANTICID, Email.SEMANTICID); emailMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { Email emailFromMap = Email.createAsFacade(emailMap); @@ -73,14 +87,14 @@ public void testCreateAsFacade() { assertEquals(typeOfPublicKey, emailFromMap.getTypeOfPublicKey()); assertEquals(IDSHORT, emailFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { emailMap.remove(Referable.IDSHORT); Email.createAsFacade(emailMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionEmailAddress() { List newElements = new ArrayList(); newElements.add(typeOfEmailAddress); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java index 40f70692..0d4f6b80 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestFax.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address; import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,8 +47,7 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link Fax} for their - * correctness + * Tests createAsFacade and isValid of {@link Fax} for their correctness * * @author haque * @@ -43,8 +57,8 @@ public class TestFax { public static MultiLanguageProperty faxNumber = new MultiLanguageProperty(Fax.FAXNUMBERID); public static Property typeOfFax = new Property(Fax.TYPEOFFAXID, ValueType.String); - private Map faxMap = new HashMap(); - + private Map faxMap = new LinkedHashMap(); + @Before public void buildFax() { faxNumber.setValue(new LangStrings(new LangString("DE", "0631123456"))); @@ -65,14 +79,14 @@ public void testCreateAsFacade() { assertEquals(typeOfFax, faxFromMap.getTypeOfFaxNumber()); assertEquals(IDSHORT, faxFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { faxMap.remove(Referable.IDSHORT); Fax.createAsFacade(faxMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionFaxNumber() { List newElements = new ArrayList(); newElements.add(typeOfFax); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java index 575daa4d..ba1d524e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/address/TestPhone.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.address; import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,8 +47,7 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link Phone} for their - * correctness + * Tests createAsFacade and isValid of {@link Phone} for their correctness * * @author haque * @@ -42,8 +56,8 @@ public class TestPhone { public static final String IDSHORT = "testPhoneId"; public static MultiLanguageProperty telephone = new MultiLanguageProperty(Phone.TELEPHONENUMBERID); public static Property typeOfTelephone = new Property(Phone.TYPEOFTELEPHONEID, ValueType.String); - private Map phoneMap = new HashMap(); - + private Map phoneMap = new LinkedHashMap(); + @Before public void buildPhone() { telephone.setValue(new LangStrings(new LangString("DE", "0631123456"))); @@ -55,7 +69,7 @@ public void buildPhone() { phoneMap.put(HasSemantics.SEMANTICID, Phone.SEMANTICID); phoneMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { Phone phoneFromMap = Phone.createAsFacade(phoneMap); @@ -64,14 +78,14 @@ public void testCreateAsFacade() { assertEquals(typeOfTelephone, phoneFromMap.getTypeOfTelephone()); assertEquals(IDSHORT, phoneFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { phoneMap.remove(Referable.IDSHORT); Phone.createAsFacade(phoneMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionTelephoneNumber() { List newElements = new ArrayList(); newElements.add(typeOfTelephone); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java index eba76433..e1fa39e4 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestAssetSpecificProperties.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties; @@ -13,7 +28,7 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -36,21 +51,22 @@ */ public class TestAssetSpecificProperties { public static final String IDSHORT = "AssetSpecificProperties"; - public static GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties(TestGuidelineSpecificProperties.IDSHORT, TestGuidelineSpecificProperties.conformityDeclaration, Collections.singletonList(TestGuidelineSpecificProperties.arbitrary)); - - private Map assetMap = new HashMap(); - + public static GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties(TestGuidelineSpecificProperties.IDSHORT, TestGuidelineSpecificProperties.conformityDeclaration, + Collections.singletonList(TestGuidelineSpecificProperties.arbitrary)); + + private Map assetMap = new LinkedHashMap(); + @Before public void buildAssetSpecificProperties() { - + List elements = new ArrayList(); elements.add(guidelineSpecificProperties); - + assetMap.put(Referable.IDSHORT, IDSHORT); assetMap.put(HasSemantics.SEMANTICID, AssetSpecificProperties.SEMANTICID); assetMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { AssetSpecificProperties assetFromMap = AssetSpecificProperties.createAsFacade(assetMap); @@ -58,17 +74,17 @@ public void testCreateAsFacade() { assertEquals(Collections.singletonList(guidelineSpecificProperties), assetFromMap.getGuidelineSpecificProperties()); assertEquals(IDSHORT, assetFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { assetMap.remove(Referable.IDSHORT); AssetSpecificProperties.createAsFacade(assetMap); } - + @SuppressWarnings("unchecked") - @Test (expected = MetamodelConstructionException.class) + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionGuideline() { - List elements = (List)assetMap.get(Property.VALUE); + List elements = (List) assetMap.get(Property.VALUE); elements.remove(guidelineSpecificProperties); AssetSpecificProperties.createAsFacade(assetMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java index c23dfa0d..d7d1f36a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/assetspecificproperties/TestGuidelineSpecificProperties.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties; @@ -13,7 +28,7 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -29,8 +44,8 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link GuidelineSpecificProperties} for their - * correctness + * Tests createAsFacade and isValid of {@link GuidelineSpecificProperties} for + * their correctness * * @author haque * @@ -39,23 +54,23 @@ public class TestGuidelineSpecificProperties { public static final String IDSHORT = "GuidelineSpecificProperties01"; public static Property conformityDeclaration = new Property(GuidelineSpecificProperties.GUIDELINEFORCONFORMITYDECLARATIONID, ValueType.String); public static Property arbitrary = new Property("arbitraryId", ValueType.String); - - private Map guidelineMap = new HashMap(); - + + private Map guidelineMap = new LinkedHashMap(); + @Before public void buildGuidelineSpecificProperties() { conformityDeclaration.setValue("test Declaration"); arbitrary.setValue("0173-1#07-DAA603#004"); - + List elements = new ArrayList(); elements.add(conformityDeclaration); elements.add(arbitrary); - + guidelineMap.put(Referable.IDSHORT, IDSHORT); guidelineMap.put(HasSemantics.SEMANTICID, GuidelineSpecificProperties.SEMANTICID); guidelineMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { GuidelineSpecificProperties guidelineFromMap = GuidelineSpecificProperties.createAsFacade(guidelineMap); @@ -64,25 +79,25 @@ public void testCreateAsFacade() { assertEquals(Collections.singletonList(arbitrary), guidelineFromMap.getArbitrary()); assertEquals(IDSHORT, guidelineFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { guidelineMap.remove(Referable.IDSHORT); GuidelineSpecificProperties.createAsFacade(guidelineMap); } - + @SuppressWarnings("unchecked") - @Test (expected = MetamodelConstructionException.class) + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionArbitrary() { - List elements = (List)guidelineMap.get(Property.VALUE); + List elements = (List) guidelineMap.get(Property.VALUE); elements.remove(arbitrary); GuidelineSpecificProperties.createAsFacade(guidelineMap); } @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionDeclaration() { - List elements = (List)guidelineMap.get(Property.VALUE); + List elements = (List) guidelineMap.get(Property.VALUE); elements.remove(conformityDeclaration); GuidelineSpecificProperties.createAsFacade(guidelineMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java index c3939be2..e35a0934 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarking.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings; @@ -13,7 +28,7 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -30,8 +45,7 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link Marking} for their - * correctness + * Tests createAsFacade and isValid of {@link Marking} for their correctness * * @author haque * @@ -41,25 +55,25 @@ public class TestMarking { public static Property markingName = new Property(Marking.MARKINGNAMEID, ValueType.String); public static File markingFile = new File("/to/the/image.jpg", "image/jpg"); public static Property additText = new Property(Marking.MARKINGADDITIONALTEXTPREFIX + "01", ValueType.String); - - private Map markingMap = new HashMap(); - + + private Map markingMap = new LinkedHashMap(); + @Before public void buildFax() { markingFile.setIdShort(Marking.MARKINGFILEID); markingName.setValue("0173-1#07-DAA603#004"); additText.setValue("text additional"); - + List elements = new ArrayList(); elements.add(markingFile); elements.add(markingName); elements.add(additText); - + markingMap.put(Referable.IDSHORT, IDSHORT); markingMap.put(HasSemantics.SEMANTICID, Marking.SEMANTICID); markingMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { Marking markingFromMap = Marking.createAsFacade(markingMap); @@ -69,25 +83,25 @@ public void testCreateAsFacade() { assertEquals(Collections.singletonList(additText), markingFromMap.getMarkingAdditionalText()); assertEquals(IDSHORT, markingFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { markingMap.remove(Referable.IDSHORT); Marking.createAsFacade(markingMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionMarkingName() { - List elements = (List)markingMap.get(Property.VALUE); + List elements = (List) markingMap.get(Property.VALUE); elements.remove(markingName); Marking.createAsFacade(markingMap); } @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionMarkingFile() { - List elements = (List)markingMap.get(Property.VALUE); + List elements = (List) markingMap.get(Property.VALUE); elements.remove(markingFile); Marking.createAsFacade(markingMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java index fc2a613b..c3811ead 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/digitalnameplate/submodelelementcollections/markings/TestMarkings.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.digitalnameplate.submodelelementcollections.markings; @@ -20,7 +35,7 @@ import org.junit.Before; import org.junit.Test; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException; @@ -32,8 +47,7 @@ import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; /** - * Tests createAsFacade and isValid of {@link Markings} for their - * correctness + * Tests createAsFacade and isValid of {@link Markings} for their correctness * * @author haque * @@ -43,8 +57,8 @@ public class TestMarkings { public static List markings; public static Marking marking; - private Map markingsMap = new HashMap(); - + private Map markingsMap = new LinkedHashMap(); + @Before public void initMarkings() { TestMarking.markingFile.setIdShort(Marking.MARKINGFILEID); @@ -53,12 +67,12 @@ public void initMarkings() { marking.setParent(new Reference(new Key(KeyElements.SUBMODELELEMENTCOLLECTION, true, IDSHORT, IdentifierType.IRDI))); markings = new ArrayList(); markings.add(marking); - + markingsMap.put(Referable.IDSHORT, IDSHORT); markingsMap.put(Property.VALUE, markings); markingsMap.put(HasSemantics.SEMANTICID, Markings.SEMANTICID); } - + @Test public void testCreateAsFacade() { Markings markingsFromMap = Markings.createAsFacade(markingsMap); @@ -66,20 +80,20 @@ public void testCreateAsFacade() { assertEquals(markings, markingsFromMap.getMarking()); assertEquals(IDSHORT, markingsFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { markingsMap.remove(Referable.IDSHORT); Markings.createAsFacade(markingsMap); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionNullMarkings() { markingsMap.remove(Property.VALUE); Markings.createAsFacade(markingsMap); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionEmptyMarkings() { markingsMap.put(Property.VALUE, new ArrayList()); Markings.createAsFacade(markingsMap); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java index c8e70ce4..dab84e90 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/TestTechnicalDataSubmodel.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata; @@ -14,7 +29,7 @@ import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -52,10 +67,10 @@ public class TestTechnicalDataSubmodel { public static ProductClassifications productClassifications = new ProductClassifications(TechnicalDataSubmodel.PRODUCTCLASSIFICATIONSID); public static TechnicalProperties technicalProperties = new TechnicalProperties(TechnicalDataSubmodel.TECHNICALPROPERTIESID); public static FurtherInformation furtherInformation = new FurtherInformation(new Property(FurtherInformation.VALIDDATEID, ValueType.DateTime)); - + public static Identifier identifier = new Identifier(IdentifierType.IRI, "http://admin-shell.io/ZVEI/TechnicalData/Submodel/1/1"); - private Map submodelMap = new HashMap(); - + private Map submodelMap = new LinkedHashMap(); + @Before public void buildFax() { TestGeneralInformation.manufacturerName.setValue("Example Company"); @@ -68,7 +83,7 @@ public void buildFax() { elements.add(furtherInformation); elements.add(productClassifications); elements.add(technicalProperties); - + submodelMap.put(Referable.IDSHORT, TechnicalDataSubmodel.SUBMODELID); submodelMap.put(HasSemantics.SEMANTICID, TechnicalDataSubmodel.SEMANTICID); submodelMap.put(Submodel.SUBMODELELEMENT, elements); @@ -86,31 +101,31 @@ public void testCreateAsFacade() { assertEquals(TechnicalDataSubmodel.SUBMODELID, submodelFromMap.getIdShort()); assertEquals(identifier, submodelFromMap.getIdentification()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { submodelMap.remove(Referable.IDSHORT); TechnicalDataSubmodel.createAsFacade(submodelMap); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdentifier() { submodelMap.remove(Identifiable.IDENTIFICATION); TechnicalDataSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionGeneralInfo() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(generalInformation); TechnicalDataSubmodel.createAsFacade(submodelMap); } - + @SuppressWarnings("unchecked") - @Test (expected = ResourceNotFoundException.class) + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionTechnicalProp() { - List elements = (List)submodelMap.get(Submodel.SUBMODELELEMENT); + List elements = (List) submodelMap.get(Submodel.SUBMODELELEMENT); elements.remove(technicalProperties); TechnicalDataSubmodel.createAsFacade(submodelMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java index b82ed47c..57d13f92 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/furtherinformation/TestFurtherInformation.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.furtherinformation; @@ -14,7 +29,7 @@ import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -42,8 +57,8 @@ public class TestFurtherInformation { public static MultiLanguageProperty statement = new MultiLanguageProperty(FurtherInformation.TEXTSTATEMENTPREFIX + "01"); public static Property validDate = new Property(FurtherInformation.VALIDDATEID, ValueType.DateTime); - private Map furtherInfoMap = new HashMap(); - + private Map furtherInfoMap = new LinkedHashMap(); + @Before public void init() { statement.setValue(new LangStrings(new LangString("DE", "test statement"))); @@ -55,7 +70,7 @@ public void init() { furtherInfoMap.put(HasSemantics.SEMANTICID, FurtherInformation.SEMANTICID); furtherInfoMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { FurtherInformation infoFromMap = FurtherInformation.createAsFacade(furtherInfoMap); @@ -64,14 +79,14 @@ public void testCreateAsFacade() { assertEquals(validDate, infoFromMap.getValidDate()); assertEquals(FurtherInformation.IDSHORT, infoFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { furtherInfoMap.remove(Referable.IDSHORT); FurtherInformation.createAsFacade(furtherInfoMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) public void testCreateAsFacadeExceptionValidDate() { List newElements = new ArrayList(); newElements.add(statement); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java index a54c7630..4c4399c8 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/generalinformation/TestGeneralInformation.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.generalinformation; @@ -14,7 +29,7 @@ import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -47,9 +62,9 @@ public class TestGeneralInformation { public static Property partNumber = new Property(GeneralInformation.MANUFACTURERPARTNUMBERID, ValueType.String); public static Property orderCode = new Property(GeneralInformation.MANUFACTURERORDERCODEID, ValueType.String); public static File image = new File("image/jpg"); - - private Map InfoMap = new HashMap(); - + + private Map InfoMap = new LinkedHashMap(); + @Before public void init() { manufacturerName.setValue("Example Company"); @@ -60,7 +75,7 @@ public void init() { orderCode.setValue("EEA-EX-200-S/47-Q3"); image.setIdShort(GeneralInformation.PRODUCTIMAGEPREFIX + "01"); image.setValue("/aasx/TechnicalData/ ProdFromTop.jpg"); - + List elements = new ArrayList(); elements.add(manufacturerName); elements.add(manufacturerLogo); @@ -68,12 +83,12 @@ public void init() { elements.add(partNumber); elements.add(orderCode); elements.add(image); - + InfoMap.put(Referable.IDSHORT, GeneralInformation.IDSHORT); InfoMap.put(HasSemantics.SEMANTICID, GeneralInformation.SEMANTICID); InfoMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { GeneralInformation infoFromMap = GeneralInformation.createAsFacade(InfoMap); @@ -86,41 +101,41 @@ public void testCreateAsFacade() { assertEquals(orderCode, infoFromMap.getManufacturerOrderCode()); assertEquals(GeneralInformation.IDSHORT, infoFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { InfoMap.remove(Referable.IDSHORT); GeneralInformation.createAsFacade(InfoMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) @SuppressWarnings("unchecked") public void testCreateAsFacadeExceptionName() { - List elements = (List)InfoMap.get(Property.VALUE); + List elements = (List) InfoMap.get(Property.VALUE); elements.remove(manufacturerName); GeneralInformation.createAsFacade(InfoMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) @SuppressWarnings("unchecked") public void testCreateAsFacadeExceptionDesignation() { - List elements = (List)InfoMap.get(Property.VALUE); + List elements = (List) InfoMap.get(Property.VALUE); elements.remove(designation); GeneralInformation.createAsFacade(InfoMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) @SuppressWarnings("unchecked") public void testCreateAsFacadeExceptionPartNumber() { - List elements = (List)InfoMap.get(Property.VALUE); + List elements = (List) InfoMap.get(Property.VALUE); elements.remove(partNumber); GeneralInformation.createAsFacade(InfoMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) @SuppressWarnings("unchecked") public void testCreateAsFacadeExceptionOrderCode() { - List elements = (List)InfoMap.get(Property.VALUE); + List elements = (List) InfoMap.get(Property.VALUE); elements.remove(orderCode); GeneralInformation.createAsFacade(InfoMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java index 8175a469..c33d4150 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassificationItem.java @@ -1,19 +1,34 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.productclassifications; import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -30,8 +45,8 @@ import org.junit.Test; /** - * Tests createAsFacade and isValid of {@link ProductClassificationItem} for their - * correctness + * Tests createAsFacade and isValid of {@link ProductClassificationItem} for + * their correctness * * @author haque * @@ -40,25 +55,25 @@ public class TestProductClassificationItem { public static Property classificationSystem = new Property(ProductClassificationItem.PRODUCTCLASSIFICATIONSYSTEMID, ValueType.String); public static Property version = new Property(ProductClassificationItem.CLASSIFICATIONSYSTEMVERSIONID, ValueType.String); public static Property productClass = new Property(ProductClassificationItem.PRODUCTCLASSID, ValueType.String); - - private Map classificationMap = new HashMap(); - + + private Map classificationMap = new LinkedHashMap(); + @Before public void init() { classificationSystem.setValue("ECLASS"); version.setValue("9.0 (BASIC)"); productClass.setValue("27-01-88-77"); - + List elements = new ArrayList(); elements.add(classificationSystem); elements.add(version); elements.add(productClass); - + classificationMap.put(Referable.IDSHORT, ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01"); classificationMap.put(HasSemantics.SEMANTICID, ProductClassificationItem.SEMANTICID); classificationMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { ProductClassificationItem classificationFromMap = ProductClassificationItem.createAsFacade(classificationMap); @@ -68,25 +83,25 @@ public void testCreateAsFacade() { assertEquals(productClass, classificationFromMap.getProductClassId()); assertEquals(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", classificationFromMap.getIdShort()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { classificationMap.remove(Referable.IDSHORT); ProductClassificationItem.createAsFacade(classificationMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) @SuppressWarnings("unchecked") public void testCreateAsFacadeExceptionProductClassificationSystem() { - List elements = (List)classificationMap.get(Property.VALUE); + List elements = (List) classificationMap.get(Property.VALUE); elements.remove(classificationSystem); ProductClassificationItem.createAsFacade(classificationMap); } - - @Test (expected = ResourceNotFoundException.class) + + @Test(expected = ResourceNotFoundException.class) @SuppressWarnings("unchecked") public void testCreateAsFacadeExceptionProductClassId() { - List elements = (List)classificationMap.get(Property.VALUE); + List elements = (List) classificationMap.get(Property.VALUE); elements.remove(productClass); ProductClassificationItem.createAsFacade(classificationMap); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java index 1069b98d..ce8abbfb 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/productclassifications/TestProductClassifications.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.productclassifications; @@ -14,7 +29,7 @@ import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -36,20 +51,21 @@ * */ public class TestProductClassifications { - public static ProductClassificationItem productClassificationItem = new ProductClassificationItem(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", TestProductClassificationItem.classificationSystem, TestProductClassificationItem.productClass); - - private Map classificationMap = new HashMap(); - + public static ProductClassificationItem productClassificationItem = new ProductClassificationItem(ProductClassifications.PRODUCTCLASSIFICATIONITEMPREFIX + "01", TestProductClassificationItem.classificationSystem, + TestProductClassificationItem.productClass); + + private Map classificationMap = new LinkedHashMap(); + @Before public void init() { List elements = new ArrayList(); elements.add(productClassificationItem); - + classificationMap.put(Referable.IDSHORT, ProductClassifications.IDSHORT); classificationMap.put(HasSemantics.SEMANTICID, ProductClassifications.SEMANTICID); classificationMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { ProductClassifications classificationFromMap = ProductClassifications.createAsFacade(classificationMap); @@ -57,8 +73,8 @@ public void testCreateAsFacade() { assertEquals(ProductClassifications.IDSHORT, classificationFromMap.getIdShort()); assertEquals(Collections.singletonList(productClassificationItem), classificationFromMap.getProductClassificationItems()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { classificationMap.remove(Referable.IDSHORT); ProductClassifications.createAsFacade(classificationMap); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java index 7dd66665..f7cc7502 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/submodel/types/technicaldata/technicalproperties/TestTechnicalProperties.java @@ -1,12 +1,27 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * -* This program and the accompanying materials are made -* available under the terms of the Eclipse Public License 2.0 -* which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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. * -* SPDX-License-Identifier: EPL-2.0 +* SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.submodel.types.technicaldata.technicalproperties; @@ -14,7 +29,7 @@ import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -46,9 +61,9 @@ public class TestTechnicalProperties { public static SubmodelElementCollection subSection = new SubmodelElementCollection(TechnicalProperties.SUBSECTIONPREFIX + "01"); public static SubmodelElement arbitrary1 = new Property("arbitraryId1", ValueType.String); public static SubmodelElement arbitrary2 = new Property("arbitraryId2", ValueType.String); - - private Map technicalMap = new HashMap(); - + + private Map technicalMap = new LinkedHashMap(); + @Before public void init() { mainSection.setSemanticId(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, TechnicalProperties.MAINSECTIONID, IdentifierType.IRDI))); @@ -61,12 +76,12 @@ public void init() { elements.add(subSection); elements.add(arbitrary1); elements.add(arbitrary2); - + technicalMap.put(Referable.IDSHORT, TechnicalProperties.IDSHORT); technicalMap.put(HasSemantics.SEMANTICID, TechnicalProperties.SEMANTICID); technicalMap.put(Property.VALUE, elements); } - + @Test public void testCreateAsFacade() { TechnicalProperties propFromMap = TechnicalProperties.createAsFacade(technicalMap); @@ -77,8 +92,8 @@ public void testCreateAsFacade() { assertEquals(Collections.singletonList(arbitrary1), propFromMap.getArbitrary()); assertEquals(Collections.singletonList(arbitrary2), propFromMap.getSMENotDescribedBySemanticId()); } - - @Test (expected = MetamodelConstructionException.class) + + @Test(expected = MetamodelConstructionException.class) public void testCreateAsFacadeExceptionIdShort() { technicalMap.remove(Referable.IDSHORT); TechnicalProperties.createAsFacade(technicalMap); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java index e065250e..b132e907 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/IBasyxConnectorFacade.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.coder.json; @@ -28,9 +43,9 @@ * should be VABMapProvider or stub */ public class IBasyxConnectorFacade implements IBaSyxConnector { - + JSONProvider provider; - + public IBasyxConnectorFacade(JSONProvider p) { provider = p; } @@ -43,7 +58,7 @@ public IBasyxConnectorFacade(JSONProvider p) { public String getValue(String path) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); provider.processBaSysGet(path, outputStream); - + try { return outputStream.toString(StandardCharsets.UTF_8.displayName()); } catch (UnsupportedEncodingException e) { @@ -59,7 +74,7 @@ public String getValue(String path) { public String setValue(String path, String newValue) throws ProviderException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); provider.processBaSysSet(path, newValue, outputStream); - + try { return outputStream.toString(StandardCharsets.UTF_8.displayName()); } catch (UnsupportedEncodingException e) { @@ -75,12 +90,12 @@ public String setValue(String path, String newValue) throws ProviderException { public String createValue(String path, String newEntity) throws ProviderException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); provider.processBaSysCreate(path, newEntity, outputStream); - + try { return outputStream.toString(StandardCharsets.UTF_8.displayName()); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Should not happen..."); - } + } } /** @@ -92,7 +107,7 @@ public String deleteValue(String path) throws ProviderException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); String nullParam = "null"; provider.processBaSysDelete(path, nullParam, outputStream); - + try { return outputStream.toString(StandardCharsets.UTF_8.displayName()); } catch (UnsupportedEncodingException e) { @@ -108,7 +123,7 @@ public String deleteValue(String path) throws ProviderException { public String deleteValue(String path, String obj) throws ProviderException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); provider.processBaSysDelete(path, obj, outputStream); - + try { return outputStream.toString(StandardCharsets.UTF_8.displayName()); } catch (UnsupportedEncodingException e) { @@ -124,7 +139,7 @@ public String deleteValue(String path, String obj) throws ProviderException { public String invokeOperation(String path, String jsonObject) throws ProviderException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); provider.processBaSysInvoke(path, jsonObject, outputStream); - + try { return outputStream.toString(StandardCharsets.UTF_8.displayName()); } catch (UnsupportedEncodingException e) { diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java index 392ba461..735a94e1 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/PrintWriterStub.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.coder.json; @@ -19,21 +34,21 @@ /** * PrintWriter stub that simulates response stream + * * @author pschorn * */ public class PrintWriterStub extends PrintWriter { - + private static Logger logger = LoggerFactory.getLogger(PrintWriterStub.class); - + private String acceptor; private String result; - - + public PrintWriterStub(String fileName, String acceptor) throws FileNotFoundException { super(fileName); // TODO Auto-generated constructor stub - + this.acceptor = acceptor; } @@ -41,20 +56,20 @@ public PrintWriterStub(String fileName, String acceptor) throws FileNotFoundExce public void write(String stream) { // check for logger.trace("[TEST] Writing to output: {}", stream); - + if (!acceptor.equals("ignore")) { assertTrue(acceptor.equals(stream)); } - + result = stream; } - + @Override public void flush() { // do nothing logger.trace("[TEST] Flushing.."); } - + public String getResult() { return result; } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java index f6ed4f9e..1a402f56 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJSONConnectorProviderIntegration.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.coder.json; @@ -27,29 +42,29 @@ */ public class TestJSONConnectorProviderIntegration extends TestProvider { - protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(), - new ConnectorFactory() { + protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() { - @Override - protected IModelProvider createProvider(String addr) { + @Override + protected IModelProvider createProvider(String addr) { - // BACKEND - // Creates a new VABMapProvider which manages a data model as defined in - // SimpleVABElement. - VABMapProvider modelprovider = new VABMapProvider(new SimpleVABElement()); + // BACKEND + // Creates a new VABMapProvider which manages a data model as defined in + // SimpleVABElement. + VABMapProvider modelprovider = new VABMapProvider(new SimpleVABElement()); - // We stack the JSONProvider on top of the model to handle serialization and exceptions - JSONProvider provider = new JSONProvider(modelprovider); + // We stack the JSONProvider on top of the model to handle serialization and + // exceptions + JSONProvider provider = new JSONProvider(modelprovider); - // FRONTEND - // We stack the JSONConnector on top of the JSONProvider to handle de-serialization and response - // verification - JSONConnector connector = new JSONConnector( - new IBasyxConnectorFacade(provider)); + // FRONTEND + // We stack the JSONConnector on top of the JSONProvider to handle + // de-serialization and response + // verification + JSONConnector connector = new JSONConnector(new IBasyxConnectorFacade(provider)); - return connector; - } - }); + return connector; + } + }); @Override protected VABConnectionManager getConnectionManager() { diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java index d1d4735e..610c929b 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/coder/json/TestJson.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.coder.json; @@ -22,7 +37,7 @@ import java.util.Base64; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -59,7 +74,7 @@ public void testDouble() { JsonPrimitive primitive = new JsonPrimitive(12.3); assertEquals(primitive.toString(), tools.serialize(12.3)); } - + /** * Tests if an integer is correctly (de-)serialized */ @@ -108,18 +123,17 @@ public void testString() { public void testMap() { String str = "{\"a\": { \"x\" : 123}, \"b\": \"123\"}"; - Map expected = new HashMap<>(); - Map a = new HashMap<>(); + Map expected = new LinkedHashMap<>(); + Map a = new LinkedHashMap<>(); a.put("x", 123); expected.put("a", a); expected.put("b", "123"); assertEquals(expected, tools.deserialize(str)); - - + JsonObject aObj = new JsonObject(); aObj.add("x", new JsonPrimitive(123)); - + JsonObject expectedObj = new JsonObject(); expectedObj.add("a", aObj); expectedObj.add("b", new JsonPrimitive("123")); @@ -135,12 +149,12 @@ public void testMap() { public void testMapWithCollection() { String str = "{\"a\": [1,2,3]}"; - Map listMap = new HashMap<>(); + Map listMap = new LinkedHashMap<>(); listMap.put("a", Arrays.asList(1, 2, 3)); - - Map setMap = new HashMap<>(); + + Map setMap = new LinkedHashMap<>(); setMap.put("a", Sets.newHashSet(1, 2, 3)); - + Map deserialized = (Map) tools.deserialize(str); Collection coll = (Collection) deserialized.get("a"); assertEquals(1, deserialized.size()); @@ -148,7 +162,7 @@ public void testMapWithCollection() { assertTrue(coll.contains(1)); assertTrue(coll.contains(2)); assertTrue(coll.contains(3)); - + deserialized = (Map) tools.deserialize(tools.serialize(listMap)); coll = (Collection) deserialized.get("a"); assertEquals(1, deserialized.size()); @@ -156,7 +170,7 @@ public void testMapWithCollection() { assertTrue(coll.contains(1)); assertTrue(coll.contains(2)); assertTrue(coll.contains(3)); - + deserialized = (Map) tools.deserialize(tools.serialize(setMap)); coll = (Collection) deserialized.get("a"); assertEquals(1, deserialized.size()); @@ -211,7 +225,7 @@ public void testEmptyList() { */ @Test public void testEmptyListInMap() { - Map map = new HashMap<>(); + Map map = new LinkedHashMap<>(); map.put("a", new ArrayList<>()); assertEquals(map, tools.deserialize(tools.serialize(map))); } @@ -226,17 +240,16 @@ public void testSet() { Set> unorderedSet = new HashSet<>(); unorderedSet.add(Collections.singletonMap("a", 4)); - - Collection> deserialized = (Collection>) tools - .deserialize(strComplexUnordered); + + Collection> deserialized = (Collection>) tools.deserialize(strComplexUnordered); assertEquals(1, deserialized.size()); assertEquals(4, deserialized.iterator().next().get("a")); - + JsonArray unorderedArray = new JsonArray(); JsonObject o1 = new JsonObject(); o1.add("a", new JsonPrimitive(4)); unorderedArray.add(o1); - + assertEquals(unorderedArray.toString(), tools.serialize(unorderedSet)); Set primitiveSet = new HashSet<>(); @@ -263,7 +276,7 @@ public void testEmptySet() { */ @Test public void testEmptySetInMap() { - Map map = new HashMap<>(); + Map map = new LinkedHashMap<>(); map.put("test", new ArrayList<>()); String result = tools.serialize(map); assertEquals("{\"test\":[]}", result); @@ -282,8 +295,7 @@ public void testNonSerializableFunction() { }; assertEquals(functionObject.toString(), tools.serialize(testConsumer)); - - + String operation = GSONTools.BASYXINVOCABLE; assertEquals(operation, tools.deserialize(functionObject.toString())); @@ -318,26 +330,26 @@ public void testSerializableFunction() throws IOException { assertEquals(testFunction.apply(5), deserialized.apply(5)); } - + /** - * Tests if null values and empty arrays are getting removed successfully - * with remove flag on + * Tests if null values and empty arrays are getting removed successfully with + * remove flag on * */ @Test public void testSerializeWithRemoveFlagsOn() throws IOException { GSONTools toolWithRemoveFlagOn = new GSONTools(new DefaultTypeFactory(), true, true); - Map expected = new HashMap<>(); - Map a = new HashMap<>(); + Map expected = new LinkedHashMap<>(); + Map a = new LinkedHashMap<>(); a.put("x", 123); expected.put("a", a); expected.put("b", "123"); expected.put("c", null); expected.put("d", new ArrayList()); - + JsonObject aObj = new JsonObject(); aObj.add("x", new JsonPrimitive(123)); - + JsonObject expectedObj = new JsonObject(); expectedObj.add("a", aObj); expectedObj.add("b", new JsonPrimitive("123")); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java index 9bc9f8d9..afbfe77d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/memory/TestInMemoryDirectory.java @@ -1,17 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.directory.memory; import static org.junit.Assert.assertEquals; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.testsuite.regression.vab.directory.proxy.TestDirectory; @@ -45,7 +60,7 @@ public void testAddMappingMultipleKey() { String value3 = "value3"; String key4 = "key4"; String value4 = "value4"; - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put(key3, value3); map.put(key4, value4); registry.addMappings(map); @@ -59,7 +74,7 @@ private void testElementsInMap(IVABRegistryService registry, Map } private Map getAddedValues() { - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put("key1", "value1"); map.put("key2", "value2"); return map; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java index 4589c535..60712ce7 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/proxy/TestDirectory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.directory.proxy; @@ -73,7 +88,6 @@ public void testGetSingleElement() { String result = registry.lookup(elem1); assertEquals(endpoint1, result); - // Retrieve and check the second AAS result = registry.lookup(elem2); assertEquals(endpoint2, result); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java index 5a26165b..1f44dd19 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/directory/restapi/TestDirectoryProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.directory.restapi; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java index 6249fa67..97641a9e 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestVABXmlProviderFactory.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.factory.xml; @@ -33,15 +48,12 @@ public void testResources() throws Exception { assertEquals(provider.getValue("tags/name/"), TestXmlParser.SOME_NAME); assertEquals(provider.getValue("tags/value/"), TestXmlParser.VALUEV); assertEquals(provider.getValue("tags/nestedTags/attrnt"), TestXmlParser.ATTRNT_1_VAL); - Iterator iterator = ((Collection) provider.getValue("tags/nestedTags/nestedTag/")) - .iterator(); + Iterator iterator = ((Collection) provider.getValue("tags/nestedTags/nestedTag/")).iterator(); assertEquals(TestXmlParser.NESTED_TAG_1, iterator.next()); assertEquals(TestXmlParser.NESTED_TAG_2, iterator.next()); assertEquals(TestXmlParser.NESTED_TAG_3, iterator.next()); - iterator = ((Collection) provider - .getValue("tags/deeplyNestedTagParent/deeplyNestedTagsChild/deeplyNestedTagsLeaf/")) - .iterator(); + iterator = ((Collection) provider.getValue("tags/deeplyNestedTagParent/deeplyNestedTagsChild/deeplyNestedTagsLeaf/")).iterator(); map = (Map) (iterator.next()); assertEquals(map.get(TestXmlParser.TEXT), TestXmlParser.DN_TEXT_1); assertEquals(map.get(TestXmlParser.ATTRDN), TestXmlParser.ATTR_1_VAL); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java index 5b59aac1..1f8bfe4a 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/factory/xml/TestXmlParser.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.factory.xml; @@ -15,7 +30,7 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -28,7 +43,7 @@ public class TestXmlParser { - private Map rootObj = new HashMap<>(); + private Map rootObj = new LinkedHashMap<>(); private static final String TAGS = "tags"; private static final String ATTR_1 = "attr_1"; @@ -92,10 +107,10 @@ public void TestBuildXmlMap() throws Exception { */ public void testContainsAllKeys() throws ParserConfigurationException, SAXException, IOException { - Map tags = new HashMap<>(); - Map nestedTags = new HashMap<>(); - Map deeplyNestedTagParent = new HashMap<>(); - Map deeplyNestedTagsChild = new HashMap<>(); + Map tags = new LinkedHashMap<>(); + Map nestedTags = new LinkedHashMap<>(); + Map deeplyNestedTagParent = new LinkedHashMap<>(); + Map deeplyNestedTagsChild = new LinkedHashMap<>(); List> deeplyNestedTagsLeaf = new ArrayList<>(); assertTrue(rootObj.containsKey(TAGS)); @@ -159,8 +174,8 @@ public void testRootNode() throws ParserConfigurationException, SAXException, IO */ public void testNestedElements() throws ParserConfigurationException, SAXException, IOException { - Map tags = new HashMap<>(); - Map nestedTags = new HashMap<>(); + Map tags = new LinkedHashMap<>(); + Map nestedTags = new LinkedHashMap<>(); List nestedTag = new ArrayList<>(); assertNotEquals(null, rootObj.get(TAGS)); @@ -189,9 +204,9 @@ public void testNestedElements() throws ParserConfigurationException, SAXExcepti */ public void testDeeplyNestedElements() throws ParserConfigurationException, SAXException, IOException { - Map tags = new HashMap<>(); - Map deeplyNestedTagParent = new HashMap<>(); - Map deeplyNestedTagsChild = new HashMap<>(); + Map tags = new LinkedHashMap<>(); + Map deeplyNestedTagParent = new LinkedHashMap<>(); + Map deeplyNestedTagsChild = new LinkedHashMap<>(); List> deeplyNestedTagsLeaf = new ArrayList<>(); assertNotEquals(null, rootObj.get(TAGS)); @@ -208,12 +223,12 @@ public void testDeeplyNestedElements() throws ParserConfigurationException, SAXE assertNotEquals(null, deeplyNestedTagsLeaf.get(1).get(TEXT)); assertNotEquals(null, deeplyNestedTagsLeaf.get(1).get(ATTRDN)); // Check the objects are created of desired types - assertTrue(rootObj instanceof HashMap); - assertTrue(rootObj.get(TAGS) instanceof HashMap); + assertTrue(rootObj instanceof LinkedHashMap); + assertTrue(rootObj.get(TAGS) instanceof LinkedHashMap); assertTrue(deeplyNestedTagsChild.get(DEEPLY_NESTED_LEAF) instanceof ArrayList); - assertTrue(deeplyNestedTagParent.get(DEEPLY_NESTED_TAGS_CHILD) instanceof HashMap); - assertTrue(tags.get(DEEPLY_NESTED_PARENT) instanceof HashMap); - assertTrue(tags instanceof HashMap); + assertTrue(deeplyNestedTagParent.get(DEEPLY_NESTED_TAGS_CHILD) instanceof LinkedHashMap); + assertTrue(tags.get(DEEPLY_NESTED_PARENT) instanceof LinkedHashMap); + assertTrue(tags instanceof LinkedHashMap); // Check the texts assertEquals(DN_TEXT_1, deeplyNestedTagsLeaf.get(0).get(TEXT)); assertEquals(ATTR_1_VAL, deeplyNestedTagsLeaf.get(0).get(ATTRDN)); @@ -234,7 +249,7 @@ public void testDeeplyNestedElements() throws ParserConfigurationException, SAXE */ public void testTextMulitpleTextNodeInParent() throws ParserConfigurationException, SAXException, IOException { - Map tags = new HashMap<>(); + Map tags = new LinkedHashMap<>(); List someTag = new ArrayList<>(); tags = (Map) rootObj.get(TAGS); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java index 1e48f777..71442114 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/ConnectorProviderStub.java @@ -1,15 +1,30 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.gateway; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; @@ -23,7 +38,7 @@ * */ public class ConnectorProviderStub implements IConnectorFactory { - private Map providerMap = new HashMap<>(); + private Map providerMap = new LinkedHashMap<>(); public void addMapping(String addr, IModelProvider provider) { providerMap.put(addr, provider); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java index 7dac3dfe..8804bb24 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestConnectorProviderMapper.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.gateway; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java index b7ca4f68..979aed65 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestDelegatingModelProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.gateway; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java index 4b70f989..11a60243 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/gateway/TestGateway.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.gateway; @@ -13,7 +28,7 @@ import java.io.IOException; import java.net.UnknownHostException; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper; @@ -46,7 +61,7 @@ public class TestGateway { @Before public void build() { // Create VAB element - Map vabElem = new HashMap(); + Map vabElem = new LinkedHashMap(); vabElem.put("propertyA", 10); // Provide it using VABMapProvider and a tcp server on port 6998 @@ -60,7 +75,7 @@ public void build() { // Create VAB element // Create tcp gateway using DelegatingModelProvider basyxGateway = new BaSyxTCPServer<>(new DelegatingModelProvider(gatewayMapper), 6999); - + // Create a http gateway using DelegatingModelProvider DelegatingModelProvider httpGWProvider = new DelegatingModelProvider(gatewayMapper); BaSyxContext context = new BaSyxContext("", "", "localhost", 5123); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java index 3af0ac5c..06f62ca3 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/manager/VABConnectionManagerStub.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.manager; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java index 9a3dc552..1359c2f9 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/model/VABModelMapTest.java @@ -1,18 +1,33 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.model.VABModelMap; @@ -35,16 +50,16 @@ public void testGetPath() { VABModelMap map = new VABModelMap<>(); map.putPath("a/b/c", 12); map.putPath("a/b/d", 13); - + // Build expected output - Map b = new HashMap<>(); + Map b = new LinkedHashMap<>(); b.put("c", 12); b.put("d", 13); - Map a = new HashMap<>(); + Map a = new LinkedHashMap<>(); a.put("b", b); - - Map root = new HashMap<>(); + + Map root = new LinkedHashMap<>(); root.put("a", a); // Assert correct behaviour of getPath @@ -59,7 +74,7 @@ public void testEquals() { expected.put("a", "b"); expected.put("x", "y"); - Map map = new HashMap<>(); + Map map = new LinkedHashMap<>(); map.put("a", "b"); map.put("x", "y"); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java index dba4bf82..1ebb8ddc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/Exceptions.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -15,7 +30,6 @@ import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; import org.eclipse.basyx.vab.coder.json.metaprotocol.Result; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; -import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.manager.VABConnectionManager; @@ -64,21 +78,5 @@ public static void testHandlingException(VABConnectionManager connManager) { Message msg = result.getMessages().get(0); assertEquals("400", msg.getCode()); } - - // Invoke unsupported functional interface - try { - connVABElement.invokeOperation("operations/supplier/invoke"); - fail(); - } catch (MalformedRequestException e) { - // this is for FileSystemProvider that does not support invoke - Result result = new Result(e); - Message msg = result.getMessages().get(0); - assertEquals("400", msg.getCode()); - } catch (ProviderException e) { - Result result = new Result(e); - Message msg = result.getMessages().get(0); - assertEquals("500", msg.getCode()); - } - } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java index 7abe93ab..60e0b4cc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/IModelProviderStub.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java index ee88b4d2..191c9004 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapCreateDelete.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -13,7 +28,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; @@ -29,7 +44,7 @@ * */ public class MapCreateDelete { - + public static void test(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); @@ -44,14 +59,14 @@ private static void testCreateElements(VABElementProxy connVABElement) { connVABElement.createValue("inRoot", 1.2); Object toTest = connVABElement.getValue("inRoot"); assertEquals(1.2, toTest); - + // Create element in Map (with new key contained in the path) connVABElement.createValue("/structure/map/inMap", "34"); toTest = connVABElement.getValue("/structure/map/inMap"); assertEquals("34", toTest); - + // Create map element - HashMap newMap = new HashMap<>(); + LinkedHashMap newMap = new LinkedHashMap<>(); newMap.put("entryA", 3); newMap.put("entryB", 4); connVABElement.createValue("mapInRoot", newMap); @@ -59,7 +74,7 @@ private static void testCreateElements(VABElementProxy connVABElement) { assertTrue(toTest instanceof Map); assertEquals(2, ((Map) toTest).size()); assertEquals(3, ((Map) toTest).get("entryA")); - + // Try to overwrite existing element (should throw Exception, already exists) try { connVABElement.createValue("inRoot", 0); @@ -70,35 +85,39 @@ private static void testCreateElements(VABElementProxy connVABElement) { } toTest = connVABElement.getValue("inRoot"); assertEquals(1.2, toTest); - + // Check case-sensitivity connVABElement.createValue("inroot", 78); toTest = connVABElement.getValue("inRoot"); assertEquals(1.2, toTest); toTest = connVABElement.getValue("inroot"); assertEquals(78, toTest); - + // Non-existing parent element try { connVABElement.createValue("unkown/x", 5); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } try { connVABElement.getValue("unknown/x"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Empty paths - at "" is a Map. Therefore create should throw an Exception try { connVABElement.createValue("", ""); fail(); - } catch (ResourceAlreadyExistsException e) {} - + } catch (ResourceAlreadyExistsException e) { + } + // Null path - should throw exception try { connVABElement.createValue(null, ""); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } private static void testDeleteElements(VABElementProxy connVABElement) { @@ -111,15 +130,16 @@ private static void testDeleteElements(VABElementProxy connVABElement) { } Object toTest = connVABElement.getValue("inRoot"); assertEquals(1.2, toTest); - + // - by index connVABElement.deleteValue("inRoot"); try { // "inRoot" should not exist anymore connVABElement.getValue("inRoot"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Check case-sensitivity toTest = connVABElement.getValue("inroot"); assertEquals(78, toTest); @@ -128,31 +148,34 @@ private static void testDeleteElements(VABElementProxy connVABElement) { // "inroot" should not exist anymore connVABElement.getValue("inroot"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Delete at Map - // - by object - should not work in maps, because object refers to a contained object, not the index + // - by object - should not work in maps, because object refers to a contained + // object, not the index try { connVABElement.deleteValue("/structure/map/", "inMap"); fail(); } catch (MalformedRequestException e) { } - + toTest = connVABElement.getValue("/structure/map/inMap"); assertEquals("34", toTest); // - by index connVABElement.deleteValue("/structure/map/inMap"); toTest = connVABElement.getValue("/structure/map"); assertEquals(0, ((Map) toTest).size()); - + // Delete remaining complete Map connVABElement.deleteValue("mapInRoot"); try { // "mapInRoot" should not exist anymore connVABElement.getValue("mapInRoot"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Empty paths - should not delete anything and throw Exception try { connVABElement.deleteValue("", ""); @@ -164,15 +187,17 @@ private static void testDeleteElements(VABElementProxy connVABElement) { } toTest = connVABElement.getValue("/primitives/integer"); assertEquals(123, toTest); - + // Null path - should throw exception try { connVABElement.deleteValue(null, ""); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } try { connVABElement.deleteValue(null); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java index a84f32f2..288ba165 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapInvoke.java @@ -1,15 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; @@ -26,34 +43,62 @@ * */ public class MapInvoke { - + public static void test(VABConnectionManager connManager) { - // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - - // Invoke complex function + + invokeComplexObjectReturningFunction(connVABElement); + + invokeSupportedFunctionalInterfaces(connVABElement); + + invokeNonexistantPath(connVABElement); + + invokeInvalidPath(connVABElement); + + invokeExceptionFunction(connVABElement); + + invokeNullPointerExceptionFunction(connVABElement); + + invokeEmptyPathException(connVABElement); + + invokeNullPathException(connVABElement); + } + + private static void invokeComplexObjectReturningFunction(VABElementProxy connVABElement) throws ProviderException { Object complex = connVABElement.invokeOperation("operations/complex/", 12, 34); assertEquals(46, complex); - - // Invoke unsupported functional interface - try { - connVABElement.invokeOperation("operations/supplier/" + Operation.INVOKE); - fail(); - } catch (ProviderException e) {} - - // Invoke non-existing operation + } + + private static void invokeSupportedFunctionalInterfaces(VABElementProxy connVABElement) { + boolean result = (boolean) connVABElement.invokeOperation("operations/supplier/" + Operation.INVOKE); + assertTrue(result); + + Object[] toConsume = { 10 }; + connVABElement.invokeOperation("operations/consumer/" + Operation.INVOKE, toConsume); + Object[] consumed = (Object[]) SimpleVABElement.getAndResetConsumed(); + assertArrayEquals(toConsume, consumed); + + connVABElement.invokeOperation("operations/runnable/" + Operation.INVOKE); + assertTrue(SimpleVABElement.getAndResetRunnableRan()); + } + + private static void invokeNonexistantPath(VABElementProxy connVABElement) throws ProviderException { try { connVABElement.invokeOperation("operations/unknown/" + Operation.INVOKE); fail(); - } catch (ResourceNotFoundException e) {} - - // Invoke invalid operation -> not a function, but a primitive data type + } catch (ResourceNotFoundException e) { + } + } + + private static void invokeInvalidPath(VABElementProxy connVABElement) { try { connVABElement.invokeOperation("operations/invalid/" + Operation.INVOKE); fail(); - } catch (ProviderException e) {} - - // Invoke operations that throw Exceptions + } catch (ProviderException e) { + } + } + + private static void invokeExceptionFunction(VABElementProxy connVABElement) { try { connVABElement.invokeOperation("operations/providerException/" + Operation.INVOKE); fail(); @@ -61,7 +106,9 @@ public static void test(VABConnectionManager connManager) { // exception type not implemented, yet // assertEquals(e.getType(), "testExceptionType"); } - + } + + private static void invokeNullPointerExceptionFunction(VABElementProxy connVABElement) { try { connVABElement.invokeOperation("operations/nullException/" + Operation.INVOKE); fail(); @@ -69,18 +116,22 @@ public static void test(VABConnectionManager connManager) { // exception type not implemented, yet // assertEquals(e.getType(), "java.lang.NullPointerException"); } - - // Empty paths - should execute, but has no effect + } + + private static void invokeEmptyPathException(VABElementProxy connVABElement) { try { connVABElement.invokeOperation("", ""); fail(); - } catch (ProviderException e) {} - - - // Null path - should throw exception + } catch (ProviderException e) { + } + } + + private static void invokeNullPathException(VABElementProxy connVABElement) throws ProviderException { try { connVABElement.invokeOperation(null, ""); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } + } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java index 75233722..c5397abb 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapRead.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -28,12 +43,12 @@ * */ public class MapRead { - + @SuppressWarnings("unchecked") public static void test(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - + // Test path access Object slashA = connVABElement.getValue("/primitives/integer"); Object slashB = connVABElement.getValue("primitives/integer/"); @@ -43,7 +58,7 @@ public static void test(VABConnectionManager connManager) { assertEquals(slashB, 123); assertEquals(slashC, 123); assertEquals(slashD, 123); - + // Test reading different data types Object map = connVABElement.getValue("primitives"); Object doubleValue = connVABElement.getValue("primitives/double"); @@ -51,51 +66,55 @@ public static void test(VABConnectionManager connManager) { assertEquals(3, ((Map) map).size()); assertEquals(3.14d, doubleValue); assertEquals("TestValue", string); - + // Test case sensitivity Object caseSensitiveA = connVABElement.getValue("special/casesensitivity"); Object caseSensitiveB = connVABElement.getValue("special/caseSensitivity"); assertEquals(true, caseSensitiveA); assertEquals(false, caseSensitiveB); - + // Test reading null value Object nullValue = connVABElement.getValue("special/null"); assertNull(nullValue); - + // Test reading serializable functions Object serializableFunction = connVABElement.getValue("operations/serializable"); Function testFunction = (Function) serializableFunction; assertEquals(3, testFunction.apply(new Object[] { 1, 2 })); - + // Non-existing parent element try { connVABElement.getValue("unknown/x"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Non-existing target element try { connVABElement.getValue("primitives/unkown"); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } try { connVABElement.getValue("unkown"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Nested access assertEquals(100, connVABElement.getValue("special/nested/nested/value")); - + // Empty path Object rootValueA = connVABElement.getValue(""); Object rootValueB = connVABElement.getValue("/"); assertEquals(4, ((Map) rootValueA).size()); assertEquals(4, ((Map) rootValueB).size()); - + // Null path - should throw exception try { connVABElement.getValue(null); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java index b3b36df9..b2010d5d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/MapUpdate.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -14,7 +29,7 @@ import static org.junit.Assert.fail; import java.io.Serializable; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.function.Function; import org.eclipse.basyx.vab.exception.provider.MalformedRequestException; @@ -29,12 +44,12 @@ * */ public class MapUpdate { - + @SuppressWarnings("unchecked") public static void test(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - + // Set primitives connVABElement.setValue("primitives/integer", 12); connVABElement.setValue("primitives/double", 1.2d); @@ -54,43 +69,45 @@ public static void test(VABConnectionManager connManager) { connVABElement.setValue("primitives/integer", 123); connVABElement.setValue("primitives/double", 3.14d); connVABElement.setValue("primitives/string", "TestValue"); - + // Update serializable function - connVABElement.setValue("operations/serializable", - (Function & Serializable) (param) -> { - return (int) param[0] - (int) param[1]; - }); + connVABElement.setValue("operations/serializable", (Function & Serializable) (param) -> { + return (int) param[0] - (int) param[1]; + }); // Read back Object serializableFunction = connVABElement.getValue("operations/serializable"); // Test Function testFunction = (Function) serializableFunction; assertEquals(-1, testFunction.apply(new Object[] { 2, 3 })); // Revert - connVABElement.setValue("operations/serializable", - (Function & Serializable) (param) -> { - return (int) param[0] + (int) param[1]; - }); - + connVABElement.setValue("operations/serializable", (Function & Serializable) (param) -> { + return (int) param[0] + (int) param[1]; + }); + // Test non-existing parent element try { connVABElement.createValue("unkown/newElement", 5); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } try { connVABElement.getValue("unknown/newElement"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Test updating a non-existing element try { connVABElement.setValue("newElement", 10); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } try { connVABElement.getValue("newElement"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Test updating an existing null-element connVABElement.setValue("special/null", true); Object bool = connVABElement.getValue("special/null"); @@ -100,26 +117,28 @@ public static void test(VABConnectionManager connManager) { try { connVABElement.setValue(null, ""); fail(); - } catch (MalformedRequestException e) {} + } catch (MalformedRequestException e) { + } } public static void testPushAll(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - + // Push whole map via null-Path - should throw exception // - create object - HashMap newMap = new HashMap<>(); + LinkedHashMap newMap = new LinkedHashMap<>(); newMap.put("testKey", "testValue"); // - push try { connVABElement.setValue(null, newMap); fail(); - } catch (MalformedRequestException e) {} - + } catch (MalformedRequestException e) { + } + // Push whole map via ""-Path // - create object - HashMap newMap2 = new HashMap<>(); + LinkedHashMap newMap2 = new LinkedHashMap<>(); newMap2.put("testKey2", "testValue2"); // - push connVABElement.setValue("", newMap2); @@ -128,10 +147,12 @@ public static void testPushAll(VABConnectionManager connManager) { try { connVABElement.getValue("testKey"); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } try { connVABElement.getValue("primitives/integer"); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java index 8087a69d..f3defacb 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/SimpleVABElement.java @@ -1,18 +1,35 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; import java.io.Serializable; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.HashSet; +import java.util.Map; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -24,31 +41,99 @@ * @author kuhn, espen * */ -public class SimpleVABElement extends HashMap { +public class SimpleVABElement extends LinkedHashMap { + public static final String EXCEPTION_MESSAGE = "Exception description"; + private static final long serialVersionUID = 3942399852711325850L; + private static Object consumed; + + public static Object getAndResetConsumed() { + Object tmp = consumed; + consumed = null; + return tmp; + } + + private static boolean runnableRan = false; + + public static boolean getAndResetRunnableRan() { + boolean tmp = runnableRan; + runnableRan = false; + return tmp; + } + /** * Constructor for a simple VAB element that contains all data types */ public SimpleVABElement() { - // Add primitive types - HashMap primitives = new HashMap<>(); - primitives.put("integer", 123); - primitives.put("double", 3.14d); - primitives.put("string", "TestValue"); + Map primitives = createPrimitiveTypes(); put("primitives", primitives); - // Add function types - HashMap functions = new HashMap<>(); + Map functions = createFunctions(); + put("operations", functions); + + Map structure = createStructureTypes(); + put("structure", structure); + + Map special = new LinkedHashMap<>(); + special.putAll(createCaseSensitiveEntries()); + + Map nestedA = createNestedMap(); + special.put("nested", nestedA); + + special.put("null", null); + + put("special", special); + } + + private Map createNestedMap() { + Map nestedA = new LinkedHashMap<>(); + Map nestedB = new LinkedHashMap<>(); + nestedA.put("nested", nestedB); + nestedB.put("value", 100); + return nestedA; + } + + private Map createCaseSensitiveEntries() { + Map caseSensitive = new LinkedHashMap<>(); + caseSensitive.put("casesensitivity", true); + caseSensitive.put("caseSensitivity", false); + return caseSensitive; + } + + private Map createStructureTypes() { + Map structure = new LinkedHashMap<>(); + structure.put("map", new LinkedHashMap()); + structure.put("set", new HashSet()); + structure.put("list", new ArrayList()); + return structure; + } + + private Map createFunctions() { + Map functions = new LinkedHashMap<>(); functions.put("supplier", (Supplier) () -> { return true; }); + + functions.put("consumer", (Consumer) (o) -> { + consumed = o; + }); + + functions.put("runnable", new Runnable() { + + @Override + public void run() { + runnableRan = true; + } + }); + functions.put("providerException", (Function) (param) -> { - throw new ProviderException("Exception description"); + throw new ProviderException(EXCEPTION_MESSAGE); }); functions.put("nullException", (Function) (param) -> { throw new NullPointerException(); }); + functions.put("complex", (Function) (param) -> { return (int) param[0] + (int) param[1]; }); @@ -59,25 +144,14 @@ public SimpleVABElement() { functions.put("invokable", (Function) (param) -> { return true; }); - put("operations", functions); - - // Add structure types - HashMap structure = new HashMap<>(); - structure.put("map", new HashMap()); - structure.put("set", new HashSet()); - structure.put("list", new ArrayList()); - put("structure", structure); + return functions; + } - // Add corner cases - HashMap special = new HashMap<>(); - special.put("casesensitivity", true); - special.put("caseSensitivity", false); - HashMap nestedA = new HashMap<>(); - HashMap nestedB = new HashMap<>(); - nestedA.put("nested", nestedB); - nestedB.put("value", 100); - special.put("nested", nestedA); - special.put("null", null); - put("special", special); + private Map createPrimitiveTypes() { + Map primitives = new LinkedHashMap<>(); + primitives.put("integer", 123); + primitives.put("double", 3.14d); + primitives.put("string", "TestValue"); + return primitives; } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java index eb440119..e0d0517d 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestCollectionProperty.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -29,16 +44,16 @@ * @author schnicke, espen */ public class TestCollectionProperty { - + @SuppressWarnings("unchecked") public static void testRead(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - + // Adding elements to tested list connVABElement.createValue("/structure/list/", 5); connVABElement.createValue("/structure/list/", 12); - + // Test reading whole lists Collection collection = (Collection) connVABElement.getValue("/structure/list/"); Iterator iterator = collection.iterator(); @@ -50,8 +65,9 @@ public static void testRead(VABConnectionManager connManager) { try { connVABElement.getValue("/structure/list/0"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Delete remaining entries connVABElement.deleteValue("/structure/list", 5); connVABElement.deleteValue("/structure/list", 12); @@ -61,20 +77,20 @@ public static void testRead(VABConnectionManager connManager) { public static void testUpdate(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - + // Read original collection Collection original = (Collection) connVABElement.getValue("/structure/list/"); - + // Replace complete value of the collection property Collection replacement = new ArrayList<>(); replacement.add(100); replacement.add(200); replacement.add(300); connVABElement.setValue("/structure/list/", replacement); - + // Read values back Collection collection = (Collection) connVABElement.getValue("/structure/list/"); - + // Check test case results assertEquals(3, collection.size()); assertEquals(replacement, collection); @@ -85,7 +101,7 @@ public static void testUpdate(VABConnectionManager connManager) { fail(); } catch (ResourceNotFoundException e) { } - + // Write original back connVABElement.setValue("/structure/list/", original); } @@ -93,36 +109,37 @@ public static void testUpdate(VABConnectionManager connManager) { public static void testCreateDelete(VABConnectionManager connManager) { // Connect to VAB element with ID "urn:fhg:es.iese:vab:1:1:simplevabelement" VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); - + // Create element in Set (no key provided) connVABElement.createValue("/structure/set/", true); Object toTest = connVABElement.getValue("/structure/set/"); assertTrue(((Collection) toTest).contains(true)); - + // Delete at Set // - by index - should not work in sets, as they do not have an ordering try { connVABElement.deleteValue("/structure/set/0/"); fail(); - } catch (ResourceNotFoundException e) {} + } catch (ResourceNotFoundException e) { + } toTest = connVABElement.getValue("/structure/set/"); assertEquals(1, ((Collection) toTest).size()); // - by object connVABElement.deleteValue("/structure/set/", true); toTest = connVABElement.getValue("/structure/set/"); assertEquals(0, ((Collection) toTest).size()); - + // Create elements in List (no key provided) connVABElement.createValue("/structure/list/", 56); toTest = connVABElement.getValue("/structure/list/"); assertTrue(((List) toTest).contains(56)); - + // Delete at List // by object connVABElement.deleteValue("/structure/list/", 56); toTest = connVABElement.getValue("/structure/list/"); assertEquals(0, ((List) toTest).size()); - + // Create a list element connVABElement.createValue("listInRoot", Arrays.asList(1, 1, 2, 3, 5)); // Test whole list @@ -130,14 +147,15 @@ public static void testCreateDelete(VABConnectionManager connManager) { assertTrue(toTest instanceof List); assertEquals(5, ((List) toTest).size()); assertEquals(2, ((List) toTest).get(2)); - + // Delete whole list connVABElement.deleteValue("listInRoot"); try { connVABElement.getValue("listInRoot"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + // Delete at List // - referring to new list: [10, 20, 40, 80] connVABElement.createValue("/structure/list/", 10); @@ -145,15 +163,17 @@ public static void testCreateDelete(VABConnectionManager connManager) { connVABElement.createValue("/structure/list/", 40); connVABElement.createValue("/structure/list/", 80); // - by index - is not possible, as list access is only allowed using references - // - in contrast to indices, references always point to the same object in the list + // - in contrast to indices, references always point to the same object in the + // list try { connVABElement.deleteValue("/structure/list/3"); fail(); - } catch (ResourceNotFoundException e) {} - + } catch (ResourceNotFoundException e) { + } + toTest = connVABElement.getValue("/structure/list/"); assertEquals(4, ((List) toTest).size()); - + // Delete half of the elements connVABElement.deleteValue("/structure/list/", 10); connVABElement.deleteValue("/structure/list/", 40); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java index 071ee1f1..0797bfdb 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/TestProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -13,8 +28,9 @@ import org.junit.Test; /** - * Abstract test suite for testing CRUD-operations for different types of model providers. - * The concrete test cases implement concrete VABConnectionManagers that are tested + * Abstract test suite for testing CRUD-operations for different types of model + * providers. The concrete test cases implement concrete VABConnectionManagers + * that are tested * * @author espen * diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java index 4c4dd267..dc3f6239 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABElementProxyTest.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java index 33d28421..79653173 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider; @@ -178,10 +193,8 @@ public void testAppend() { @Test public void testIsOperationPath() { - String[] positive = { "submodelElements/id/invoke", "submodelElements/id/invoke/", - "operations/id/invoke", "operations/id/invoke/", "operations/test", "elem/operations/id" }; - String[] negative = { "", "/submodelElementsX/", "/myoperations/", "/submodelElementsFake/", - "/submodelElementsFake/operationX/", "submodelElements/id/" }; + String[] positive = { "submodelElements/id/invoke", "submodelElements/id/invoke/", "operations/id/invoke", "operations/id/invoke/", "operations/test", "elem/operations/id" }; + String[] negative = { "", "/submodelElementsX/", "/myoperations/", "/submodelElementsFake/", "/submodelElementsFake/operationX/", "submodelElements/id/" }; for (String test : positive) { assertTrue(test, VABPathTools.isOperationInvokationPath(test)); } @@ -190,7 +203,7 @@ public void testIsOperationPath() { } assertFalse(VABPathTools.isOperationInvokationPath(null)); } - + @Test public void testStripInvokeFromPath() { assertEquals("id", VABPathTools.stripInvokeFromPath("id/invoke")); @@ -199,14 +212,23 @@ public void testStripInvokeFromPath() { assertEquals("id/value", VABPathTools.stripInvokeFromPath("id/value")); assertEquals("", VABPathTools.stripInvokeFromPath("")); } - + + @Test + public void testStripFromPath() { + assertEquals("id", VABPathTools.stripFromPath("id/invoke", "invoke")); + assertEquals("", VABPathTools.stripFromPath("invoke", "invoke")); + assertEquals("", VABPathTools.stripFromPath("/invoke", "invoke")); + assertEquals("id/value", VABPathTools.stripFromPath("id/value", "invoke")); + assertEquals("id", VABPathTools.stripFromPath("id/value", "value")); + assertEquals("", VABPathTools.stripFromPath("", "")); + } + @Test public void testGetPathFromURL() { - - String[] urls = {"http://localhost:8080/test/elem.aasx", "http://localhost/test/elem.aasx", - "basyx://127.0.0.1:4000//http://localhost:8080/test/elem.aasx", "/test/elem.aasx", "test/elem.aasx"}; - - for(String url: urls) { + + String[] urls = { "http://localhost:8080/test/elem.aasx", "http://localhost/test/elem.aasx", "basyx://127.0.0.1:4000//http://localhost:8080/test/elem.aasx", "/test/elem.aasx", "test/elem.aasx" }; + + for (String url : urls) { assertEquals("/test/elem.aasx", VABPathTools.getPathFromURL(url)); } } @@ -214,10 +236,7 @@ public void testGetPathFromURL() { @Test public void testHarmonizePathWithSuffix() { String expected = "http://localhost:8080/server/subserver/suffix"; - String[] toTest = { expected, - "http://localhost:8080/server/subserver/suffix/", - "http://localhost:8080/server/subserver/", - "http://localhost:8080/server/subserver", }; + String[] toTest = { expected, "http://localhost:8080/server/subserver/suffix/", "http://localhost:8080/server/subserver/", "http://localhost:8080/server/subserver", }; for (String t : toTest) { String harmonized = VABPathTools.harmonizePathWithSuffix(t, "suffix"); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java index bf720950..63a436ea 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/filesystem/TestFileSystemProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider.filesystem; @@ -29,9 +44,9 @@ * */ public class TestFileSystemProvider extends TestProvider { - + private static Logger logger = LoggerFactory.getLogger(TestFileSystemProvider.class); - + private VABConnectionManager connManager; @Override diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java index 846b0c61..58d207bf 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/lambda/TestLambdaProvider.java @@ -1,17 +1,32 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider.lambda; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -38,20 +53,19 @@ public class TestLambdaProvider extends TestProvider { private static double doubleElement = 3.14d; private static Collection collectionElement = new ArrayList<>(); private static Map rootAccessor; - private static HashMap rootElement = new SimpleVABElement(); + private static LinkedHashMap rootElement = new SimpleVABElement(); @SuppressWarnings("unchecked") - private static HashMap structureElement = (HashMap) rootElement.get("structure"); + private static LinkedHashMap structureElement = (LinkedHashMap) rootElement.get("structure"); @SuppressWarnings("unchecked") - private static HashMap mapElement = (HashMap) structureElement.get("map"); + private static LinkedHashMap mapElement = (LinkedHashMap) structureElement.get("map"); - protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(), - new ConnectorFactory() { + protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(), new ConnectorFactory() { - @Override - protected IModelProvider createProvider(String addr) { - return buildProvider(); - } - }); + @Override + protected IModelProvider createProvider(String addr) { + return buildProvider(); + } + }); @Override protected VABConnectionManager getConnectionManager() { @@ -61,12 +75,14 @@ protected VABConnectionManager getConnectionManager() { @SuppressWarnings("unchecked") private static IModelProvider buildProvider() { // Create primitive lambda elements - HashMap primitives = (HashMap) rootElement.get("primitives"); - // Has no hidden setter (==null), so value should be completely replaced when set + LinkedHashMap primitives = (LinkedHashMap) rootElement.get("primitives"); + // Has no hidden setter (==null), so value should be completely replaced when + // set primitives.put("integer", VABLambdaProviderHelper.createSimple((Supplier) () -> { return 123; }, null)); - // Has a hidden setter, so write access to this element changes "doubleElement", which is returned by the getter + // Has a hidden setter, so write access to this element changes "doubleElement", + // which is returned by the getter primitives.put("double", VABLambdaProviderHelper.createSimple((Supplier) () -> { return doubleElement; }, (Consumer) (newObject) -> { @@ -74,7 +90,7 @@ private static IModelProvider buildProvider() { })); // Create collection lambda element - HashMap collections = (HashMap) rootElement.get("structure"); + LinkedHashMap collections = (LinkedHashMap) rootElement.get("structure"); Map collectionAccessor = VABLambdaProviderHelper.createCollection((Supplier) () -> { return collectionElement; }, (Consumer>) (collection) -> { @@ -91,7 +107,7 @@ private static IModelProvider buildProvider() { rootAccessor = VABLambdaProviderHelper.createMap((Supplier) () -> { return rootElement; }, (Consumer>) (map) -> { - rootElement = (HashMap) map; + rootElement = (LinkedHashMap) map; }, (BiConsumer) (key, value) -> { rootElement.put(key, value); }, (Consumer) (o) -> { @@ -99,11 +115,12 @@ private static IModelProvider buildProvider() { rootElement.remove(key); }); - // Create first accessor for structure/map element (-> test nested lambda properties) + // Create first accessor for structure/map element (-> test nested lambda + // properties) Map structureAccessor = VABLambdaProviderHelper.createMap((Supplier) () -> { return structureElement; }, (Consumer>) (map) -> { - structureElement = (HashMap) map; + structureElement = (LinkedHashMap) map; }, (BiConsumer) (key, value) -> { structureElement.put(key, value); }, (Consumer) (o) -> { @@ -112,11 +129,12 @@ private static IModelProvider buildProvider() { }); // Replace actual structure property with lambda accessor rootElement.put("structure", structureAccessor); - // Create second accessor for structure/map element (-> nested lambda properties) + // Create second accessor for structure/map element (-> nested lambda + // properties) Map mapAccessor = VABLambdaProviderHelper.createMap((Supplier) () -> { return mapElement; }, (Consumer>) (map) -> { - mapElement = (HashMap) map; + mapElement = (LinkedHashMap) map; }, (BiConsumer) (key, value) -> { mapElement.put(key, value); }, (Consumer) (o) -> { diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java index 65210f6b..67dc8511 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/map/TestMapProvider.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.modelprovider.map; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java index 1cac05a1..c021bc22 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestVABBaSyxTCP.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx; @@ -30,8 +45,7 @@ * */ public class TestVABBaSyxTCP extends TestProvider { - protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory_BaSyxNative(), - new BaSyxConnectorFactory()); + protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory_BaSyxNative(), new BaSyxConnectorFactory()); @Rule public VABTCPServerResource res = new VABTCPServerResource(new VABMapProvider(new SimpleVABElement())); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java index 61776a29..ab74a1de 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/TestsuiteDirectory_BaSyxNative.java @@ -1,33 +1,45 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx; import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry; - - - /** - * Implement the test suite directory service with pre-configured directory entries + * Implement the test suite directory service with pre-configured directory + * entries * * @author kuhn * */ public class TestsuiteDirectory_BaSyxNative extends VABInMemoryRegistry { - /** * Constructor - load all directory entries */ public TestsuiteDirectory_BaSyxNative() { // VAB Element mapping addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement", "basyx://localhost:6998"); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java index 1d04e72f..9b5aae71 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/basyx/VABTCPServerResource.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.basyx; @@ -14,8 +29,9 @@ import org.junit.rules.ExternalResource; /** - * This class initializes a TCP Server and adds a provider to it. Note that this server can only provide one - * model per port and new servers have to be started for each model. + * This class initializes a TCP Server and adds a provider to it. Note that this + * server can only provide one model per port and new servers have to be started + * for each model. * * @author pschorn, espen * diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java index 9f68f61a..9aa69ada 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/AASHTTPServerResource.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.http; @@ -14,7 +29,8 @@ import org.junit.rules.ExternalResource; /** - * This class initializes Tomcat server and required servlets for all HTTP test classes in this project. + * This class initializes Tomcat server and required servlets for all HTTP test + * classes in this project. * * @author espen * @@ -28,22 +44,22 @@ public class AASHTTPServerResource extends ExternalResource { */ public AASHTTPServerResource(BaSyxContext context) { this.context = context; - } + } /** * Create a new AASHTTPServer before a test case runs */ @Override - protected void before() { - server = new BaSyxHTTPServer(context); + protected void before() { + server = new BaSyxHTTPServer(context); server.start(); - } + } /** * Shutdown the created server after a test case */ @Override - protected void after() { + protected void after() { server.shutdown(); - } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java index 4cda615f..b0aea974 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/SimpleVABElementServlet.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.http; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java index 6a1dc455..3bb741ce 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestVABHTTP.java @@ -1,17 +1,36 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.http; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import java.util.HashMap; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.LinkedHashMap; import java.util.List; import javax.ws.rs.client.Client; @@ -20,14 +39,21 @@ import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; +import org.apache.http.client.ClientProtocolException; +import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation; +import org.eclipse.basyx.testsuite.regression.vab.modelprovider.SimpleVABElement; import org.eclipse.basyx.testsuite.regression.vab.modelprovider.TestProvider; import org.eclipse.basyx.testsuite.regression.vab.support.RecordingProvider; +import org.eclipse.basyx.vab.coder.json.metaprotocol.Message; +import org.eclipse.basyx.vab.exception.provider.ProviderException; import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException; import org.eclipse.basyx.vab.manager.VABConnectionManager; +import org.eclipse.basyx.vab.modelprovider.VABElementProxy; import org.eclipse.basyx.vab.modelprovider.VABPathTools; import org.eclipse.basyx.vab.modelprovider.api.IModelProvider; import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory; +import org.eclipse.basyx.vab.protocol.http.helper.HTTPUploadHelper; import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext; import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface; import org.junit.Rule; @@ -40,19 +66,21 @@ * */ public class TestVABHTTP extends TestProvider { - protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(), - new HTTPConnectorFactory()); + public static final String AASX_PATH = "src/test/resources/aas/factory/aasx/01_Festo.aasx"; + + private static final String RECORDER_URL = "http://localhost:8080/basys.sdk/Testsuite/Recorder/"; + private static final String SIMPLE_VAB_URL = "http://localhost:8080/basys.sdk/Testsuite/SimpleVAB"; - private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new HashMap<>())); + protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory(), new HTTPConnectorFactory()); + + private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new LinkedHashMap<>())); /** * Makes sure Tomcat Server is started after before each test case */ @Rule - public AASHTTPServerResource res = new AASHTTPServerResource( - new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")) - .addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet()) - .addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface(recorder))); + public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")).addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet()) + .addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface(recorder))); @Override protected VABConnectionManager getConnectionManager() { @@ -67,12 +95,12 @@ protected VABConnectionManager getConnectionManager() { */ @Test public void testRootURL() { - performRequest("http://localhost:8080/basys.sdk/Testsuite/SimpleVAB"); + performRequest(SIMPLE_VAB_URL); } /** - * Tests, if the provider throws a ResourceNotFoundException, if the HTTP endpoint - * could not be reached + * Tests, if the provider throws a ResourceNotFoundException, if the HTTP + * endpoint could not be reached */ @Test(expected = ResourceNotFoundException.class) public void testResourceNotFound() { @@ -90,8 +118,7 @@ public void testParameters() { String parameterRequest = "test?a=1,2&b=3,4"; - performRequestNoException("http://localhost:8080/basys.sdk/Testsuite/Recorder/" + parameterRequest); - + performRequestNoException(RECORDER_URL + parameterRequest); List paths = recorder.getPaths(); assertEquals(1, paths.size()); @@ -107,7 +134,7 @@ public void testNoParameters() { String parameterRequest = "test"; - performRequestNoException("http://localhost:8080/basys.sdk/Testsuite/Recorder/" + parameterRequest); + performRequestNoException(RECORDER_URL + parameterRequest); List paths = recorder.getPaths(); @@ -115,6 +142,49 @@ public void testNoParameters() { assertEquals(parameterRequest, VABPathTools.stripSlashes(paths.get(0))); } + @Test + public void testUpload() throws ClientProtocolException, IOException { + String parameterRequest = "aasx"; + String uploadURL = RECORDER_URL + parameterRequest; + String strToSend = "1"; + HTTPUploadHelper.uploadHTTPPost(new ByteArrayInputStream(strToSend.getBytes()), uploadURL); + + List paths = recorder.getPaths(); + assertEquals(1, paths.size()); + assertEquals(parameterRequest, VABPathTools.stripSlashes(paths.get(0))); + + Object retStr = recorder.getValue(parameterRequest); + assertEquals(strToSend, retStr); + } + + @Test + public void invokeExceptionFunction() { + VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); + try { + connVABElement.invokeOperation("operations/providerException/" + Operation.INVOKE); + fail(); + } catch (ProviderException e) { + List msg = e.getMessages(); + assertEquals(2, msg.size()); + String msgText = msg.get(1).getText(); + assertTrue(msgText.contains("ProviderException: " + SimpleVABElement.EXCEPTION_MESSAGE)); + } + } + + @Test + public void invokeNullPointerExceptionFunction() { + VABElementProxy connVABElement = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); + try { + connVABElement.invokeOperation("operations/nullException/" + Operation.INVOKE); + fail(); + } catch (ProviderException e) { + List msg = e.getMessages(); + assertEquals(2, msg.size()); + String msgText = msg.get(1).getText(); + assertTrue(msgText.contains("ProviderException: " + NullPointerException.class.getName())); + } + } + /** * Performs an HTTP request on an URL * @@ -123,7 +193,6 @@ public void testNoParameters() { private void performRequest(String URL) { Client client = ClientBuilder.newClient(); - // Called URL WebTarget resource = client.target(URL); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java index 4ebc0d7a..4d0ff6f6 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/http/TestsuiteDirectory.java @@ -1,48 +1,62 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.http; import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry; - - - /** - * Implement the test suite directory service with pre-configured directory entries + * Implement the test suite directory service with pre-configured directory + * entries * * @author kuhn * */ public class TestsuiteDirectory extends VABInMemoryRegistry { - + /** * Constructor - load all directory entries */ public TestsuiteDirectory() { this("http"); } - + /** - * Constructor - load all directory entries with link - * protocol defined in the parameter + * Constructor - load all directory entries with link protocol defined in the + * parameter + * * @param protocol */ public TestsuiteDirectory(String protocol) { defineMapping(protocol); } - + /** * Define mapping of submodel and vab element */ private void defineMapping(String protocol) { - addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement", protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleVAB/"); + addMapping("urn:fhg:es.iese:vab:1:1:simplevabelement", protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleVAB/"); addMapping("urn:fhg:es.iese:aas:1:1:submodel", protocol + "://localhost:8080/basys.sdk/Testsuite/SimpleAASSubmodel/"); } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestHTTPSVerification.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestHTTPSVerification.java new file mode 100644 index 00000000..5dae843c --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestHTTPSVerification.java @@ -0,0 +1,108 @@ +package org.eclipse.basyx.testsuite.regression.vab.protocol.https; + +import static org.junit.Assert.assertTrue; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.LinkedHashMap; + +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.security.auth.x500.X500Principal; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.eclipse.basyx.testsuite.regression.vab.protocol.http.AASHTTPServerResource; +import org.eclipse.basyx.testsuite.regression.vab.protocol.http.SimpleVABElementServlet; +import org.eclipse.basyx.testsuite.regression.vab.protocol.http.TestsuiteDirectory; +import org.eclipse.basyx.testsuite.regression.vab.support.RecordingProvider; +import org.eclipse.basyx.vab.manager.VABConnectionManager; +import org.eclipse.basyx.vab.modelprovider.VABElementProxy; +import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider; +import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext; +import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface; +import org.eclipse.basyx.vab.protocol.https.HTTPSConnectorProvider; +import org.eclipse.basyx.vab.protocol.https.JerseyHttpsClientFactory; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Test whether ssl validation is performed on a https client + * + * @author zhangzai + * + */ +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class TestHTTPSVerification { + @Mock + private SSLSession sslSessionMock; + @Mock + private X509Certificate x509Mock; + + private DefaultHostnameVerifier testVerifier = new DefaultHostnameVerifier(); + + private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new LinkedHashMap<>())); + + /** + * Makes sure Tomcat Server is started after before each test case + */ + @Rule + public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir"), "localhost", 8080, true, "resources/ssl.cert", "pass123") + .addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet()).addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface(recorder))); + + @Test(expected = javax.ws.rs.ProcessingException.class) + public void testValidation() throws KeyManagementException, NoSuchAlgorithmException { + performRequest("https://localhost:8080/basys.sdk/Testsuite/SimpleVAB"); + } + + @Test(expected = org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException.class) + public void testValidationFlagHTTPSConnector() { + HTTPSConnectorProvider httpsConnectorProvider = new HTTPSConnectorProvider(); + httpsConnectorProvider.enableValidation(); + VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory("https"), httpsConnectorProvider); + + VABElementProxy proxy = connManager.connectToVABElement("urn:fhg:es.iese:vab:1:1:simplevabelement"); + proxy.getValue("/primitives/integer"); + } + + /** + * Create a test that verifies the host name with a mocked certificate. + * + * @throws KeyManagementException + * @throws NoSuchAlgorithmException + * @throws SSLPeerUnverifiedException + */ + @Test + public void testHTTPSClientValidation() throws KeyManagementException, NoSuchAlgorithmException, SSLPeerUnverifiedException { + X509Certificate[] certs = { x509Mock }; + X500Principal principleStub = new X500Principal("CN=localhost, OU=JavaSoft, O=Sun Microsystems, C=US"); + Mockito.when(x509Mock.getSubjectX500Principal()).thenReturn(principleStub); + Mockito.when(sslSessionMock.getPeerCertificates()).thenReturn(certs); + + assertTrue(testVerifier.verify("localhost", sslSessionMock)); + } + + /** + * Performs an HTTP request on an URL + * + * @param URL + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + private void performRequest(String URL) throws KeyManagementException, NoSuchAlgorithmException { + Client client = JerseyHttpsClientFactory.getJerseyHTTPSClientWithValidation(); + WebTarget resource = client.target(URL); + Builder request = resource.request(); + request.accept(MediaType.APPLICATION_JSON); + request.get(String.class); + } + +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java index 5191dcf6..da7fd541 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/https/TestVABHTTPS.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.https; @@ -13,12 +28,12 @@ import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import javax.ws.rs.client.Client; -import javax.ws.rs.client.WebTarget; import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import org.eclipse.basyx.testsuite.regression.vab.modelprovider.TestProvider; @@ -34,6 +49,7 @@ import org.eclipse.basyx.vab.protocol.http.server.VABHTTPInterface; import org.eclipse.basyx.vab.protocol.https.HTTPSConnectorProvider; import org.eclipse.basyx.vab.protocol.https.JerseyHttpsClientFactory; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -44,33 +60,38 @@ * */ public class TestVABHTTPS extends TestProvider { - protected VABConnectionManager connManager = new VABConnectionManager(new TestsuiteDirectory("https"), - new HTTPSConnectorProvider()); - private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new HashMap<>())); + protected VABConnectionManager connManager; + + private RecordingProvider recorder = new RecordingProvider(new VABMapProvider(new LinkedHashMap<>())); /** * Makes sure Tomcat Server is started after before each test case */ @Rule - public AASHTTPServerResource res = new AASHTTPServerResource( - new BaSyxContext("/basys.sdk", - System.getProperty("java.io.tmpdir"), "localhost", 8080, true, "resources/ssl.cert", "pass123") - .addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet()) - .addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface(recorder))); + public AASHTTPServerResource res = new AASHTTPServerResource(new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir"), "localhost", 8080, true, "resources/ssl.cert", "pass123") + .addServletMapping("/Testsuite/SimpleVAB/*", new SimpleVABElementServlet()).addServletMapping("/Testsuite/Recorder/*", new VABHTTPInterface(recorder))); + + @Before + public void setUp() { + HTTPSConnectorProvider httpsConnectorProvider = new HTTPSConnectorProvider(); + httpsConnectorProvider.disableValidation(); + connManager = new VABConnectionManager(new TestsuiteDirectory("https"), httpsConnectorProvider); + } @Override protected VABConnectionManager getConnectionManager() { return connManager; } - + /** * Tests for URL with no ending slash when accessing the root element, e.g. * http://localhost:8080/basys.sdk/Testsuite/SimpleVAB
* The SDK ensures that each access ends with a /. However, browser * requests do not necessarily conform to this - * @throws NoSuchAlgorithmException - * @throws KeyManagementException + * + * @throws NoSuchAlgorithmException + * @throws KeyManagementException */ @Test public void testRootURL() throws KeyManagementException, NoSuchAlgorithmException { @@ -116,11 +137,11 @@ public void testNoParameters() { * Performs an HTTP request on an URL * * @param URL - * @throws NoSuchAlgorithmException - * @throws KeyManagementException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException */ private void performRequest(String URL) throws KeyManagementException, NoSuchAlgorithmException { - Client client = JerseyHttpsClientFactory.getJerseyHTTPSClient(); + Client client = JerseyHttpsClientFactory.getJerseyHTTPSClientWithoutValidation(); // Called URL WebTarget resource = client.target(URL); diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/BrowsePathHelperTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/BrowsePathHelperTest.java new file mode 100644 index 00000000..2d029535 --- /dev/null +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/BrowsePathHelperTest.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (C) 2021 Festo Didactic SE + * + * 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. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ +package org.eclipse.basyx.testsuite.regression.vab.protocol.opcua; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.eclipse.basyx.vab.protocol.opcua.connector.milo.BrowsePathHelper; +import org.eclipse.basyx.vab.protocol.opcua.exception.OpcUaException; +import org.eclipse.milo.opcua.stack.core.BuiltinReferenceType; +import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName; +import org.eclipse.milo.opcua.stack.core.types.structured.BrowsePath; +import org.eclipse.milo.opcua.stack.core.types.structured.RelativePath; +import org.eclipse.milo.opcua.stack.core.types.structured.RelativePathElement; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class BrowsePathHelperTest { + + @SuppressWarnings("deprecation") + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void nullThrowsIllegalArgumentException() { + thrown.expect(IllegalArgumentException.class); + + BrowsePathHelper.parse(null); + } + + @Test + public void emptyStringThrowsException() { + thrown.expect(IllegalArgumentException.class); + + BrowsePathHelper.parse(""); + } + + @Test + public void validPathWithEscapedPeriod() { + String s = "/2:Block&.Output"; + BrowsePath bp = BrowsePathHelper.parse(s); + + RelativePathElement rpe = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, new QualifiedName(2, "Block.Output")); + + assertEquals(1, bp.getRelativePath().getElements().length); + assertEquals(rpe, bp.getRelativePath().getElements()[0]); + } + + @Test + public void validPathWithTwoElements() { + String s = "/3:Truck.0:NodeVersion"; + BrowsePath bp = BrowsePathHelper.parse(s); + + RelativePathElement rpe1 = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, new QualifiedName(3, "Truck")); + + RelativePathElement rpe2 = new RelativePathElement(BuiltinReferenceType.Aggregates.getNodeId(), false, true, new QualifiedName(0, "NodeVersion")); + + assertEquals(2, bp.getRelativePath().getElements().length); + assertEquals(rpe1, bp.getRelativePath().getElements()[0]); + assertEquals(rpe2, bp.getRelativePath().getElements()[1]); + } + + @Test + public void validPathWithTwoElementsAndEscapes() { + String s = ".3:Truck&/Car/Node&:Version"; + BrowsePath bp = BrowsePathHelper.parse(s); + + RelativePathElement rpe1 = new RelativePathElement(BuiltinReferenceType.Aggregates.getNodeId(), false, true, new QualifiedName(3, "Truck/Car")); + + RelativePathElement rpe2 = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, new QualifiedName(0, "Node:Version")); + + assertEquals(2, bp.getRelativePath().getElements().length); + assertEquals(rpe1, bp.getRelativePath().getElements()[0]); + assertEquals(rpe2, bp.getRelativePath().getElements()[1]); + } + + @Test + public void multiSelectorPath() { + String s = "/2:Block/Output."; + BrowsePath bp = BrowsePathHelper.parse(s); + + RelativePathElement last = bp.getRelativePath().getElements()[2]; + assertNull(last.getTargetName()); + } + + @Test + public void invalidPathWithMissingReferenceType() { + thrown.expect(OpcUaException.class); + thrown.expectMessage(org.hamcrest.CoreMatchers.containsString("index 0")); + + String s = "3:Truck/NodeVersion"; + BrowsePathHelper.parse(s); + } + + @Test + public void pathWithEmptyPathElement() { + thrown.expect(OpcUaException.class); + thrown.expectMessage(org.hamcrest.CoreMatchers.containsString("index 9")); + + String s = "/3:Truck/.NodeVersion"; + BrowsePathHelper.parse(s); + } + + @Test + public void pathWithIllegalNamespace() { + thrown.expect(OpcUaException.class); + thrown.expectMessage(org.hamcrest.CoreMatchers.containsString("index 1")); + + String s = "/3a:Truck"; + BrowsePathHelper.parse(s); + } + + @Test + public void pathWithTwoNamespaces() { + thrown.expect(OpcUaException.class); + thrown.expectMessage(org.hamcrest.CoreMatchers.containsString("index 9")); + + String s = "/3:Truck/2:Car:Bike"; + BrowsePathHelper.parse(s); + } + + @Test + public void pathWithDoubleColon() { + thrown.expect(OpcUaException.class); + thrown.expectMessage(org.hamcrest.CoreMatchers.containsString("index 9")); + + String s = "/3:Truck/2::Bike"; + BrowsePathHelper.parse(s); + } + + @Test + public void pathWithDirectReferenceTypeAtStart() { + thrown.expect(IllegalArgumentException.class); + + String s = "<1:ConnectedTo>1:Boiler/1:HeatSensor"; + BrowsePathHelper.parse(s); + } + + @Test + public void pathWithDirectReferenceTypeInMiddle() { + thrown.expect(IllegalArgumentException.class); + + String s = ".1:Boiler<1:ConnectedTo>1:HeatSensor"; + BrowsePathHelper.parse(s); + } + + @Test + public void relativePathToString() { + RelativePathElement rpe1 = new RelativePathElement(BuiltinReferenceType.Aggregates.getNodeId(), false, true, new QualifiedName(0, "Objects")); + + RelativePathElement rpe2 = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, new QualifiedName(1, "Cars")); + + RelativePathElement rpe3 = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, null); + + RelativePath rp = new RelativePath(new RelativePathElement[] { rpe1, rpe2, rpe3 }); + + String s = BrowsePathHelper.toString(rp); + + assertEquals(".0:Objects/1:Cars/", s); + } + + @Test + public void relativePathWithMissingQualifiedNameToString() { + thrown.expect(IllegalArgumentException.class); + + RelativePathElement rpe1 = new RelativePathElement(BuiltinReferenceType.Aggregates.getNodeId(), false, true, new QualifiedName(0, "Objects")); + + RelativePathElement rpe2 = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, null); + + RelativePathElement rpe3 = new RelativePathElement(BuiltinReferenceType.HierarchicalReferences.getNodeId(), false, true, new QualifiedName(1, "Cars")); + + RelativePath rp = new RelativePath(new RelativePathElement[] { rpe1, rpe2, rpe3 }); + + BrowsePathHelper.toString(rp); + } + + @Test + public void relativePathWithInverseReferencesToString() { + thrown.expect(IllegalArgumentException.class); + + RelativePathElement rpe1 = new RelativePathElement(BuiltinReferenceType.Aggregates.getNodeId(), true, true, new QualifiedName(0, "Objects")); + + RelativePath rp = new RelativePath(new RelativePathElement[] { rpe1 }); + + BrowsePathHelper.toString(rp); + } +} diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java index fa50ad49..e4e0fee5 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/protocol/opcua/TestVABOpcUa.java @@ -1,16 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.protocol.opcua; import org.eclipse.basyx.vab.gateway.ConnectorProviderMapper; -import org.eclipse.basyx.vab.protocol.opcua.connector.OpcUaConnectorProvider; +import org.eclipse.basyx.vab.protocol.opcua.connector.OpcUaConnectorFactory; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.ULong; @@ -27,41 +42,35 @@ * */ public class TestVABOpcUa { - - private static Logger logger = LoggerFactory.getLogger(TestVABOpcUa.class); - - protected ConnectorProviderMapper clientMapper = new ConnectorProviderMapper(); -// @Test - public void testOpcUaMethodCall() { - clientMapper.addConnectorProvider("opc.tcp", new OpcUaConnectorProvider()); - try { - Object methodCallRes = clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer") - .invokeOperation("0:Objects/2:Data/2:Static/2:MethodTest/2:ScalarMethod1", - new Object[] { Boolean.valueOf("true"), Byte.valueOf("1"), UByte.valueOf("2"), - Short.valueOf("3"), UShort.valueOf("5"), 8, UInteger.valueOf(13), - Long.valueOf("21"), ULong.valueOf("34"), Float.valueOf("55.0"), - Double.valueOf("89.0") }); - Assert.assertEquals("true 1 2 3 5 8 13 21 34 55.0 89.0 ", methodCallRes); - } catch (Exception e) { - // TODO Auto-generated catch block - logger.error("[TEST] Exception in testOpcUaMethodCall", e); - } - } - -// @Test - public void testOpcUaReadAndWrite() { - clientMapper.addConnectorProvider("opc.tcp", new OpcUaConnectorProvider()); - try { - clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer") - .setValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value", 42); + private static Logger logger = LoggerFactory.getLogger(TestVABOpcUa.class); + + protected ConnectorProviderMapper clientMapper = new ConnectorProviderMapper(); + + // @Test + public void testOpcUaMethodCall() { + clientMapper.addConnectorProvider("opc.tcp", new OpcUaConnectorFactory()); + try { + Object methodCallRes = clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer").invokeOperation("0:Objects/2:Data/2:Static/2:MethodTest/2:ScalarMethod1", new Object[] { Boolean.valueOf("true"), + Byte.valueOf("1"), UByte.valueOf("2"), Short.valueOf("3"), UShort.valueOf("5"), 8, UInteger.valueOf(13), Long.valueOf("21"), ULong.valueOf("34"), Float.valueOf("55.0"), Double.valueOf("89.0") }); + Assert.assertEquals("true 1 2 3 5 8 13 21 34 55.0 89.0 ", methodCallRes); + } catch (Exception e) { + // TODO Auto-generated catch block + logger.error("[TEST] Exception in testOpcUaMethodCall", e); + } + } + + // @Test + public void testOpcUaReadAndWrite() { + clientMapper.addConnectorProvider("opc.tcp", new OpcUaConnectorFactory()); + try { + clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer").setValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value", 42); - Object ret = clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer") - .getValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value"); - Assert.assertEquals("42", ret); - } catch (Exception e) { - // TODO Auto-generated catch block - logger.error("[TEST] Exception in testOpcUaReadAndWrite", e); - } - } + Object ret = clientMapper.getConnector("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer").getValue("0:Objects/2:Data/2:Static/2:AnalogScalar/2:Int32Value"); + Assert.assertEquals("42", ret); + } catch (Exception e) { + // TODO Auto-generated catch block + logger.error("[TEST] Exception in testOpcUaReadAndWrite", e); + } + } } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java index c59d7315..ec19ba98 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/RecordingProvider.java @@ -1,14 +1,31 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.support; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -43,7 +60,6 @@ public void reset() { paths.clear(); } - @Override public Object getValue(String path) throws ProviderException { paths.add(path); @@ -59,7 +75,21 @@ public void setValue(String path, Object newValue) throws ProviderException { @Override public void createValue(String path, Object newEntity) throws ProviderException { paths.add(path); - wrapped.createValue(path, newEntity); + if (newEntity instanceof InputStream) { + try { + InputStream in = (InputStream) newEntity; + int n = in.available(); + byte[] bytes = new byte[n]; + in.read(bytes, 0, n); + String s = new String(bytes, StandardCharsets.UTF_8); + wrapped.createValue(path, s); + } catch (Exception e) { + throw new ProviderException("Cannot parse input stream"); + } + + } else { + wrapped.createValue(path, newEntity); + } } @Override diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java index 617fc770..beff488f 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/support/TestTypeDestroyer.java @@ -1,11 +1,26 @@ /******************************************************************************* * Copyright (C) 2021 the Eclipse BaSyx Authors * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ + * 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: * - * SPDX-License-Identifier: EPL-2.0 + * 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. + * + * SPDX-License-Identifier: MIT ******************************************************************************/ package org.eclipse.basyx.testsuite.regression.vab.support; @@ -22,11 +37,12 @@ /** * Removes type information similar to what a communication over VAB would do + * * @author rajashek * */ public class TestTypeDestroyer { - + @SuppressWarnings("unchecked") @Test public void testTypeDestroyer() { diff --git a/src/test/resources/aas/factory/aasx/01_Festo.aasx b/src/test/resources/aas/factory/aasx/01_Festo.aasx new file mode 100644 index 00000000..64900301 Binary files /dev/null and b/src/test/resources/aas/factory/aasx/01_Festo.aasx differ diff --git a/src/test/resources/aas/factory/xml/inWorkarounds.xml b/src/test/resources/aas/factory/xml/inWorkarounds.xml new file mode 100644 index 00000000..5791d2f2 --- /dev/null +++ b/src/test/resources/aas/factory/xml/inWorkarounds.xml @@ -0,0 +1,65 @@ + + + + + asset + http://pk.festo.com/q30j38dlajx + + + Template + + + + + submodelIdShort + http://www.zvei.de/demo/submodel/12345679 + + + + operation_ID + + + + + + file_ID + file_mimetype + file_value + Template + + + + + + + blob_ID + YmxvYit2YWx1ZQ== + blob_mimetype + Template + + + + + + + + + reference_ELE_ID + + + 0173-1#05-AAA650#002 + + + Template + + + + + + + + + \ No newline at end of file