Skip to content

Commit 011e427

Browse files
authored
Delete relationships on RelatedElementCollection.remove (#127)
Fixes #126 Signed-off-by: Gary O'Neall <[email protected]>
1 parent 8319660 commit 011e427

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

src/main/java/org/spdx/library/model/RelatedElementCollection.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
import java.util.ArrayList;
2121
import java.util.Collection;
2222
import java.util.Collections;
23+
import java.util.HashSet;
2324
import java.util.Iterator;
2425
import java.util.List;
2526
import java.util.Objects;
2627
import java.util.Optional;
28+
import java.util.Set;
2729

2830
import javax.annotation.Nullable;
2931

@@ -32,6 +34,8 @@
3234
import org.spdx.library.InvalidSPDXAnalysisException;
3335
import org.spdx.library.SpdxConstants;
3436
import org.spdx.library.model.enumerations.RelationshipType;
37+
import org.spdx.storage.IModelStore;
38+
import org.spdx.storage.IModelStore.IModelStoreLock;
3539

3640
/**
3741
* Collection of SPDX elements related to an SpdxElement
@@ -50,6 +54,10 @@ public class RelatedElementCollection implements Collection<SpdxElement> {
5054
ModelCollection<Relationship> relationshipCollection;
5155
private RelationshipType relationshipTypeFilter;
5256
private String relatedElementTypeFilter;
57+
/**
58+
* Keeps track of any created relationships so we can delete them when removed
59+
*/
60+
private Set<String> createdRelationshipIds = new HashSet<>();
5361

5462
private SpdxElement owningElement;
5563

@@ -170,8 +178,15 @@ public boolean add(SpdxElement e) {
170178
return false;
171179
}
172180
try {
173-
Relationship relationship = owningElement.createRelationship(e, relationshipTypeFilter, null);
174-
return owningElement.addRelationship(relationship);
181+
IModelStoreLock lock = owningElement.getModelStore()
182+
.enterCriticalSection(owningElement.getDocumentUri(), false);
183+
try {
184+
Relationship relationship = owningElement.createRelationship(e, relationshipTypeFilter, null);
185+
createdRelationshipIds.add(relationship.getId());
186+
return owningElement.addRelationship(relationship);
187+
} finally {
188+
owningElement.getModelStore().leaveCriticalSection(lock);
189+
}
175190
} catch (InvalidSPDXAnalysisException e1) {
176191
logger.error("Error adding relationship",e1);
177192
throw new RuntimeException(e1);
@@ -199,7 +214,28 @@ public boolean remove(Object o) {
199214
if (relatedElement.isPresent() &&
200215
relatedElement.get().equals(o) &&
201216
relationship.getRelationshipType().equals(relationshipTypeFilter)) {
202-
return relationshipCollection.remove(relationship);
217+
IModelStore modelStore = relationship.getModelStore();
218+
String documentUri = relationship.getDocumentUri();
219+
final IModelStoreLock lock = modelStore.enterCriticalSection(documentUri, false);
220+
try {
221+
if (relationshipCollection.remove(relationship)) {
222+
try {
223+
if (createdRelationshipIds.contains(relationship.getId())) {
224+
createdRelationshipIds.remove(relationship.getId());
225+
modelStore.delete(documentUri, relationship.getId());
226+
}
227+
} catch (SpdxIdInUseException ex) {
228+
// This is possible if the relationship is in use
229+
// outside of the RelatedElementCollection - just ignore
230+
// the exception
231+
}
232+
return true;
233+
} else {
234+
return false;
235+
}
236+
} finally {
237+
modelStore.leaveCriticalSection(lock);
238+
}
203239
}
204240
} catch (InvalidSPDXAnalysisException e) {
205241
logger.error("Error getting relationship properties - skipping removal of element",e);

src/test/java/org/spdx/library/model/SpdxDocumentTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.commons.lang3.StringUtils;
2727
import org.spdx.library.DefaultModelStore;
2828
import org.spdx.library.InvalidSPDXAnalysisException;
29+
import org.spdx.library.ModelCopyManager;
2930
import org.spdx.library.Version;
3031
import org.spdx.library.model.enumerations.AnnotationType;
3132
import org.spdx.library.model.enumerations.ChecksumAlgorithm;
@@ -652,5 +653,24 @@ public void testSetSpecVersion() throws InvalidSPDXAnalysisException {
652653
doc.setSpecVersion(ver);
653654
assertEquals(ver, doc.getSpecVersion());
654655
}
656+
657+
// Test for issue 126 - removing a documentDescribes not properly decrementing use counts
658+
public void testRemoveDescribes() throws InvalidSPDXAnalysisException {
659+
IModelStore modelStore = new InMemSpdxStore();
660+
String docUri = "https://some.doc.uri";
661+
ModelCopyManager copyManager = new ModelCopyManager();
662+
SpdxDocument doc = new SpdxDocument(modelStore, docUri, copyManager, true);
663+
String describedElementId = "describedElement";
664+
SpdxElement describedElement = new GenericSpdxElement(modelStore, docUri, describedElementId, copyManager, true);
665+
assertEquals(0, doc.getDocumentDescribes().size());
666+
assertEquals(0, doc.getRelationships().size());
667+
doc.getDocumentDescribes().add(describedElement);
668+
assertEquals(1, doc.getDocumentDescribes().size());
669+
assertEquals(1, doc.getRelationships().size());
670+
Relationship rel = doc.getRelationships().toArray(new Relationship[1])[0];
671+
assertEquals(describedElement, rel.getRelatedSpdxElement().get());
672+
doc.getDocumentDescribes().remove(describedElement);
673+
modelStore.delete(docUri, describedElementId);
674+
}
655675

656676
}

0 commit comments

Comments
 (0)