Skip to content

Commit

Permalink
Add a circular dependency check on some objects deps
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Bui-Quang <[email protected]>
  • Loading branch information
pl-buiquang committed Jan 6, 2020
1 parent 12c386f commit 99e35c9
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.afs;

/**
* @author Paul Bui-Quang <paul.buiquang at rte-france.com>
*/
public class AfsCircularDependencyException extends AfsException {
public AfsCircularDependencyException(String message) {
super(message);
}

public AfsCircularDependencyException() {
super("Circular dependency detected");
}
}
11 changes: 11 additions & 0 deletions afs-core/src/main/java/com/powsybl/afs/ProjectFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ public void removeDependencies(String name) {
storage.flush();
}

public boolean hasDeepDependency(ProjectFile candidateDependency) {
return hasDeepDependency(candidateDependency, null);
}

public boolean hasDeepDependency(ProjectFile candidateDependency, String dependencyName) {
List<ProjectFile> dependencies = (dependencyName != null) ?
getDependencies(dependencyName, ProjectFile.class) :
getDependencies().stream().map(ProjectDependency::getProjectNode).filter(dep -> ProjectFile.class.isAssignableFrom(dep.getClass())).map(ProjectFile.class::cast).collect(Collectors.toList());
return dependencies.stream().anyMatch(dep -> dep.getId().equals(candidateDependency.getId()) || dep.hasDeepDependency(candidateDependency, dependencyName));
}

public boolean mandatoryDependenciesAreMissing() {
return false;
}
Expand Down
15 changes: 15 additions & 0 deletions afs-core/src/test/java/com/powsybl/afs/AfsBaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,19 @@ public void fetchNodeTest() {
checkResult.accept(projectFolder, afs.fetchNode(projectFolder.getId()));
}

@Test
public void hasDeepDependencyTest() {
Project project = afs.getRootFolder().createProject("test");
FooFile createdFile = project.getRootFolder().fileBuilder(FooFileBuilder.class)
.withName("foo")
.build();
FooFile otherFile = project.getRootFolder().fileBuilder(FooFileBuilder.class)
.withName("bar")
.build();
createdFile.setDependencies("dep", Collections.singletonList(otherFile));
assertTrue(createdFile.hasDeepDependency(otherFile));
assertFalse(createdFile.hasDeepDependency(createdFile));
otherFile.setDependencies("dep", Collections.singletonList(createdFile));
assertTrue(createdFile.hasDeepDependency(createdFile, "dep"));
}
}
4 changes: 4 additions & 0 deletions afs-ext-base/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.powsybl.afs.ext.base;

import com.google.common.io.CharStreams;
import com.powsybl.afs.AfsCircularDependencyException;
import com.powsybl.afs.OrderedDependencyManager;
import com.powsybl.afs.ProjectFile;
import com.powsybl.afs.ProjectFileCreationContext;
Expand Down Expand Up @@ -59,10 +60,16 @@ public List<AbstractScript> getIncludedScripts() {
}

public void addGenericScript(GenericScript genericScript) {
if (genericScript.hasDeepDependency(this) || getId().equals(genericScript.getId())) {
throw new AfsCircularDependencyException();
}
orderedDependencyManager.appendDependencies(INCLUDED_SCRIPTS_DEPENDENCY_NAME, Collections.singletonList(genericScript));
}

public void addScript(T includeScript) {
if (includeScript.hasDeepDependency(this) || getId().equals(includeScript.getId())) {
throw new AfsCircularDependencyException();
}
orderedDependencyManager.appendDependencies(INCLUDED_SCRIPTS_DEPENDENCY_NAME, Collections.singletonList(includeScript));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
*/
package com.powsybl.afs.ext.base;

import com.powsybl.afs.AfsException;
import com.powsybl.afs.DependencyCache;
import com.powsybl.afs.ProjectFile;
import com.powsybl.afs.ProjectFileCreationContext;
import com.powsybl.afs.*;
import com.powsybl.iidm.network.Network;

import java.util.Collections;
Expand Down Expand Up @@ -41,6 +38,9 @@ public Optional<ProjectFile> getCase() {

public void setCase(ProjectFile aCase) {
Objects.requireNonNull(aCase);
if (aCase.hasDeepDependency(this, CASE_DEPENDENCY_NAME) || getId().equals(aCase.getId())) {
throw new AfsCircularDependencyException();
}
setDependencies(CASE_DEPENDENCY_NAME, Collections.singletonList(aCase));
projectCaseDependency.invalidate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.assertThatCode;

/**
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
Expand Down Expand Up @@ -135,5 +136,7 @@ public void test() {
assertEquals(includes.size(), 2);
assertEquals(includes.get(0).getId(), include1.getId());
assertEquals(includes.get(1).getId(), include3.getId());

assertThatCode(() -> script.addScript(script)).isInstanceOf(AfsCircularDependencyException.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.IOException;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.Assert.*;

/**
Expand Down Expand Up @@ -190,5 +191,7 @@ public void test() {

assertNotEquals(importedCase2.getName(), virtualCase3.getCase().map(ProjectFile::getName).orElse(null));
assertEquals(importedCase3.getName(), virtualCase3.getCase().map(ProjectFile::getName).orElse(null));

assertThatCode(() -> virtualCase3.setCase(virtualCase3)).isInstanceOf(AfsCircularDependencyException.class);
}
}

0 comments on commit 99e35c9

Please sign in to comment.