-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Jannis Jung <jannis.jung@iese.fraunhofer.de>
- Loading branch information
1 parent
0ca3fbf
commit f72c0e6
Showing
9 changed files
with
821 additions
and
17 deletions.
There are no files selected for viewing
106 changes: 106 additions & 0 deletions
106
src/main/java/org/eclipse/basyx/aas/factory/json/BidirectionalJSONConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/******************************************************************************* | ||
* Copyright (C) 2023 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.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell; | ||
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; | ||
import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; | ||
import org.eclipse.basyx.submodel.metamodel.api.reference.IKey; | ||
import org.eclipse.basyx.submodel.metamodel.map.Submodel; | ||
import org.eclipse.basyx.submodel.metamodel.map.reference.Key; | ||
import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory; | ||
import org.eclipse.basyx.vab.coder.json.serialization.GSONTools; | ||
|
||
/** | ||
* Serializes and deserializes shells and submodels to and from json | ||
* | ||
* @author jungjan | ||
* | ||
*/ | ||
public class BidirectionalJSONConverter { | ||
private static GSONTools gsonTools = new GSONTools(new DefaultTypeFactory()); | ||
|
||
public static String serializeSubmodel(ISubmodel submodel) { | ||
return gsonTools.serialize(submodel); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static ISubmodel deserializeSubmodel(String jsonSubmodel) { | ||
return Submodel.createAsFacade((Map<String, Object>) gsonTools.deserialize(jsonSubmodel)); | ||
} | ||
|
||
public static String serializeShell(AssetAdministrationShell shell) { | ||
return gsonTools.serialize(shell); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static AssetAdministrationShell deserializeShell(String jsonShell) { | ||
return AssetAdministrationShell.createAsFacade((Map<String, Object>) gsonTools.deserialize(jsonShell)); | ||
} | ||
|
||
public static <T> String serializeObject(T object) { | ||
return gsonTools.serialize(object); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static <T> T deserializeJSON(String json) { | ||
T retrieved = (T) gsonTools.deserialize(json); | ||
return retrieved; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public static AASDescriptor deserializeAASDescriptor(String json) { | ||
return AASDescriptor.createAsFacade((Map<String, Object>) gsonTools.deserialize(json)); | ||
} | ||
|
||
/** | ||
* | ||
* @param submodel | ||
* @return the semanticId of a submodel serialized according to the following schema: | ||
* {@code {type:<type>;value:<value>;idType:<idType>[/]}}. | ||
* Example: {@code type:Submodel;value:a value;idType:Custom/type:Submodel;value:another value;idType:Custom} | ||
*/ | ||
public static String semanticIdAsSString(ISubmodel submodel) { | ||
if (submodel.getSemanticId() == null) { | ||
return null; | ||
} | ||
List<IKey> keys = submodel.getSemanticId().getKeys(); | ||
return semanticIdKeysToString(keys); | ||
} | ||
|
||
public static String semanticIdKeysToString(List<IKey> keys) { | ||
return keys.stream().map(k -> | ||
Key.TYPE + ":" + k.getType() + ";" | ||
/* + Key.LOCAL + ":" + k.isLocal() + ";" */ //ignoring local since it won't be relevant for V3 | ||
+ Key.VALUE + ":" + k.getValue() + ";" | ||
+ Key.IDTYPE + ":" + k.getIdType()) | ||
.collect(Collectors.joining("/")); | ||
} | ||
|
||
} |
25 changes: 23 additions & 2 deletions
25
src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
186 changes: 186 additions & 0 deletions
186
src/main/java/org/eclipse/basyx/extensions/storage/BaSyxStorageAPI.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
/******************************************************************************* | ||
* Copyright (C) 2023 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.storage; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell; | ||
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor; | ||
import org.eclipse.basyx.submodel.metamodel.api.ISubmodel; | ||
import org.eclipse.basyx.submodel.metamodel.api.qualifier.IIdentifiable; | ||
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.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* Abstract class to create a storage API. The generic type {@code <T>} | ||
* determines the type of Objects, this API should handle. One API can handle | ||
* exactly one type of object i.e it manages exactly one data collection within | ||
* the remote storage. | ||
* | ||
* @author jungjan | ||
* | ||
* @param <T> | ||
* The type of Objects to be handled | ||
*/ | ||
public abstract class BaSyxStorageAPI<T> implements IBaSyxStorageAPI<T> { | ||
protected Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
protected final String COLLECTION_NAME; | ||
protected final Class<T> TYPE; | ||
|
||
/** | ||
* | ||
* @param collectionName | ||
* The name of the collection, managed by this API | ||
* @param type | ||
* Must be the exact same type as the type of the generic parameter | ||
* {@code <T>} | ||
*/ | ||
public BaSyxStorageAPI(String collectionName, Class<T> type) { | ||
COLLECTION_NAME = collectionName; | ||
TYPE = type; | ||
} | ||
|
||
/** | ||
* DISCLAIMER: Currently only supports to extract keys from IIdentifiables. | ||
* Helper method that extracts a key for persistence storage requests from an | ||
* object. | ||
* | ||
* @param obj | ||
* An object that contains a key that can be used to find the | ||
* persisted version of the object. | ||
* @return The key | ||
*/ | ||
protected String getKey(T obj) { | ||
if (!(obj instanceof IIdentifiable)) { | ||
throw new IllegalArgumentException("Can only extract a key from a object of type " + IIdentifiable.class.getName()); | ||
} | ||
return ((IIdentifiable) obj).getIdentification().getId(); | ||
} | ||
|
||
/** | ||
* Retrieves an object by its key from the persistence storage. | ||
* | ||
* The result of this retrieval will then be further processed by the | ||
* {@link #retrieve(String)} method to ensure it is interpreted correctly. | ||
* | ||
* @param key | ||
* The key of the object to be retrieved | ||
* @return The expected object if successful | ||
* @param key | ||
* @return | ||
*/ | ||
public abstract T rawRetrieve(String key); | ||
|
||
/** | ||
* Returns a Object that was originally retrieved from the abstract method | ||
* {@code rawRetrieve}. If the object to be returned is a submodel type, it will | ||
* be updated with a correct interpretation of is's SubmodelElements. | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
@Override | ||
public T retrieve(String key) { | ||
T retrieved = rawRetrieve(key); | ||
if (retrieved != null && isSubmodelType(retrieved.getClass())) { | ||
return (T) handleRetrievedSubmodel((Submodel) retrieved); | ||
} | ||
return retrieved; | ||
} | ||
|
||
/** | ||
* Helper to bring the SubmodelElements a retrieved SubmodelObject to the | ||
* correct Type of ISubmodelElements. Background: SubmodelsElements are | ||
* typically retrieved from a persistence storage within a Submodel and come in | ||
* the raw form of {@code Map<String, Map<String, Object>>}. This method | ||
* processes the raw SubmodelElements to a | ||
* {@code Map<String, ISubmodelElement>}. | ||
* | ||
* @param retrieved | ||
* The retrieved submodel with raw SubmodelElements | ||
* @return An updated version of the submodel with correctly interpreted | ||
* SubmodelElements | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
protected Submodel handleRetrievedSubmodel(Submodel retrieved) { | ||
Map<String, Map<String, Object>> elementMaps = (Map<String, Map<String, Object>>) retrieved.get(Submodel.SUBMODELELEMENT); | ||
Map<String, ISubmodelElement> elements = forceToISubmodelElements(elementMaps); | ||
retrieved.put(Submodel.SUBMODELELEMENT, elements); | ||
return retrieved; | ||
} | ||
|
||
/** | ||
* Converts raw SubmodelElements from a retrieved SubmodelObject to | ||
* ISubmodelElements. Background: SubmodelsElements are typically retrieved from | ||
* a persistence storage within a Submodel and come in the raw form of | ||
* {@code Map<String, Map<String, Object>>}. This method processes the raw | ||
* SubmodelElements to a {@code Map<String, ISubmodelElement>}. | ||
* | ||
* @param submodelElementObjectMap | ||
* The raw SubmodelElements (typically retrieved within a submdoel -> | ||
* can be get with {@code submodel.get(Submodel.SUBMODELELEMENT)})) | ||
* @return A map in the expected form of {@code Map<String, ISubmodelElement>} | ||
*/ | ||
private Map<String, ISubmodelElement> forceToISubmodelElements(Map<String, Map<String, Object>> submodelElementObjectMap) { | ||
Map<String, ISubmodelElement> elements = new HashMap<>(); | ||
|
||
submodelElementObjectMap.forEach((idShort, elementMap) -> { | ||
ISubmodelElement element = SubmodelElementFacadeFactory.createSubmodelElement(elementMap); | ||
elements.put(idShort, element); | ||
}); | ||
return elements; | ||
} | ||
|
||
/* | ||
* Not yet tested | ||
*/ | ||
protected boolean isSubmodelType(Class<?> type) { | ||
return ISubmodel.class.isAssignableFrom(type); | ||
} | ||
|
||
/* | ||
* Not yet tested | ||
*/ | ||
protected boolean isShellType(Class<?> type) { | ||
return IAssetAdministrationShell.class.isAssignableFrom(type); | ||
} | ||
|
||
/* | ||
* Not yet tested | ||
*/ | ||
protected boolean isAASDescriptorType(Class<?> type) { | ||
return AASDescriptor.class.isAssignableFrom(type); | ||
} | ||
|
||
/* | ||
* Not yet tested | ||
*/ | ||
protected boolean isBaSyxType(Class<?> type) { | ||
return (isShellType(type) || isSubmodelType(type) || isAASDescriptorType(type)); | ||
} | ||
} |
Oops, something went wrong.