Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for additional
* information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/
package org.eclipse.esmf.aspectmodel.versionupdate;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.esmf.metamodel.vocabulary.RdfNamespace;
import org.eclipse.esmf.samm.KnownVersion;
import com.google.common.collect.Streams;
import org.apache.jena.graph.NodeFactory;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
/**
* Abstract migration function that is used to apply a change to all URIs in a model
*/
public abstract class AbstractUriRewriter extends AbstractSammMigrator {
protected AbstractUriRewriter( final KnownVersion sourceVersion, final KnownVersion targetVersion ) {
super( sourceVersion, targetVersion, 100 );
}
/**
* The URI rewriter implementation decides whether a URI needs to be rewritten, given the map of old to new namespaces
*
* @param oldUri the URI to rewrite
* @param oldToNewNamespaces the map of old to new namespaces
* @return empty if the URI should be kept as-is, the replacement URI otherwise
*/
protected abstract Optional rewriteUri( String oldUri, Map oldToNewNamespaces );
protected Resource updateResource( final Resource resource, final Map oldToNewNamespaces ) {
if ( resource.isAnon() ) {
return resource;
}
return rewriteUri( resource.getURI(), oldToNewNamespaces ).map( ResourceFactory::createResource ).orElse( resource );
}
protected Property updateProperty( final Property property, final Map oldToNewNamespaces ) {
return rewriteUri( property.getURI(), oldToNewNamespaces ).map( ResourceFactory::createProperty ).orElse( property );
}
protected Literal updateLiteral( final Literal literal, final Map oldToNewNamespaces ) {
return Optional.ofNullable( literal.getDatatypeURI() )
.flatMap( uri -> rewriteUri( uri, oldToNewNamespaces ) )
.map( uri -> ResourceFactory.createTypedLiteral( literal.getLexicalForm(), NodeFactory.getType( uri ) ) )
.orElse( literal );
}
protected RDFNode updateRdfNode( final RDFNode rdfNode, final Map oldToNewNamespaces ) {
if ( rdfNode.isResource() ) {
return updateResource( rdfNode.asResource(), oldToNewNamespaces );
} else if ( rdfNode.isLiteral() ) { // needed especially for "curie" literals, which are versioned: "unit:day"^^samm:curie
return updateLiteral( rdfNode.asLiteral(), oldToNewNamespaces );
}
return rdfNode;
}
protected Map buildReplacementPrefixMap( final Model sourceModel, final Map targetPrefixes ) {
final Map sourcePrefixes = RdfNamespace.createPrefixMap( getSourceKnownVersion() );
final Map oldToNewNamespaces = new HashMap<>();
for ( final Map.Entry targetEntry : targetPrefixes.entrySet() ) {
final String prefix = targetEntry.getKey();
if ( prefix != null ) {
final String sourceUri = sourcePrefixes.get( prefix );
if ( sourceUri != null && !sourceUri.equals( targetEntry.getValue() ) ) {
oldToNewNamespaces.put( sourceUri, targetEntry.getValue() );
}
}
}
return oldToNewNamespaces;
}
/**
* Builds the map of RDF prefixes to set in the migrated model, e.g. "xsd" -> XSD.NS
*
* @param sourceModel the source model
* @param targetPrefixes the target prefix map, containing e.g. "samm" -> samm.getNamespace()
* @param oldToNewNamespaces the map of old RDF namespaces to their new counterparts
* @return the prefix map
*/
protected Map buildPrefixMap( final Model sourceModel, final Map targetPrefixes,
final Map oldToNewNamespaces ) {
return sourceModel.getNsPrefixMap().keySet().stream().map( prefix ->
Map. entry( prefix, targetPrefixes.getOrDefault( prefix, sourceModel.getNsPrefixURI( prefix ) ) ) )
.collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ) );
}
@Override
public Model migrate( final Model sourceModel ) {
final Model targetModel = ModelFactory.createDefaultModel();
final Map targetPrefixes = RdfNamespace.createPrefixMap( getTargetKnownVersion() );
final Map oldToNewNamespaces = buildReplacementPrefixMap( sourceModel, targetPrefixes );
Streams.stream( sourceModel.listStatements() ).map( statement -> targetModel
.createStatement(
updateResource( statement.getSubject(), oldToNewNamespaces ),
updateProperty( statement.getPredicate(), oldToNewNamespaces ),
updateRdfNode( statement.getObject(), oldToNewNamespaces )
) ).forEach( targetModel::add );
targetModel.setNsPrefixes( buildPrefixMap( sourceModel, targetPrefixes, oldToNewNamespaces ) );
return targetModel;
}
}