diff --git a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/AbstractSpringIndexElement.java b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/AbstractSpringIndexElement.java index 7e1f90bf6..6bf5faf5a 100644 --- a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/AbstractSpringIndexElement.java +++ b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/AbstractSpringIndexElement.java @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.commons.protocol.spring; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public abstract class AbstractSpringIndexElement implements SpringIndexElement { @@ -24,7 +25,7 @@ public abstract class AbstractSpringIndexElement implements SpringIndexElement { @Override public List getChildren() { - return children; + return Collections.unmodifiableList(this.children); } public void addChild(SpringIndexElement child) { diff --git a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElement.java b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElement.java index 0f4a26879..03bdbeb0c 100644 --- a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElement.java +++ b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElement.java @@ -10,15 +10,22 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.protocol.spring; -import java.util.Iterator; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; -public class ProjectElement extends AbstractSpringIndexElement { +public class ProjectElement implements SpringIndexElement { private String projectName; + + private Map documents; + private List otherElements; public ProjectElement(String projectName) { this.projectName = projectName; + this.documents = new ConcurrentHashMap<>(); + this.otherElements = new ArrayList<>(); } public String getProjectName() { @@ -26,13 +33,36 @@ public class ProjectElement extends AbstractSpringIndexElement { } public void removeDocument(String docURI) { - List children = this.getChildren(); + this.documents.remove(docURI); + } + + @Override + public List getChildren() { + List result = new ArrayList<>(); + + result.addAll(documents.values()); + result.addAll(otherElements); - for (Iterator iterator = children.iterator(); iterator.hasNext();) { - SpringIndexElement springIndexElement = (SpringIndexElement) iterator.next(); - if (springIndexElement instanceof DocumentElement doc && doc.getDocURI().equals(docURI)) { - iterator.remove(); - } + return result; + } + + @Override + public void addChild(SpringIndexElement child) { + if (child instanceof DocumentElement document) { + documents.put(document.getDocURI(), document); + } + else { + otherElements.add(child); + } + } + + @Override + public void removeChild(SpringIndexElement doc) { + if (doc instanceof DocumentElement document) { + documents.remove(document.getDocURI()); + } + else { + otherElements.remove(doc); } } diff --git a/headless-services/commons/commons-lsp-extensions/src/test/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElementTest.java b/headless-services/commons/commons-lsp-extensions/src/test/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElementTest.java new file mode 100644 index 000000000..e763ec6a7 --- /dev/null +++ b/headless-services/commons/commons-lsp-extensions/src/test/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElementTest.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2025 Broadcom + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Broadcom - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.protocol.spring; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.junit.jupiter.api.Test; + +class ProjectElementTest { + + @Test + void testAddDocumentChildren() { + ProjectElement project = new ProjectElement("projectName"); + + List children = project.getChildren(); + assertEquals(0, children.size()); + + DocumentElement doc1 = new DocumentElement("docUri1"); + DocumentElement doc2 = new DocumentElement("docUri2"); + + project.addChild(doc1); + project.addChild(doc2); + + children = project.getChildren(); + assertEquals(2, children.size()); + + assertTrue(children.contains(doc1)); + assertTrue(children.contains(doc2)); + } + + @Test + void testAddNonDocumentChildren() { + ProjectElement project = new ProjectElement("projectName"); + + var child1 = new AbstractSpringIndexElement() {}; + var child2 = new AbstractSpringIndexElement() {}; + + project.addChild(child1); + project.addChild(child2); + + List children = project.getChildren(); + assertEquals(2, children.size()); + + assertTrue(children.contains(child1)); + assertTrue(children.contains(child2)); + } + + @Test + void testMixedProjectChildren() { + ProjectElement project = new ProjectElement("projectName"); + + var doc1 = new DocumentElement("docUri1"); + var doc2 = new DocumentElement("docUri2"); + + project.addChild(doc1); + project.addChild(doc2); + + var child1 = new AbstractSpringIndexElement() {}; + var child2 = new AbstractSpringIndexElement() {}; + + project.addChild(child1); + project.addChild(child2); + + List children = project.getChildren(); + assertEquals(4, children.size()); + + assertTrue(children.contains(child1)); + assertTrue(children.contains(child2)); + assertTrue(children.contains(doc1)); + assertTrue(children.contains(doc2)); + } + + @Test + void testRemoveProjectChildren() { + ProjectElement project = new ProjectElement("projectName"); + + var doc1 = new DocumentElement("docUri1"); + var doc2 = new DocumentElement("docUri2"); + + project.addChild(doc1); + project.addChild(doc2); + + var child1 = new AbstractSpringIndexElement() {}; + var child2 = new AbstractSpringIndexElement() {}; + + project.addChild(child1); + project.addChild(child2); + + project.removeDocument("docUri1"); + List children = project.getChildren(); + assertEquals(3, children.size()); + + assertTrue(children.contains(child1)); + assertTrue(children.contains(child2)); + assertFalse(children.contains(doc1)); + assertTrue(children.contains(doc2)); + + project.removeDocument("docDoesNotExist"); + children = project.getChildren(); + assertEquals(3, children.size()); + + assertTrue(children.contains(child1)); + assertTrue(children.contains(child2)); + assertFalse(children.contains(doc1)); + assertTrue(children.contains(doc2)); + + project.removeChild(child2); + children = project.getChildren(); + assertEquals(2, children.size()); + + assertTrue(children.contains(child1)); + assertFalse(children.contains(child2)); + assertFalse(children.contains(doc1)); + assertTrue(children.contains(doc2)); + } + +}