Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

Commit

Permalink
[#762] process branch contains uris
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Pozzi committed Mar 22, 2022
1 parent d674467 commit 23104f3
Show file tree
Hide file tree
Showing 21 changed files with 213 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* A factory to create {@link NodeMerger} instances.
*/
class NodeMergerFactory {
public class NodeMergerFactory {

private NodeMergerFactory() {
}
Expand Down
37 changes: 25 additions & 12 deletions src/main/java/de/bonndan/nivio/input/ProcessMerger.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package de.bonndan.nivio.input;

import de.bonndan.nivio.input.dto.ProcessDescription;
import de.bonndan.nivio.model.*;
import de.bonndan.nivio.input.dto.RelationDescription;
import de.bonndan.nivio.model.Process;
import de.bonndan.nivio.model.*;
import org.springframework.lang.NonNull;

import java.util.List;
Expand Down Expand Up @@ -35,24 +36,36 @@ public ProcessingChangelog mergeAndDiff(@NonNull final List<ProcessDescription>
@NonNull final ProcessLog log
) {
ProcessingChangelog changelog = nodeMerger.mergeAndDiff(processDescriptions, log);
addMissingRelations(changelog);
changelog.merge(addMissingRelations());
return changelog;
}

private void addMissingRelations(ProcessingChangelog changelog) {
private ProcessingChangelog addMissingRelations() {

final IndexReadAccess<GraphComponent> readAccess = landscape.getReadAccess();

ProcessingChangelog changelog = new ProcessingChangelog();
readAccess.all(Process.class).forEach(process -> changelog.merge(addMissingRelations(process, landscape)));
return changelog;
}

public static ProcessingChangelog addMissingRelations(Process process, Landscape landscape) {

final IndexReadAccess<GraphComponent> readAccess = landscape.getReadAccess();
final GraphWriteAccess<GraphComponent> writeAccess = landscape.getWriteAccess();
final ProcessingChangelog changelog = new ProcessingChangelog();

readAccess.all(Process.class).forEach(
process -> process.getBranches().stream()
.flatMap(branch -> branch.getEdges().stream())
.filter(relation -> readAccess.get(relation.getFullyQualifiedIdentifier()).isEmpty())
.forEach(relation -> {
writeAccess.addOrReplaceRelation(relation);
changelog.addEntry(relation, ProcessingChangelog.ChangeType.CREATED);
})
process.getBranches().stream()
.flatMap(branch -> branch.getEdges().stream())
.filter(uri -> readAccess.get(uri).isEmpty())
.forEach(uri -> {
Item source = (Item) readAccess.get(Relation.parseSourceURI(uri)).orElseThrow();
Item target = (Item) readAccess.get(Relation.parseTargetURI(uri)).orElseThrow();
var relation = RelationFactory.create(source, target, new RelationDescription());
writeAccess.addOrReplaceRelation(relation);
changelog.addEntry(relation, ProcessingChangelog.ChangeType.CREATED);
});

);
return changelog;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.input.dto.RelationDescription;
import de.bonndan.nivio.model.Relation;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

Expand All @@ -22,6 +21,7 @@
public class InputFormatHandlerCSV implements InputFormatHandler {

public static final String IDENTIFIER_KEY = "identifier";
public static final String DELIMITER = ";";

private final FileFetcher fileFetcher;

Expand Down Expand Up @@ -60,8 +60,8 @@ public List<LandscapeDescription> applyData(@NonNull final SourceReference refer

String columnValue = strings[colNum];
if (IDENTIFIER_KEY.equals(key)) {
if (columnValue.contains(Relation.DELIMITER)) {
String[] split = columnValue.split(Relation.DELIMITER);
if (columnValue.contains(DELIMITER)) {
String[] split = columnValue.split(DELIMITER);
itemDescription.setIdentifier(split[0]);
relationDescription = new RelationDescription(split[0], split[1]);
} else {
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/de/bonndan/nivio/model/Branch.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.lang.NonNull;

import java.net.URI;
import java.util.List;
import java.util.Objects;

Expand All @@ -10,16 +11,16 @@
*/
public class Branch {

private final List<Relation> edges;
private final List<URI> edges;

/**
* @param edges add relations of this branch. Start and/or end are part of other branches.
*/
public Branch(@NonNull final List<Relation> edges) {
public Branch(@NonNull final List<URI> edges) {
this.edges = Objects.requireNonNull(edges);
}

public List<Relation> getEdges() {
public List<URI> getEdges() {
return edges;
}
}
27 changes: 20 additions & 7 deletions src/main/java/de/bonndan/nivio/model/GraphWriteAccess.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.bonndan.nivio.model;

import org.springframework.lang.NonNull;

import java.net.URI;
import java.util.Objects;

Expand All @@ -9,9 +11,9 @@ public class GraphWriteAccess<T extends GraphComponent> {
private final Index<T> index;
private final IndexReadAccess<T> readAccess;

public GraphWriteAccess(Index<T> index, IndexReadAccess<T> readAccess) {
this.index = index;
this.readAccess = readAccess;
public GraphWriteAccess(@NonNull final Index<T> index, @NonNull final IndexReadAccess<T> readAccess) {
this.index = Objects.requireNonNull(index);
this.readAccess = Objects.requireNonNull(readAccess);
}

/**
Expand Down Expand Up @@ -52,13 +54,24 @@ public T addOrReplaceChild(T added) {
* @return true if successful
*/
public boolean removeChild(T node) {
T parent = (T) node.getParent();
@SuppressWarnings("unchecked") T parent = (T) node.getParent();
return index.removeChild(parent, node);
}

public void addOrReplaceRelation(Relation relation) {
relation.attach(readAccess);
index.addOrReplace(relation).ifPresent(Relation::detach);
/**
* Adds a relation to the index.
*
* If a similar relation exists, it is removed and detached from index access.
*
* @param relation relation to add
*/
public void addOrReplaceRelation(@NonNull final Relation relation) {
Objects.requireNonNull(relation).attach(readAccess);
index.addOrReplace(relation).ifPresent(relation1 -> {
if (relation1 != relation) { //safety net
relation1.detach();
}
});
}

public void removeRelation(Relation relation) {
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/de/bonndan/nivio/model/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ public Index(@NonNull final SearchIndex searchIndex) {
/**
* Returns for node for an URI.
*/
public Optional<T> get(URI uri) {
public Optional<T> get(@NonNull final URI uri) {
if (ComponentClass.relation.name().equals(uri.getScheme())) {
URI target = Relation.parseTargetURI(uri);
return edges.columnMap().get(target).values().stream()
.filter(relation -> relation.getFullyQualifiedIdentifier().equals(uri))
.map(relation -> (T)relation)
.findFirst();
}
return Optional.ofNullable(nodes.get(uri));
}

Expand All @@ -52,6 +59,10 @@ public List<T> getChildren(@NonNull final URI uri) {
.collect(Collectors.toList());
}

/**
* @param uri uri of an endpoint
* @return all inbound and outbound relations
*/
public Set<Relation> getRelations(@NonNull final URI uri) {
Map<URI, Relation> outgoing = edges.rowMap().get(Objects.requireNonNull(uri));
if (outgoing == null) {
Expand Down
5 changes: 0 additions & 5 deletions src/main/java/de/bonndan/nivio/model/Landscape.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,6 @@ public Map<URI, Group> getGroups() {
.collect(Collectors.toMap(GraphComponent::getFullyQualifiedIdentifier, group -> group));
}

@JsonGetter("groups")
public Collection<Group> getGroupItems() {
return getReadAccess().all(Group.class);
}

@JsonIgnore
public ProcessLog getLog() {
return processLog;
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/de/bonndan/nivio/model/Process.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -53,6 +50,9 @@ public List<Branch> getBranches() {
public Set<Assessable> getAssessables() {
return branches.stream()
.flatMap(branch -> branch.getEdges().stream())
.map(uri -> indexReadAccess.findRelation(Relation.parseSourceURI(uri), Relation.parseTargetURI(uri))
.orElseThrow(()->new NoSuchElementException(String.format("%s not present", uri)))
)
.collect(Collectors.toSet());
}

Expand Down
26 changes: 8 additions & 18 deletions src/main/java/de/bonndan/nivio/model/ProcessFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -53,7 +54,7 @@ public Process createFromDescription(@NonNull final String identifier,
validateGraph(itemsPerBranch);

var branches = itemsPerBranch.stream()
.map(branchNodes -> createBranchWithRelations(parent.getWriteAccess(), branchNodes))
.map(ProcessFactory::createBranchWithRelations)
.collect(Collectors.toList());

return new Process(identifier,
Expand All @@ -71,38 +72,27 @@ public Process createFromDescription(@NonNull final String identifier,
*
* Creates relations if absent.
*
* @param writeAccess
* @param branchNodes items
* @return a new branch
*/
private static Branch createBranchWithRelations(GraphWriteAccess<GraphComponent> writeAccess, final List<Item> branchNodes) {
List<Relation> relations = new ArrayList<>();
private static Branch createBranchWithRelations(final List<Item> branchNodes) {
List<URI> relations = new ArrayList<>();
for (int i = 0; i < branchNodes.size(); i++) {
Item item = branchNodes.get(i);
if (i == branchNodes.size() - 1) {
break;
}
Item next = branchNodes.get(i + 1);
Relation relation1 = item.getRelations().stream().filter(relation -> relation.getSource().equals(item) && relation.getTarget().equals(next))
Relation relation = item.getRelations().stream()
.filter(relation1 -> relation1.getSource().equals(item) && relation1.getTarget().equals(next))
.findFirst()
.orElseGet(() -> {
Relation created = createRelation(item, next);
writeAccess.addOrReplaceRelation(created);
return created;
});
relations.add(relation1);
.orElseGet(() -> RelationFactory.create(item, next, new RelationDescription()));
relations.add(relation.getFullyQualifiedIdentifier());
}

return new Branch(relations);
}

@NonNull
private static Relation createRelation(Item item, Item next) {
RelationDescription description = new RelationDescription();
description.setType(RelationType.DATAFLOW);
return RelationFactory.create(item, next, description);
}

/**
* Ensures that each branch is connected to at least one node of the other branches.
*
Expand Down
40 changes: 36 additions & 4 deletions src/main/java/de/bonndan/nivio/model/Relation.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
public class Relation implements Component, Assessable {

public static final String DELIMITER = ";";
public static final String TO = "to=";

protected final URI sourceURI;

Expand Down Expand Up @@ -57,14 +57,40 @@ public Relation(@NonNull final GraphComponent source,
this.fullyQualifiedIdentifier = new URI(Relation.class.getSimpleName().toLowerCase(Locale.ROOT),
source.getFullyQualifiedIdentifier().getAuthority(),
source.getFullyQualifiedIdentifier().getPath(),
"to=" + target.getFullyQualifiedIdentifier(),
TO + target.getFullyQualifiedIdentifier(),
null
);
} catch (URISyntaxException e) {
throw new ProcessingException("Failed to generate fqi", e);
}
}

/**
* @param uri relation uri
* @return the relation source item uri
*/
public static URI parseSourceURI(@NonNull final URI uri) {

if (!uri.getScheme().equals(ComponentClass.relation.name())) {
throw new IllegalArgumentException(String.format("Relation URI must be given, was: %s", uri));
}

return URI.create(ComponentClass.item.name() + "://" + Objects.requireNonNull(uri).getAuthority() + uri.getPath());
}

/**
* @param uri relation uri
* @return the relation target item uri
*/
public static URI parseTargetURI(URI uri) {

if (!uri.getScheme().equals(ComponentClass.relation.name())) {
throw new IllegalArgumentException(String.format("Relation URI must be given, was: %s", uri));
}

return URI.create(uri.getQuery().replace(TO, ""));
}

@Override
@NonNull
public String getIdentifier() {
Expand Down Expand Up @@ -129,12 +155,18 @@ public URI getTargetURI() {

@NonNull
public Item getTarget() {
if (!isAttached()) {
throw new IllegalStateException(String.format("Relation %s is already detached", fullyQualifiedIdentifier));
}
return (Item) indexReadAccess.get(targetURI)
.orElseThrow(() -> new NoSuchElementException(String.format("Source %s not in index.", sourceURI)));
}

@NonNull
public Item getSource() {
if (!isAttached()) {
throw new IllegalStateException(String.format("Relation %s is already detached", fullyQualifiedIdentifier));
}
return (Item) indexReadAccess.get(sourceURI)
.orElseThrow(() -> new NoSuchElementException(String.format("Source %s not in index.", sourceURI)));
}
Expand Down Expand Up @@ -205,8 +237,8 @@ public String toString() {
return fullyQualifiedIdentifier.toString();
}

void attach(IndexReadAccess<? extends GraphComponent> indexReadAccess) {
this.indexReadAccess = indexReadAccess;
void attach(@NonNull final IndexReadAccess<? extends GraphComponent> indexReadAccess) {
this.indexReadAccess = Objects.requireNonNull(indexReadAccess);
}

void detach() {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/de/bonndan/nivio/model/Unit.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public Landscape getParent() {

@NonNull
@Override
public Set<Group> getChildren() {
return getChildren(component -> true, Group.class);
public Set<Context> getChildren() {
return getChildren(component -> true, Context.class);
}
}
Loading

0 comments on commit 23104f3

Please sign in to comment.