diff --git a/distribution-core/pom.xml b/distribution-core/pom.xml
index ae371bbdeb9..6aded0633f8 100644
--- a/distribution-core/pom.xml
+++ b/distribution-core/pom.xml
@@ -278,10 +278,16 @@
${project.groupId}
- powsybl-iidm-reducer
+ powsybl-iidm-mergingview
${project.version}
+
+ ${project.groupId}
+ powsybl-iidm-reducer
+ ${project.version}
+
+
${project.groupId}
powsybl-iidm-test
diff --git a/iidm/iidm-mergingview/pom.xml b/iidm/iidm-mergingview/pom.xml
new file mode 100644
index 00000000000..d9d89e7ce33
--- /dev/null
+++ b/iidm/iidm-mergingview/pom.xml
@@ -0,0 +1,84 @@
+
+
+
+ 4.0.0
+
+
+ powsybl-iidm
+ com.powsybl
+ 3.1.0-SNAPSHOT
+
+
+ powsybl-iidm-mergingview
+ IIDM Merging View
+ A network merging tool for IIDM model
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ com.powsybl.iidm.mergingview
+
+
+
+
+
+
+
+
+
+
+ ${project.groupId}
+ powsybl-commons
+ ${project.version}
+
+
+ ${project.groupId}
+ powsybl-iidm-api
+ ${project.version}
+
+
+
+
+ com.google.jimfs
+ jimfs
+ test
+
+
+ junit
+ junit
+ test
+
+
+ org.slf4j
+ slf4j-simple
+ test
+
+
+ ${project.groupId}
+ powsybl-iidm-impl
+ ${project.version}
+ test
+
+
+ ${project.groupId}
+ powsybl-iidm-test
+ ${project.version}
+ test
+
+
+
+
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/AbstractAdapter.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/AbstractAdapter.java
new file mode 100644
index 00000000000..b5c512ef031
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/AbstractAdapter.java
@@ -0,0 +1,110 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+
+import com.powsybl.commons.extensions.Extension;
+import com.powsybl.iidm.network.Identifiable;
+
+/**
+ * @author Thomas Adam
+ */
+abstract class AbstractAdapter> implements Identifiable {
+
+ private final I delegate;
+
+ private final MergingViewIndex index;
+
+ protected AbstractAdapter(final I delegate, final MergingViewIndex index) {
+ this.delegate = Objects.requireNonNull(delegate, "delegate is null");
+ this.index = Objects.requireNonNull(index, "merging view index is null");
+ }
+
+ @Override
+ public MergingView getNetwork() {
+ return index.getView();
+ }
+
+ // -------------------------------
+ // Simple delegated methods ------
+ // -------------------------------
+ public I getDelegate() {
+ return delegate;
+ }
+
+ public MergingViewIndex getIndex() {
+ return index;
+ }
+
+ @Override
+ public String getId() {
+ return delegate.getId();
+ }
+
+ @Override
+ public String getName() {
+ return delegate.getName();
+ }
+
+ @Override
+ public boolean hasProperty() {
+ return delegate.hasProperty();
+ }
+
+ @Override
+ public boolean hasProperty(final String key) {
+ return delegate.hasProperty(key);
+ }
+
+ @Override
+ public String getProperty(final String key) {
+ return delegate.getProperty(key);
+ }
+
+ @Override
+ public String getProperty(final String key, final String defaultValue) {
+ return delegate.getProperty(key, defaultValue);
+ }
+
+ @Override
+ public String setProperty(final String key, final String value) {
+ return delegate.setProperty(key, value);
+ }
+
+ @Override
+ public Set getPropertyNames() {
+ return delegate.getPropertyNames();
+ }
+
+ @Override
+ public > void addExtension(final Class super E> type, final E extension) {
+ delegate.addExtension(type, extension);
+ }
+
+ @Override
+ public > E getExtension(final Class super E> type) {
+ return delegate.getExtension(type);
+ }
+
+ @Override
+ public > E getExtensionByName(final String name) {
+ return delegate.getExtensionByName(name);
+ }
+
+ @Override
+ public > boolean removeExtension(final Class type) {
+ return delegate.removeExtension(type);
+ }
+
+ @Override
+ public > Collection getExtensions() {
+ return delegate.getExtensions();
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingNetworkListener.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingNetworkListener.java
new file mode 100644
index 00000000000..c2be513393b
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingNetworkListener.java
@@ -0,0 +1,30 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import com.powsybl.iidm.network.Identifiable;
+import com.powsybl.iidm.network.NetworkListener;
+
+/**
+ * @author Thomas Adam
+ */
+public class MergingNetworkListener implements NetworkListener {
+ @Override
+ public void onCreation(final Identifiable identifiable) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public void onRemoval(final Identifiable identifiable) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public void onUpdate(final Identifiable identifiable, final String attribute, final Object oldValue, final Object newValue) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingView.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingView.java
new file mode 100644
index 00000000000..60704b1c000
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingView.java
@@ -0,0 +1,696 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import com.powsybl.commons.PowsyblException;
+import com.powsybl.commons.extensions.Extension;
+import com.powsybl.iidm.network.Battery;
+import com.powsybl.iidm.network.Branch;
+import com.powsybl.iidm.network.BusbarSection;
+import com.powsybl.iidm.network.ContainerType;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.DanglingLine;
+import com.powsybl.iidm.network.Generator;
+import com.powsybl.iidm.network.HvdcConverterStation;
+import com.powsybl.iidm.network.HvdcLine;
+import com.powsybl.iidm.network.HvdcLineAdder;
+import com.powsybl.iidm.network.Identifiable;
+import com.powsybl.iidm.network.LccConverterStation;
+import com.powsybl.iidm.network.Line;
+import com.powsybl.iidm.network.LineAdder;
+import com.powsybl.iidm.network.Load;
+import com.powsybl.iidm.network.Network;
+import com.powsybl.iidm.network.NetworkFactory;
+import com.powsybl.iidm.network.NetworkListener;
+import com.powsybl.iidm.network.ShuntCompensator;
+import com.powsybl.iidm.network.StaticVarCompensator;
+import com.powsybl.iidm.network.Substation;
+import com.powsybl.iidm.network.Switch;
+import com.powsybl.iidm.network.ThreeWindingsTransformer;
+import com.powsybl.iidm.network.TieLineAdder;
+import com.powsybl.iidm.network.TwoWindingsTransformer;
+import com.powsybl.iidm.network.VariantManager;
+import com.powsybl.iidm.network.VoltageLevel;
+import com.powsybl.iidm.network.VscConverterStation;
+
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Not destructive network merge.
+ *
+ * @author Thomas Adam
+ */
+public final class MergingView implements Network {
+ public static final PowsyblException NOT_IMPLEMENTED_EXCEPTION = new PowsyblException("Not implemented exception");
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MergingView.class);
+
+ /** Indexing of all Identifiable into current merging view */
+ private final MergingViewIndex index;
+
+ /** Delegate for Identifiable creation into current merging view */
+ private final Network workingNetwork;
+
+ /** To listen events from merging network */
+ private final NetworkListener listener = new MergingNetworkListener();
+
+ /** Constructor */
+ private MergingView(final NetworkFactory factory, final String id, final String format) {
+ Objects.requireNonNull(factory, "factory is null");
+
+ index = new MergingViewIndex(this);
+ // Working network will store view informations
+ workingNetwork = factory.createNetwork(id, format);
+ // Add working network as merging network
+ index.checkAndAdd(workingNetwork);
+ workingNetwork.addListener(listener);
+ }
+
+ /** Public constructor */
+ public static MergingView create(final String id, final String format) {
+ return new MergingView(NetworkFactory.findDefault(), id, format);
+ }
+
+ @Override
+ public void merge(final Network other) {
+ Objects.requireNonNull(other, "network is null");
+
+ final long start = System.currentTimeMillis();
+
+ index.checkAndAdd(other);
+ other.addListener(listener);
+
+ LOGGER.info("Merging of {} done in {} ms", other.getId(), System.currentTimeMillis() - start);
+ }
+
+ @Override
+ public void merge(final Network... others) {
+ for (final Network other : others) {
+ merge(other);
+ }
+ }
+
+ @Override
+ public ContainerType getContainerType() {
+ return ContainerType.NETWORK;
+ }
+
+ @Override
+ public String getId() {
+ return workingNetwork.getId();
+ }
+
+ @Override
+ public String getName() {
+ return workingNetwork.getName();
+ }
+
+ @Override
+ public DateTime getCaseDate() {
+ return workingNetwork.getCaseDate();
+ }
+
+ @Override
+ public Network setCaseDate(final DateTime date) {
+ workingNetwork.setCaseDate(date);
+ return this;
+ }
+
+ @Override
+ public int getForecastDistance() {
+ return workingNetwork.getForecastDistance();
+ }
+
+ @Override
+ public Network setForecastDistance(final int forecastDistance) {
+ workingNetwork.setForecastDistance(forecastDistance);
+ return this;
+ }
+
+ @Override
+ public boolean hasProperty() {
+ return index.getNetworkStream()
+ .anyMatch(Network::hasProperty);
+ }
+
+ @Override
+ public boolean hasProperty(final String key) {
+ return index.getNetworkStream()
+ .anyMatch(n -> n.hasProperty(key));
+ }
+
+ @Override
+ public String getProperty(final String key) {
+ return index.getNetworkStream()
+ .map(n -> n.getProperty(key))
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public String getProperty(final String key, final String defaultValue) {
+ return index.getNetworkStream()
+ .map(n -> n.getProperty(key, defaultValue))
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(defaultValue);
+ }
+
+ @Override
+ public String setProperty(final String key, final String value) {
+ index.getNetworkStream().forEach(n -> n.setProperty(key, value));
+ return null;
+ }
+
+ @Override
+ public Set getPropertyNames() {
+ return index.getNetworkStream()
+ .map(Network::getPropertyNames)
+ .flatMap(Set::stream)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public String getSourceFormat() {
+ String format = "hybrid";
+ // If all Merging Network has same format
+ final Set formats = index.getNetworkStream()
+ .map(Network::getSourceFormat)
+ .collect(Collectors.toSet());
+ if (formats.size() == 1) {
+ format = formats.iterator().next();
+ }
+ return format;
+ }
+
+ @Override
+ public Set getCountries() {
+ return getSubstationStream()
+ .map(Substation::getCountry)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toCollection(() -> EnumSet.noneOf(Country.class)));
+ }
+
+ @Override
+ public int getCountryCount() {
+ return getCountries().size();
+ }
+
+ @Override
+ public Identifiable> getIdentifiable(final String id) {
+ return index.getNetworkStream()
+ .map(n -> n.getIdentifiable(id))
+ .filter(Objects::nonNull)
+ .map(index::getIdentifiable)
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public Collection> getIdentifiables() {
+ return index.getIdentifiables();
+ }
+
+ @Override
+ public SubstationAdderAdapter newSubstation() {
+ return new SubstationAdderAdapter(workingNetwork.newSubstation(), index);
+ }
+
+ @Override
+ public Iterable getSubstations() {
+ return Collections.unmodifiableCollection(index.getSubstations());
+ }
+
+ @Override
+ public Stream getSubstationStream() {
+ return index.getSubstations().stream();
+ }
+
+ @Override
+ public int getSubstationCount() {
+ return index.getSubstations().size();
+ }
+
+ @Override
+ public Iterable getSubstations(final Country country, final String tsoId, final String... geographicalTags) {
+ return getSubstations(Optional.ofNullable(country).map(Country::getName).orElse(null), tsoId, geographicalTags);
+ }
+
+ @Override
+ public Iterable getSubstations(final String country, final String tsoId, final String... geographicalTags) {
+ return StreamSupport.stream(getSubstations().spliterator(), false).filter(substation -> {
+ if (country != null && !country.equals(substation.getCountry().map(Country::getName).orElse(""))) {
+ return false;
+ }
+ if (tsoId != null && !tsoId.equals(substation.getTso())) {
+ return false;
+ }
+ for (final String tag : geographicalTags) {
+ if (!substation.getGeographicalTags().contains(tag)) {
+ return false;
+ }
+ }
+ return true;
+ }).collect(Collectors.toList());
+ }
+
+ @Override
+ public Substation getSubstation(final String id) {
+ return getSubstationStream()
+ .filter(s -> id.compareTo(s.getId()) == 0)
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public Network getNetwork() {
+ return this;
+ }
+
+ // -------------------------------
+ // Not implemented methods -------
+ // -------------------------------
+
+ @Override
+ public VariantManager getVariantManager() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getVoltageLevels() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getVoltageLevelStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getVoltageLevelCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public VoltageLevel getVoltageLevel(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public LineAdder newLine() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getLines() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Branch getBranch(final String branchId) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getBranches() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getBranchStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getBranchCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getLineStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getLineCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Line getLine(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public TieLineAdder newTieLine() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getTwoWindingsTransformers() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getTwoWindingsTransformerStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getTwoWindingsTransformerCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public TwoWindingsTransformer getTwoWindingsTransformer(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getThreeWindingsTransformers() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getThreeWindingsTransformerStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getThreeWindingsTransformerCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public ThreeWindingsTransformer getThreeWindingsTransformer(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getGenerators() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getGeneratorStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getGeneratorCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Generator getGenerator(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getBatteries() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getBatteryStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getBatteryCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Battery getBattery(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getLoads() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getLoadStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getLoadCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Load getLoad(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getShuntCompensators() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getShuntCompensatorStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getShuntCompensatorCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public ShuntCompensator getShuntCompensator(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getDanglingLines() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getDanglingLineStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getDanglingLineCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public DanglingLine getDanglingLine(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getStaticVarCompensators() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getStaticVarCompensatorStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getStaticVarCompensatorCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public StaticVarCompensator getStaticVarCompensator(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Switch getSwitch(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getSwitches() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getSwitchStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getSwitchCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public BusbarSection getBusbarSection(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getBusbarSections() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getBusbarSectionStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getBusbarSectionCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable> getHvdcConverterStations() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream> getHvdcConverterStationStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getHvdcConverterStationCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public HvdcConverterStation> getHvdcConverterStation(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getLccConverterStations() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getLccConverterStationStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getLccConverterStationCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public LccConverterStation getLccConverterStation(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getVscConverterStations() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getVscConverterStationStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getVscConverterStationCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public VscConverterStation getVscConverterStation(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getHvdcLines() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getHvdcLineStream() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getHvdcLineCount() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public HvdcLine getHvdcLine(final String id) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public HvdcLineAdder newHvdcLine() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public BusBreakerView getBusBreakerView() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public BusView getBusView() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public void addListener(final NetworkListener listener) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public void removeListener(final NetworkListener listener) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public > void addExtension(final Class super E> type, final E extension) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public > E getExtension(final Class super E> type) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public > E getExtensionByName(final String name) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public > boolean removeExtension(final Class type) {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public > Collection getExtensions() {
+ throw NOT_IMPLEMENTED_EXCEPTION;
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingViewIndex.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingViewIndex.java
new file mode 100644
index 00000000000..d42907f81ab
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/MergingViewIndex.java
@@ -0,0 +1,110 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.WeakHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.powsybl.commons.PowsyblException;
+import com.powsybl.iidm.network.Identifiable;
+import com.powsybl.iidm.network.Network;
+import com.powsybl.iidm.network.Substation;
+import com.powsybl.iidm.network.VoltageLevel;
+
+/**
+ * @author Thomas Adam
+ */
+class MergingViewIndex {
+
+ /** Local storage for adapters created */
+ private final Map, AbstractAdapter>> adaptersCacheMap = new WeakHashMap<>();
+
+ /** Network asked to be merged */
+ private final Collection networks = new ArrayList<>();
+
+ /** Current merging view reference */
+ private final MergingView currentView;
+
+ /** Constructor */
+ MergingViewIndex(final MergingView currentView) {
+ // Keep reference on current view
+ this.currentView = Objects.requireNonNull(currentView);
+ }
+
+ /** @return current merging view instance */
+ MergingView getView() {
+ return currentView;
+ }
+
+ /** @return stream of merging network */
+ Stream getNetworkStream() {
+ return networks.stream();
+ }
+
+ /** Validate all networks added into merging network list */
+ void checkAndAdd(final Network other) {
+ // Check multi-variants network
+ ValidationUtil.checkSingleyVariant(other);
+ // Check unique identifiable network
+ ValidationUtil.checkUniqueIds(other, this);
+ // Local storage for mergeable network
+ networks.add(other);
+ }
+
+ /** @return adapter according to given parameter */
+ Identifiable> getIdentifiable(final Identifiable> identifiable) {
+ if (identifiable instanceof Substation) {
+ return getSubstation((Substation) identifiable); // container
+ } else if (identifiable instanceof VoltageLevel) {
+ return getVoltageLevel((VoltageLevel) identifiable); // container
+ } else if (identifiable instanceof Network) {
+ return currentView; // container
+ } else {
+ throw new PowsyblException(identifiable.getClass() + " type is not managed in MergingViewIndex.");
+ }
+ }
+
+ /** @return all adapters according to all Identifiables */
+ Stream> getIdentifiableStream() {
+ // Search into merging & working networks and return Adapters
+ return getNetworkStream()
+ .map(Network::getIdentifiables)
+ .filter(n -> !(n instanceof Network))
+ .flatMap(Collection::stream)
+ .map(this::getIdentifiable);
+ }
+
+ /** @return all adapters according to all Identifiables */
+ Collection> getIdentifiables() {
+ // Search into merging & working networks and return Adapters
+ return getIdentifiableStream().collect(Collectors.toList());
+ }
+
+ /** @return all Adapters according to all Substations into merging view */
+ Collection getSubstations() {
+ // Search Substations into merging & working networks and return Adapters
+ return getNetworkStream()
+ .flatMap(Network::getSubstationStream)
+ .map(this::getSubstation)
+ .collect(Collectors.toList());
+ }
+
+ /** @return adapter according to given Substation */
+ SubstationAdapter getSubstation(final Substation substation) {
+ return substation == null ? null : (SubstationAdapter) adaptersCacheMap.computeIfAbsent(substation, key -> new SubstationAdapter((Substation) key, this));
+ }
+
+ /** @return adapter according to given VoltageLevel */
+ VoltageLevelAdapter getVoltageLevel(final VoltageLevel vl) {
+ return vl == null ? null : (VoltageLevelAdapter) adaptersCacheMap.computeIfAbsent(vl, key -> new VoltageLevelAdapter((VoltageLevel) key, this));
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/SubstationAdapter.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/SubstationAdapter.java
new file mode 100644
index 00000000000..aa84db09eac
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/SubstationAdapter.java
@@ -0,0 +1,136 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.powsybl.iidm.network.ContainerType;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.Substation;
+import com.powsybl.iidm.network.ThreeWindingsTransformer;
+import com.powsybl.iidm.network.ThreeWindingsTransformerAdder;
+import com.powsybl.iidm.network.TwoWindingsTransformer;
+import com.powsybl.iidm.network.TwoWindingsTransformerAdder;
+import com.powsybl.iidm.network.VoltageLevel;
+
+/**
+ * @author Thomas Adam
+ */
+class SubstationAdapter extends AbstractAdapter implements Substation {
+
+ SubstationAdapter(final Substation delegate, final MergingViewIndex index) {
+ super(delegate, index);
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter newVoltageLevel() {
+ return new VoltageLevelAdderAdapter(getDelegate().newVoltageLevel(), getIndex());
+ }
+
+ @Override
+ public Stream getVoltageLevelStream() {
+ return getDelegate().getVoltageLevelStream().map(getIndex()::getVoltageLevel);
+ }
+
+ @Override
+ public Iterable getVoltageLevels() {
+ return Collections.unmodifiableSet(getVoltageLevelStream().collect(Collectors.toSet()));
+ }
+
+ // -------------------------------
+ // Not implemented methods -------
+ // -------------------------------
+ @Override
+ public TwoWindingsTransformerAdder newTwoWindingsTransformer() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getTwoWindingsTransformers() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getTwoWindingsTransformerStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public ThreeWindingsTransformerAdder newThreeWindingsTransformer() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getThreeWindingsTransformers() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getThreeWindingsTransformerStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ // -------------------------------
+ // Simple delegated methods ------
+ // -------------------------------
+ @Override
+ public ContainerType getContainerType() {
+ return getDelegate().getContainerType();
+ }
+
+ @Override
+ public Optional getCountry() {
+ return getDelegate().getCountry();
+ }
+
+ @Override
+ public Country getNullableCountry() {
+ return getDelegate().getNullableCountry();
+ }
+
+ @Override
+ public SubstationAdapter setCountry(final Country country) {
+ getDelegate().setCountry(country);
+ return this;
+ }
+
+ @Override
+ public String getTso() {
+ return getDelegate().getTso();
+ }
+
+ @Override
+ public SubstationAdapter setTso(final String tso) {
+ getDelegate().setTso(tso);
+ return this;
+ }
+
+ @Override
+ public int getTwoWindingsTransformerCount() {
+ return getDelegate().getTwoWindingsTransformerCount();
+ }
+
+ @Override
+ public int getThreeWindingsTransformerCount() {
+ return getDelegate().getThreeWindingsTransformerCount();
+ }
+
+ @Override
+ public Set getGeographicalTags() {
+ return getDelegate().getGeographicalTags();
+ }
+
+ @Override
+ public SubstationAdapter addGeographicalTag(final String tag) {
+ getDelegate().addGeographicalTag(tag);
+ return this;
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/SubstationAdderAdapter.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/SubstationAdderAdapter.java
new file mode 100644
index 00000000000..b785f040a13
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/SubstationAdderAdapter.java
@@ -0,0 +1,71 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.Objects;
+
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.SubstationAdder;
+
+/**
+ * @author Thomas Adam
+ */
+class SubstationAdderAdapter implements SubstationAdder {
+
+ private final SubstationAdder delegate;
+
+ private final MergingViewIndex index;
+
+ SubstationAdderAdapter(final SubstationAdder delegate, final MergingViewIndex index) {
+ this.delegate = Objects.requireNonNull(delegate, "delegate is null");
+ this.index = Objects.requireNonNull(index, "merging view index is null");
+ }
+
+ @Override
+ public SubstationAdapter add() {
+ return index.getSubstation(delegate.add());
+ }
+
+ // -------------------------------
+ // Simple delegated methods ------
+ // -------------------------------
+ @Override
+ public SubstationAdderAdapter setId(final String id) {
+ delegate.setId(id);
+ return this;
+ }
+
+ @Override
+ public SubstationAdderAdapter setEnsureIdUnicity(final boolean ensureIdUnicity) {
+ delegate.setEnsureIdUnicity(ensureIdUnicity);
+ return this;
+ }
+
+ @Override
+ public SubstationAdderAdapter setName(final String name) {
+ delegate.setName(name);
+ return this;
+ }
+
+ @Override
+ public SubstationAdderAdapter setCountry(final Country country) {
+ delegate.setCountry(country);
+ return this;
+ }
+
+ @Override
+ public SubstationAdderAdapter setTso(final String tso) {
+ delegate.setTso(tso);
+ return this;
+ }
+
+ @Override
+ public SubstationAdderAdapter setGeographicalTags(final String... tags) {
+ delegate.setGeographicalTags(tags);
+ return this;
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/ValidationUtil.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/ValidationUtil.java
new file mode 100644
index 00000000000..8bec46bbc19
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/ValidationUtil.java
@@ -0,0 +1,43 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+import com.powsybl.commons.PowsyblException;
+import com.powsybl.iidm.network.Identifiable;
+import com.powsybl.iidm.network.Network;
+
+/**
+ * @author Thomas Adam
+ */
+public final class ValidationUtil {
+
+ private ValidationUtil() {
+ }
+
+ public static void checkSingleyVariant(final Network other) {
+ // this check must not be done on the number of variants but on the size
+ // of the internal variant array because the network can have only
+ // one variant but an internal array with a size greater that one and
+ // some re-usable variants
+ if (other.getVariantManager().getVariantIds().size() != 1) {
+ throw new PowsyblException("Merging of multi-variants network is not supported");
+ }
+ }
+
+ public static void checkUniqueIds(final Network other, final MergingViewIndex index) {
+ // check mergeability
+ final Collection otherIds = other.getIdentifiables().stream().map(Identifiable::getId).collect(Collectors.toSet());
+ index.getIdentifiableStream().map(Identifiable::getId).forEach(id -> {
+ if (otherIds.contains(id)) {
+ throw new PowsyblException("The object '" + id + "' already exists into merging view");
+ }
+ });
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/VoltageLevelAdapter.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/VoltageLevelAdapter.java
new file mode 100644
index 00000000000..424f282590b
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/VoltageLevelAdapter.java
@@ -0,0 +1,349 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.Writer;
+import java.nio.file.Path;
+import java.util.Random;
+import java.util.stream.Stream;
+
+import com.powsybl.iidm.network.Battery;
+import com.powsybl.iidm.network.BatteryAdder;
+import com.powsybl.iidm.network.Connectable;
+import com.powsybl.iidm.network.ContainerType;
+import com.powsybl.iidm.network.DanglingLine;
+import com.powsybl.iidm.network.DanglingLineAdder;
+import com.powsybl.iidm.network.Generator;
+import com.powsybl.iidm.network.GeneratorAdder;
+import com.powsybl.iidm.network.LccConverterStation;
+import com.powsybl.iidm.network.LccConverterStationAdder;
+import com.powsybl.iidm.network.Load;
+import com.powsybl.iidm.network.LoadAdder;
+import com.powsybl.iidm.network.ShuntCompensator;
+import com.powsybl.iidm.network.ShuntCompensatorAdder;
+import com.powsybl.iidm.network.StaticVarCompensator;
+import com.powsybl.iidm.network.StaticVarCompensatorAdder;
+import com.powsybl.iidm.network.Switch;
+import com.powsybl.iidm.network.TopologyKind;
+import com.powsybl.iidm.network.TopologyVisitor;
+import com.powsybl.iidm.network.VoltageLevel;
+import com.powsybl.iidm.network.VscConverterStation;
+import com.powsybl.iidm.network.VscConverterStationAdder;
+import com.powsybl.iidm.network.util.ShortIdDictionary;
+
+/**
+ * @author Thomas Adam
+ */
+class VoltageLevelAdapter extends AbstractAdapter implements VoltageLevel {
+
+ public VoltageLevelAdapter(final VoltageLevel delegate, final MergingViewIndex index) {
+ super(delegate, index);
+ }
+
+ @Override
+ public SubstationAdapter getSubstation() {
+ return getIndex().getSubstation(getDelegate().getSubstation());
+ }
+
+ // -------------------------------
+ // Not implemented methods --------------
+ // -------------------------------
+ @Override
+ public T getConnectable(final String id, final Class aClass) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getConnectables(final Class clazz) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getConnectableStream(final Class clazz) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getConnectableCount(final Class clazz) {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getConnectables() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getConnectableStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getConnectableCount() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public GeneratorAdder newGenerator() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getGenerators() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getGeneratorStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public BatteryAdder newBattery() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getBatteries() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getBatteryStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public LoadAdder newLoad() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getLoads() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getLoadStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getSwitches() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public ShuntCompensatorAdder newShuntCompensator() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getShuntCompensators() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getShuntCompensatorStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public DanglingLineAdder newDanglingLine() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getDanglingLines() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getDanglingLineStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public int getDanglingLineCount() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public StaticVarCompensatorAdder newStaticVarCompensator() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getStaticVarCompensators() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getStaticVarCompensatorStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public VscConverterStationAdder newVscConverterStation() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getVscConverterStations() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getVscConverterStationStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public LccConverterStationAdder newLccConverterStation() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Iterable getLccConverterStations() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public Stream getLccConverterStationStream() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public NodeBreakerView getNodeBreakerView() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public BusBreakerView getBusBreakerView() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ @Override
+ public BusView getBusView() {
+ throw MergingView.NOT_IMPLEMENTED_EXCEPTION;
+ }
+
+ // -------------------------------
+ // Simple delegated methods ------
+ // -------------------------------
+ @Override
+ public int getSwitchCount() {
+ return getDelegate().getSwitchCount();
+ }
+
+ @Override
+ public int getGeneratorCount() {
+ return getDelegate().getGeneratorCount();
+ }
+
+ @Override
+ public int getBatteryCount() {
+ return getDelegate().getBatteryCount();
+ }
+
+ @Override
+ public int getLoadCount() {
+ return getDelegate().getLoadCount();
+ }
+
+ @Override
+ public int getStaticVarCompensatorCount() {
+ return getDelegate().getStaticVarCompensatorCount();
+ }
+
+ @Override
+ public int getVscConverterStationCount() {
+ return getDelegate().getVscConverterStationCount();
+ }
+
+ @Override
+ public ContainerType getContainerType() {
+ return getDelegate().getContainerType();
+ }
+
+ @Override
+ public double getNominalV() {
+ return getDelegate().getNominalV();
+ }
+
+ @Override
+ public VoltageLevel setNominalV(final double nominalV) {
+ return getDelegate().setNominalV(nominalV);
+ }
+
+ @Override
+ public double getLowVoltageLimit() {
+ return getDelegate().getLowVoltageLimit();
+ }
+
+ @Override
+ public VoltageLevel setLowVoltageLimit(final double lowVoltageLimit) {
+ return getDelegate().setLowVoltageLimit(lowVoltageLimit);
+ }
+
+ @Override
+ public double getHighVoltageLimit() {
+ return getDelegate().getHighVoltageLimit();
+ }
+
+ @Override
+ public VoltageLevel setHighVoltageLimit(final double highVoltageLimit) {
+ return getDelegate().setHighVoltageLimit(highVoltageLimit);
+ }
+
+ @Override
+ public int getShuntCompensatorCount() {
+ return getDelegate().getShuntCompensatorCount();
+ }
+
+ @Override
+ public int getLccConverterStationCount() {
+ return getDelegate().getLccConverterStationCount();
+ }
+
+ @Override
+ public void visitEquipments(final TopologyVisitor visitor) {
+ getDelegate().visitEquipments(visitor);
+ }
+
+ @Override
+ public TopologyKind getTopologyKind() {
+ return getDelegate().getTopologyKind();
+ }
+
+ @Override
+ public void printTopology() {
+ getDelegate().printTopology();
+ }
+
+ @Override
+ public void printTopology(final PrintStream out, final ShortIdDictionary dict) {
+ getDelegate().printTopology(out, dict);
+ }
+
+ @Override
+ public void exportTopology(final Path file) throws IOException {
+ getDelegate().exportTopology(file);
+ }
+
+ @Override
+ public void exportTopology(final Writer writer, final Random random) throws IOException {
+ getDelegate().exportTopology(writer, random);
+ }
+
+ @Override
+ public void exportTopology(final Writer writer) throws IOException {
+ getDelegate().exportTopology(writer);
+ }
+}
diff --git a/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/VoltageLevelAdderAdapter.java b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/VoltageLevelAdderAdapter.java
new file mode 100644
index 00000000000..9a1fad1011c
--- /dev/null
+++ b/iidm/iidm-mergingview/src/main/java/com/powsybl/iidm/mergingview/VoltageLevelAdderAdapter.java
@@ -0,0 +1,83 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import java.util.Objects;
+
+import com.powsybl.iidm.network.TopologyKind;
+import com.powsybl.iidm.network.VoltageLevelAdder;
+
+/**
+ * @author Thomas Adam
+ */
+class VoltageLevelAdderAdapter implements VoltageLevelAdder {
+
+ private final VoltageLevelAdder delegate;
+
+ private final MergingViewIndex index;
+
+ VoltageLevelAdderAdapter(final VoltageLevelAdder delegate, final MergingViewIndex index) {
+ this.delegate = Objects.requireNonNull(delegate, "delegate is null");
+ this.index = Objects.requireNonNull(index, "merging view index is null");
+ }
+
+ @Override
+ public VoltageLevelAdapter add() {
+ return index.getVoltageLevel(delegate.add());
+ }
+
+ // -------------------------------
+ // Simple delegated methods ------
+ // -------------------------------
+ @Override
+ public VoltageLevelAdderAdapter setId(final String id) {
+ delegate.setId(id);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setEnsureIdUnicity(final boolean ensureIdUnicity) {
+ delegate.setEnsureIdUnicity(ensureIdUnicity);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setName(final String name) {
+ delegate.setName(name);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setNominalV(final double nominalV) {
+ delegate.setNominalV(nominalV);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setLowVoltageLimit(final double lowVoltageLimit) {
+ delegate.setLowVoltageLimit(lowVoltageLimit);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setHighVoltageLimit(final double highVoltageLimit) {
+ delegate.setHighVoltageLimit(highVoltageLimit);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setTopologyKind(final String topologyKind) {
+ delegate.setTopologyKind(topologyKind);
+ return this;
+ }
+
+ @Override
+ public VoltageLevelAdderAdapter setTopologyKind(final TopologyKind topologyKind) {
+ delegate.setTopologyKind(topologyKind);
+ return this;
+ }
+}
diff --git a/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/MergingNetworkTest.java b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/MergingNetworkTest.java
new file mode 100644
index 00000000000..1003ff1d525
--- /dev/null
+++ b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/MergingNetworkTest.java
@@ -0,0 +1,218 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.powsybl.commons.PowsyblException;
+import com.powsybl.iidm.network.ContainerType;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.Network;
+import com.powsybl.iidm.network.Substation;
+import com.powsybl.iidm.network.VariantManagerConstants;
+
+import org.joda.time.DateTime;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+/**
+ * @author Thomas Adam
+ */
+public class MergingNetworkTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private MergingView mergingView;
+ private Network n1;
+ private Network n2;
+ private Network n3;
+
+ @Before
+ public void setup() {
+ mergingView = MergingView.create("MergingNetworkTest", "iidm");
+
+ n1 = Network.create("n1", "iidm");
+ n2 = Network.create("n2", "iidm");
+ n3 = Network.create("n3", "ucte");
+ }
+
+ @Test
+ public void testSetterGetter() {
+ mergingView.merge(n1, n2);
+ assertSame(mergingView, mergingView.getNetwork());
+ assertSame(mergingView, mergingView.getIdentifiable("n1").getNetwork());
+ assertSame(mergingView, mergingView.getIdentifiable("n2").getNetwork());
+ assertEquals("MergingNetworkTest", mergingView.getId());
+ assertEquals("MergingNetworkTest", mergingView.getName());
+
+ final DateTime caseDate = new DateTime();
+ mergingView.setCaseDate(caseDate);
+ assertEquals(caseDate, mergingView.getCaseDate());
+ mergingView.setForecastDistance(3);
+ assertEquals(3, mergingView.getForecastDistance());
+ assertEquals(ContainerType.NETWORK, mergingView.getContainerType());
+
+ assertEquals("iidm", mergingView.getSourceFormat());
+ mergingView.merge(n3);
+ assertEquals("hybrid", mergingView.getSourceFormat());
+
+ // Properties
+ final String key = "keyTest";
+ final String value = "ValueTest";
+ assertFalse(mergingView.hasProperty());
+ mergingView.setProperty(key, value);
+ assertTrue(mergingView.hasProperty(key));
+ assertEquals(value, mergingView.getProperty(key));
+ assertEquals("defaultValue", mergingView.getProperty("noFound", "defaultValue"));
+ assertEquals(1, mergingView.getPropertyNames().size());
+
+ // Identifiables
+ assertFalse("MergingView cannot be empty", mergingView.getIdentifiables().isEmpty());
+
+ // Substations
+ assertTrue(mergingView.getCountries().isEmpty());
+ final Substation s1 = addSubstation(mergingView, "S1", Country.FR);
+ assertSame(mergingView, s1.getNetwork());
+ assertEquals(1, mergingView.getCountryCount());
+ addSubstation(n2, "S2", Country.ES);
+ assertEquals(2, mergingView.getCountryCount());
+ assertNull(mergingView.getSubstation("S0"));
+ assertSame(s1, mergingView.getSubstation("S1"));
+ assertEquals(2, mergingView.getSubstationCount());
+ assertTrue(mergingView.getSubstations(Country.FR, "RTE", "A").iterator().hasNext());
+ assertFalse(mergingView.getSubstations(Country.BE, "RTE", "A").iterator().hasNext());
+ assertFalse(mergingView.getSubstations((String) null, "FAIL").iterator().hasNext());
+ assertTrue(mergingView.getSubstations(Country.ES, null).iterator().hasNext());
+ assertFalse(mergingView.getSubstations(Country.FR, "RTE", "B").iterator().hasNext());
+
+ // Not implemented yet !
+ TestUtil.notImplemented(mergingView::getVariantManager);
+ TestUtil.notImplemented(mergingView::getVoltageLevels);
+ TestUtil.notImplemented(mergingView::getVoltageLevelStream);
+ TestUtil.notImplemented(mergingView::getVoltageLevelCount);
+ TestUtil.notImplemented(() -> mergingView.getVoltageLevel(""));
+ TestUtil.notImplemented(mergingView::newLine);
+ TestUtil.notImplemented(mergingView::getLines);
+ TestUtil.notImplemented(() -> mergingView.getBranch(""));
+ TestUtil.notImplemented(mergingView::getBranches);
+ TestUtil.notImplemented(mergingView::getBranchStream);
+ TestUtil.notImplemented(mergingView::getBranchCount);
+ TestUtil.notImplemented(mergingView::getLineStream);
+ TestUtil.notImplemented(mergingView::getLineCount);
+ TestUtil.notImplemented(() -> mergingView.getLine(""));
+ TestUtil.notImplemented(mergingView::newTieLine);
+ TestUtil.notImplemented(mergingView::getTwoWindingsTransformers);
+ TestUtil.notImplemented(mergingView::getTwoWindingsTransformerStream);
+ TestUtil.notImplemented(mergingView::getTwoWindingsTransformerCount);
+ TestUtil.notImplemented(() -> mergingView.getTwoWindingsTransformer(""));
+ TestUtil.notImplemented(mergingView::getThreeWindingsTransformers);
+ TestUtil.notImplemented(mergingView::getThreeWindingsTransformerStream);
+ TestUtil.notImplemented(mergingView::getThreeWindingsTransformerCount);
+ TestUtil.notImplemented(() -> mergingView.getThreeWindingsTransformer(""));
+ TestUtil.notImplemented(mergingView::getGenerators);
+ TestUtil.notImplemented(mergingView::getGeneratorStream);
+ TestUtil.notImplemented(mergingView::getGeneratorCount);
+ TestUtil.notImplemented(() -> mergingView.getGenerator(""));
+ TestUtil.notImplemented(mergingView::getBatteries);
+ TestUtil.notImplemented(mergingView::getBatteryStream);
+ TestUtil.notImplemented(mergingView::getBatteryCount);
+ TestUtil.notImplemented(() -> mergingView.getBattery(""));
+ TestUtil.notImplemented(mergingView::getLoads);
+ TestUtil.notImplemented(mergingView::getLoadStream);
+ TestUtil.notImplemented(mergingView::getLoadCount);
+ TestUtil.notImplemented(() -> mergingView.getLoad(""));
+ TestUtil.notImplemented(mergingView::getShuntCompensators);
+ TestUtil.notImplemented(mergingView::getShuntCompensatorStream);
+ TestUtil.notImplemented(mergingView::getShuntCompensatorCount);
+ TestUtil.notImplemented(() -> mergingView.getShuntCompensator(""));
+ TestUtil.notImplemented(mergingView::getDanglingLines);
+ TestUtil.notImplemented(mergingView::getDanglingLineStream);
+ TestUtil.notImplemented(mergingView::getDanglingLineCount);
+ TestUtil.notImplemented(() -> mergingView.getDanglingLine(""));
+ TestUtil.notImplemented(mergingView::getStaticVarCompensators);
+ TestUtil.notImplemented(mergingView::getStaticVarCompensatorStream);
+ TestUtil.notImplemented(mergingView::getStaticVarCompensatorCount);
+ TestUtil.notImplemented(() -> mergingView.getStaticVarCompensator(""));
+ TestUtil.notImplemented(() -> mergingView.getSwitch(""));
+ TestUtil.notImplemented(mergingView::getSwitches);
+ TestUtil.notImplemented(mergingView::getSwitchStream);
+ TestUtil.notImplemented(mergingView::getSwitchCount);
+ TestUtil.notImplemented(() -> mergingView.getBusbarSection(""));
+ TestUtil.notImplemented(mergingView::getBusbarSections);
+ TestUtil.notImplemented(mergingView::getBusbarSectionStream);
+ TestUtil.notImplemented(mergingView::getBusbarSectionCount);
+ TestUtil.notImplemented(mergingView::getHvdcConverterStations);
+ TestUtil.notImplemented(mergingView::getHvdcConverterStationStream);
+ TestUtil.notImplemented(mergingView::getHvdcConverterStationCount);
+ TestUtil.notImplemented(() -> mergingView.getHvdcConverterStation(""));
+ TestUtil.notImplemented(mergingView::getLccConverterStations);
+ TestUtil.notImplemented(mergingView::getLccConverterStationStream);
+ TestUtil.notImplemented(mergingView::getLccConverterStationCount);
+ TestUtil.notImplemented(() -> mergingView.getLccConverterStation(""));
+ TestUtil.notImplemented(mergingView::getVscConverterStations);
+ TestUtil.notImplemented(mergingView::getVscConverterStationStream);
+ TestUtil.notImplemented(mergingView::getVscConverterStationCount);
+ TestUtil.notImplemented(() -> mergingView.getVscConverterStation(""));
+ TestUtil.notImplemented(mergingView::getHvdcLines);
+ TestUtil.notImplemented(mergingView::getHvdcLineStream);
+ TestUtil.notImplemented(mergingView::getHvdcLineCount);
+ TestUtil.notImplemented(() -> mergingView.getHvdcLine(""));
+ TestUtil.notImplemented(mergingView::newHvdcLine);
+ TestUtil.notImplemented(mergingView::getBusBreakerView);
+ TestUtil.notImplemented(mergingView::getBusView);
+ TestUtil.notImplemented(() -> mergingView.addListener(null));
+ TestUtil.notImplemented(() -> mergingView.removeListener(null));
+ TestUtil.notImplemented(() -> mergingView.addExtension(null, null));
+ TestUtil.notImplemented(() -> mergingView.getExtension(null));
+ TestUtil.notImplemented(() -> mergingView.getExtensionByName(null));
+ TestUtil.notImplemented(() -> mergingView.removeExtension(null));
+ TestUtil.notImplemented(mergingView::getExtensions);
+ }
+
+ @Test
+ public void failMergeIfMultiVariants() {
+ n1.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, "Failed");
+ thrown.expect(PowsyblException.class);
+ thrown.expectMessage("Merging of multi-variants network is not supported");
+ mergingView.merge(n1);
+ }
+
+ @Test
+ public void failMergeWithSameObj() {
+ addSubstation(n1, "P1", Country.FR);
+ addSubstation(n2, "P1", Country.FR);
+ thrown.expect(PowsyblException.class);
+ thrown.expectMessage("The object 'P1' already exists into merging view");
+ mergingView.merge(n1, n2);
+ }
+
+ @Test
+ public void failAddSameObj() {
+ addSubstation(mergingView, "P1", Country.FR);
+ thrown.expect(PowsyblException.class);
+ thrown.expectMessage("The network MergingNetworkTest already contains an object 'SubstationImpl' with the id 'P1'");
+ addSubstation(mergingView, "P1", Country.FR);
+ }
+
+ private Substation addSubstation(final Network network, final String substationId, final Country country) {
+ return network.newSubstation()
+ .setId(substationId)
+ .setName(substationId)
+ .setEnsureIdUnicity(false)
+ .setCountry(country)
+ .setTso("RTE")
+ .setGeographicalTags("A")
+ .add();
+ }
+}
diff --git a/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/SubstationAdapterTest.java b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/SubstationAdapterTest.java
new file mode 100644
index 00000000000..e6e983ab0f5
--- /dev/null
+++ b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/SubstationAdapterTest.java
@@ -0,0 +1,111 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.powsybl.commons.extensions.Extension;
+import com.powsybl.iidm.network.ContainerType;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.Substation;
+import com.powsybl.iidm.network.TopologyKind;
+import com.powsybl.iidm.network.VoltageLevel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Thomas Adam
+ */
+public class SubstationAdapterTest {
+
+ private MergingView mergingView;
+
+ @Before
+ public void setup() {
+ mergingView = MergingView.create("SubstationAdapterTest", "iidm");
+ }
+
+ @Test
+ public void baseTests() {
+ // adder
+ final Substation substation = mergingView.newSubstation()
+ .setId("sub")
+ .setName("sub_name")
+ .setCountry(Country.AD)
+ .setTso("TSO")
+ .setEnsureIdUnicity(false)
+ .setGeographicalTags("geoTag1", "geoTag2")
+ .add();
+ assertTrue(substation instanceof SubstationAdapter);
+ assertEquals("sub", substation.getId());
+ assertEquals("sub_name", substation.getName());
+ assertEquals(Country.AD, substation.getCountry().orElse(null));
+ assertEquals("TSO", substation.getTso());
+ assertEquals(ContainerType.SUBSTATION, substation.getContainerType());
+
+ // setter and getter
+ substation.setCountry(Country.AF);
+ assertEquals(Country.AF, substation.getCountry().orElse(null));
+ assertEquals(Country.AF, substation.getNullableCountry());
+ substation.setTso("new tso");
+ assertEquals("new tso", substation.getTso());
+ assertEquals(0, substation.getTwoWindingsTransformerCount());
+ assertEquals(0, substation.getThreeWindingsTransformerCount());
+ assertEquals(substation, substation.addGeographicalTag("geoTag3"));
+ assertEquals(3, substation.getGeographicalTags().size());
+
+ // Properties
+ final String key = "keyTest";
+ final String value = "ValueTest";
+ assertFalse(substation.hasProperty());
+ substation.setProperty(key, value);
+ assertTrue(substation.hasProperty(key));
+ assertEquals(value, substation.getProperty(key));
+ assertEquals("defaultValue", substation.getProperty("noFound", "defaultValue"));
+ assertEquals(1, substation.getPropertyNames().size());
+
+ // Extension
+ assertTrue(substation.getExtensions().isEmpty());
+ final SubstationExtensionTest extension = new SubstationExtensionTest(null);
+ assertNotNull(extension);
+ substation.addExtension(SubstationExtensionTest.class, extension);
+ assertSame(extension, substation.getExtension(SubstationExtensionTest.class));
+ assertSame(extension, substation.getExtensionByName("SubstationExtensionTest"));
+ assertNull(substation.getExtension(String.class));
+ assertEquals(1, substation.getExtensions().size());
+ assertArrayEquals(substation.getExtensions().toArray(new Extension[0]), new Extension[] {extension});
+ assertTrue(substation.removeExtension(SubstationExtensionTest.class));
+
+ // VoltageLevel
+ final VoltageLevel v1 = substation.newVoltageLevel()
+ .setTopologyKind(TopologyKind.BUS_BREAKER)
+ .setId("bbVL")
+ .setName("bbVL_name")
+ .setNominalV(200.0)
+ .setLowVoltageLimit(100.0)
+ .setHighVoltageLimit(200.0)
+ .add();
+ assertTrue(v1 instanceof VoltageLevelAdapter);
+ assertTrue(substation.getVoltageLevelStream().findAny().isPresent());
+ assertSame(v1, substation.getVoltageLevels().iterator().next());
+
+ // Not implemented yet !
+ TestUtil.notImplemented(substation::newTwoWindingsTransformer);
+ TestUtil.notImplemented(substation::getTwoWindingsTransformers);
+ TestUtil.notImplemented(substation::getTwoWindingsTransformerStream);
+ TestUtil.notImplemented(substation::newThreeWindingsTransformer);
+ TestUtil.notImplemented(substation::getThreeWindingsTransformers);
+ TestUtil.notImplemented(substation::getThreeWindingsTransformerStream);
+ }
+}
diff --git a/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/SubstationExtensionTest.java b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/SubstationExtensionTest.java
new file mode 100644
index 00000000000..75dfff7f37e
--- /dev/null
+++ b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/SubstationExtensionTest.java
@@ -0,0 +1,27 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import com.powsybl.commons.extensions.AbstractExtension;
+import com.powsybl.iidm.network.Substation;
+
+/**
+ * @author Thomas Adam
+ */
+public class SubstationExtensionTest extends AbstractExtension {
+
+ public SubstationExtensionTest(final Substation substation) {
+ super(substation);
+ }
+
+ @Override
+ public String getName() {
+ return "SubstationExtensionTest";
+ }
+
+}
+
diff --git a/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/TestUtil.java b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/TestUtil.java
new file mode 100644
index 00000000000..650b01990d2
--- /dev/null
+++ b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/TestUtil.java
@@ -0,0 +1,30 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import static org.junit.Assert.fail;
+
+import com.powsybl.commons.PowsyblException;
+
+/**
+ * @author Thomas Adam
+ */
+public final class TestUtil {
+
+ private TestUtil() {
+ }
+
+ static void notImplemented(final Runnable execute) {
+ // Using Try/catch in order to make sure executed code is covered by test
+ try {
+ execute.run();
+ fail("Implementation done -> this test must be updated");
+ } catch (final PowsyblException ex) {
+ // Ignored
+ }
+ }
+}
diff --git a/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/VoltageLevelTest.java b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/VoltageLevelTest.java
new file mode 100644
index 00000000000..9b8b1dcfc53
--- /dev/null
+++ b/iidm/iidm-mergingview/src/test/java/com/powsybl/iidm/mergingview/VoltageLevelTest.java
@@ -0,0 +1,128 @@
+/**
+ * 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/.
+ */
+package com.powsybl.iidm.mergingview;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.powsybl.iidm.network.ContainerType;
+import com.powsybl.iidm.network.Country;
+import com.powsybl.iidm.network.Substation;
+import com.powsybl.iidm.network.TopologyKind;
+import com.powsybl.iidm.network.VoltageLevel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Thomas Adam
+ */
+public class VoltageLevelTest {
+
+ private MergingView mergingView;
+ private Substation substation;
+
+ @Before
+ public void setUp() {
+ mergingView = MergingView.create("VoltageLevelTest", "iidm");
+ substation = mergingView.newSubstation()
+ .setCountry(Country.AF)
+ .setTso("tso")
+ .setName("sub")
+ .setId("subId")
+ .add();
+ }
+
+ @Test
+ public void baseTests() {
+ // adder
+ final VoltageLevel voltageLevel = substation.newVoltageLevel()
+ .setTopologyKind(TopologyKind.BUS_BREAKER)
+ .setTopologyKind(TopologyKind.BUS_BREAKER.name())
+ .setId("bbVL")
+ .setName("bbVL_name")
+ .setNominalV(200.0)
+ .setLowVoltageLimit(100.0)
+ .setHighVoltageLimit(200.0)
+ .setEnsureIdUnicity(false)
+ .add();
+ assertTrue(voltageLevel instanceof VoltageLevelAdapter);
+ assertSame(mergingView, voltageLevel.getNetwork());
+ assertSame(substation, voltageLevel.getSubstation());
+ assertSame(voltageLevel, mergingView.getIdentifiable("bbVL"));
+ assertEquals(ContainerType.VOLTAGE_LEVEL, voltageLevel.getContainerType());
+
+ // setter getter
+ voltageLevel.setHighVoltageLimit(300.0);
+ assertEquals(300.0, voltageLevel.getHighVoltageLimit(), 0.0);
+ voltageLevel.setLowVoltageLimit(200.0);
+ assertEquals(200.0, voltageLevel.getLowVoltageLimit(), 0.0);
+ voltageLevel.setNominalV(500.0);
+ assertEquals(500.0, voltageLevel.getNominalV(), 0.0);
+
+ assertEquals(0, voltageLevel.getShuntCompensatorCount());
+ assertEquals(0, voltageLevel.getLccConverterStationCount());
+ assertEquals(TopologyKind.BUS_BREAKER, voltageLevel.getTopologyKind());
+
+ // Not implemented yet !
+
+ // Generator
+ TestUtil.notImplemented(voltageLevel::newGenerator);
+ TestUtil.notImplemented(voltageLevel::getGenerators);
+ TestUtil.notImplemented(voltageLevel::getGeneratorStream);
+ assertEquals(0, voltageLevel.getGeneratorCount());
+ // Battery
+ TestUtil.notImplemented(voltageLevel::newBattery);
+ TestUtil.notImplemented(voltageLevel::getBatteries);
+ TestUtil.notImplemented(voltageLevel::getBatteryStream);
+ assertEquals(0, voltageLevel.getBatteryCount());
+ // Load
+ TestUtil.notImplemented(voltageLevel::newLoad);
+ TestUtil.notImplemented(voltageLevel::getLoads);
+ TestUtil.notImplemented(voltageLevel::getLoadStream);
+ assertEquals(0, voltageLevel.getLoadCount());
+ // Switch
+ TestUtil.notImplemented(voltageLevel::getSwitches);
+ assertEquals(0, voltageLevel.getSwitchCount());
+ // ShuntCompensator
+ TestUtil.notImplemented(voltageLevel::newShuntCompensator);
+ TestUtil.notImplemented(voltageLevel::getShuntCompensators);
+ TestUtil.notImplemented(voltageLevel::getShuntCompensatorStream);
+ // DanglingLine
+ TestUtil.notImplemented(voltageLevel::newDanglingLine);
+ TestUtil.notImplemented(voltageLevel::getDanglingLines);
+ TestUtil.notImplemented(voltageLevel::getDanglingLineStream);
+ TestUtil.notImplemented(voltageLevel::getDanglingLineCount);
+ // StaticVarCompensator
+ TestUtil.notImplemented(voltageLevel::newStaticVarCompensator);
+ TestUtil.notImplemented(voltageLevel::getStaticVarCompensators);
+ TestUtil.notImplemented(voltageLevel::getStaticVarCompensatorStream);
+ assertEquals(0, voltageLevel.getStaticVarCompensatorCount());
+ // VscConverterStation
+ TestUtil.notImplemented(voltageLevel::newVscConverterStation);
+ TestUtil.notImplemented(voltageLevel::getVscConverterStations);
+ TestUtil.notImplemented(voltageLevel::getVscConverterStationStream);
+ assertEquals(0, voltageLevel.getVscConverterStationCount());
+ // LccConverterStation
+ TestUtil.notImplemented(voltageLevel::newLccConverterStation);
+ TestUtil.notImplemented(voltageLevel::getLccConverterStations);
+ TestUtil.notImplemented(voltageLevel::getLccConverterStationStream);
+ // Bus
+ TestUtil.notImplemented(voltageLevel::getNodeBreakerView);
+ TestUtil.notImplemented(voltageLevel::getBusBreakerView);
+ TestUtil.notImplemented(voltageLevel::getBusView);
+ // Connectables
+ TestUtil.notImplemented(() -> voltageLevel.getConnectable("", null));
+ TestUtil.notImplemented(() -> voltageLevel.getConnectables(null));
+ TestUtil.notImplemented(() -> voltageLevel.getConnectableStream(null));
+ TestUtil.notImplemented(() -> voltageLevel.getConnectableCount(null));
+ TestUtil.notImplemented(voltageLevel::getConnectables);
+ TestUtil.notImplemented(voltageLevel::getConnectableStream);
+ TestUtil.notImplemented(voltageLevel::getConnectableCount);
+ }
+}
diff --git a/iidm/pom.xml b/iidm/pom.xml
index 23ea1eed14d..83d4b6bb749 100644
--- a/iidm/pom.xml
+++ b/iidm/pom.xml
@@ -29,6 +29,7 @@
iidm-converter-api
iidm-extensions
iidm-impl
+ iidm-mergingview
iidm-reducer
iidm-test
iidm-util