CgmesNamespace.java
/**
* Copyright (c) 2019, RTE (http://www.rte-france.com)
* 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 http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.cgmes.model;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.powsybl.commons.PowsyblException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public final class CgmesNamespace {
private CgmesNamespace() {
}
private static final Logger LOG = LoggerFactory.getLogger(CgmesNamespace.class);
public static final String CIM_100_NAMESPACE = "http://iec.ch/TC57/CIM100#";
public static final String CIM_16_NAMESPACE = "http://iec.ch/TC57/2013/CIM-schema-cim16#";
private static final Set<String> VALID_CIM_NAMESPACES = Set.of(CIM_16_NAMESPACE, CIM_100_NAMESPACE);
private static final Pattern CIM_100_PLUS_NAMESPACE_PATTERN = Pattern.compile(".*/CIM\\d+#$");
public static final String RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
public static final String ENTSOE_NAMESPACE = "http://entsoe.eu/CIM/SchemaExtension/3/1#";
public static final String EU_NAMESPACE = "http://iec.ch/TC57/CIM100-European#";
public static final String MD_NAMESPACE = "http://iec.ch/TC57/61970-552/ModelDescription/1#";
public static final String CIM_16_EQ_PROFILE = "http://entsoe.eu/CIM/EquipmentCore/3/1";
public static final String CIM_16_EQ_OPERATION_PROFILE = "http://entsoe.eu/CIM/EquipmentOperation/3/1";
public static final String CIM_16_TP_PROFILE = "http://entsoe.eu/CIM/Topology/4/1";
public static final String CIM_16_SV_PROFILE = "http://entsoe.eu/CIM/StateVariables/4/1";
public static final String CIM_16_SSH_PROFILE = "http://entsoe.eu/CIM/SteadyStateHypothesis/1/1";
public static final String CIM_16_EQ_BD_PROFILE = "http://entsoe.eu/CIM/EquipmentBoundary/3/1";
public static final String CIM_16_TP_BD_PROFILE = "http://entsoe.eu/CIM/TopologyBoundary/3/1";
public static final String CGMES_EQ_3_OR_GREATER_PREFIX = "http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/";
public static final String CIM_100_EQ_PROFILE = "http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0";
public static final String CIM_100_EQ_OPERATION_PROFILE = "http://iec.ch/TC57/ns/CIM/Operation-EU/3.0";
public static final String CIM_100_TP_PROFILE = "http://iec.ch/TC57/ns/CIM/Topology-EU/3.0";
public static final String CIM_100_SV_PROFILE = "http://iec.ch/TC57/ns/CIM/StateVariables-EU/3.0";
public static final String CIM_100_SSH_PROFILE = "http://iec.ch/TC57/ns/CIM/SteadyStateHypothesis-EU/3.0";
public static final String CIM_100_EQ_BD_PROFILE = "http://iec.ch/TC57/ns/CIM/EquipmentBoundary-EU/3.0";
public static final Cim CIM_16 = new Cim16();
public static final Cim CIM_100 = new Cim100();
public static final List<Cim> CIM_LIST = List.of(CIM_16, CIM_100);
public interface Cim {
int getVersion();
String getNamespace();
boolean hasProfileUri(String profileUri);
String getProfileUri(String profile);
String getProfile(String profileUri);
String getEuPrefix();
String getEuNamespace();
}
private abstract static class AbstractCim implements Cim {
private final int version;
private final String namespace;
private final String euPrefix;
private final String euNamespace;
private final BiMap<String, String> profiles = HashBiMap.create();
private AbstractCim(int version, String namespace, String euPrefix, String euNamespace, Map<String, String> profiles) {
this.version = version;
this.namespace = namespace;
this.euPrefix = euPrefix;
this.euNamespace = euNamespace;
this.profiles.putAll(profiles);
}
@Override
public int getVersion() {
return version;
}
@Override
public String getNamespace() {
return namespace;
}
@Override
public String getEuPrefix() {
return euPrefix;
}
@Override
public String getEuNamespace() {
return euNamespace;
}
@Override
public boolean hasProfileUri(String profileUri) {
return profiles.containsValue(profileUri);
}
@Override
public String getProfileUri(String profile) {
return profiles.get(profile);
}
@Override
public String getProfile(String profileUri) {
return profiles.inverse().get(profileUri);
}
}
private static final class Cim16 extends AbstractCim {
private Cim16() {
super(16, CIM_16_NAMESPACE, "entsoe", ENTSOE_NAMESPACE,
Map.of("EQ", CIM_16_EQ_PROFILE,
"EQ_OP", CIM_16_EQ_OPERATION_PROFILE,
"SSH", CIM_16_SSH_PROFILE,
"SV", CIM_16_SV_PROFILE,
"TP", CIM_16_TP_PROFILE,
"EQ_BD", CIM_16_EQ_BD_PROFILE,
"TP_BD", CIM_16_TP_BD_PROFILE));
}
}
private static final class Cim100 extends AbstractCim {
private Cim100() {
super(100, CIM_100_NAMESPACE, "eu", EU_NAMESPACE,
Map.of("EQ", CIM_100_EQ_PROFILE,
"EQ_OP", CIM_100_EQ_OPERATION_PROFILE,
"SSH", CIM_100_SSH_PROFILE,
"SV", CIM_100_SV_PROFILE,
"TP", CIM_100_TP_PROFILE,
"EQ_BD", CIM_100_EQ_BD_PROFILE));
}
}
public static boolean isValid(String ns) {
// Until CIM16 the CIM namespace contained the string "CIM-schema-cim<versionNumber>#"
// Since CIM100 the namespace seems to follow the pattern "/CIM<versionNumber>#"
return VALID_CIM_NAMESPACES.contains(ns) || CIM_100_PLUS_NAMESPACE_PATTERN.matcher(ns).matches();
}
public static Cim getCim(int cimVersion) {
switch (cimVersion) {
case 16:
return CIM_16;
case 100:
return CIM_100;
default:
if (cimVersion > 100) {
LOG.info("CIM version is above 100 ({}), will be considered 100", cimVersion);
return CIM_100;
}
throw new PowsyblException("Unsupported CIM version " + cimVersion);
}
}
public static String getProfile(String profileUri) {
for (Cim cim : CIM_LIST) {
if (cim.hasProfileUri(profileUri)) {
return cim.getProfile(profileUri);
}
}
return null;
}
}