From 52af186175c5f73d6ac0d48a924fedf9a844721a Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Wed, 8 May 2024 23:14:25 +0200 Subject: [PATCH 01/12] allow tagging of repositories e.g. add a property tags="baseline,release, foo";\ to a Repository in build.bnd tags="baseline,release, foo";\ Signed-off-by: Christoph Rueger --- .../bnd/osgi/repository/BaseRepository.java | 10 ++++++- .../src/aQute/bnd/service/Tagged.java | 27 +++++++++++++++++++ .../maven/provider/Configuration.java | 5 ++++ .../maven/provider/MavenBndRepository.java | 6 +++++ bndtools.core/_plugin.xml | 1 + 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java index e409e1cd3f..42bdc3f9a5 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java @@ -25,16 +25,20 @@ import aQute.bnd.exceptions.Exceptions; import aQute.bnd.osgi.resource.ResourceUtils; +import aQute.bnd.service.Tagged; /** * WARNING ! Not tested */ -public abstract class BaseRepository implements Repository { +public abstract class BaseRepository implements Repository, Tagged { private static final RequirementExpression[] EMPTY = new RequirementExpression[0]; static IdentityExpression all; private final PromiseFactory promiseFactory = new PromiseFactory( PromiseFactory.inlineExecutor()); + private static final String DEFAULT_TAG = "all"; + private static final List DEFAULT_TAGS = List.of(DEFAULT_TAG); + static { Requirement requireAll = ResourceUtils.createWildcardRequirement(); all = () -> requireAll; @@ -244,4 +248,8 @@ public RequirementBuilder addAttribute(String name, Object value) { }; } + @Override + public List getTags() { + return DEFAULT_TAGS; + } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java new file mode 100644 index 0000000000..71861ec68b --- /dev/null +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java @@ -0,0 +1,27 @@ +package aQute.bnd.service; + +import java.util.Arrays; +import java.util.List; + +/** + * Allows to add tags to implementing classes. Originally intended for tagging + * repositories. + */ +public interface Tagged { + + /** + * @return a non-null list of tags. + */ + List getTags(); + + static List toTags(String csvTags) { + if (csvTags == null || csvTags.isBlank()) { + return List.of("all"); // default + } + + return Arrays.stream(csvTags.split(",")) + .map(String::trim) + .toList(); + } + +} diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/Configuration.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/Configuration.java index 14fa4a320f..c311b257c0 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/Configuration.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/Configuration.java @@ -76,4 +76,9 @@ public interface Configuration { * Extensions for files that contain multiple JARs */ String multi(); + + /** + * @return a comma separated list of tags. + */ + String tags(); } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java index b750ef71a1..b96ee9f2bd 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java @@ -68,6 +68,7 @@ import aQute.bnd.service.Registry; import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryPlugin; +import aQute.bnd.service.Tagged; import aQute.bnd.service.clipboard.Clipboard; import aQute.bnd.service.maven.PomOptions; import aQute.bnd.service.maven.ToDependencyPom; @@ -1074,4 +1075,9 @@ public String getStatus() { public boolean isRemote() { return remote; } + + @Override + public List getTags() { + return Tagged.toTags(configuration.tags()); + } } diff --git a/bndtools.core/_plugin.xml b/bndtools.core/_plugin.xml index c44c5e31a1..860f87b641 100644 --- a/bndtools.core/_plugin.xml +++ b/bndtools.core/_plugin.xml @@ -899,6 +899,7 @@ helpUrl="https://bnd.bndtools.org/plugins/maven.html" rank="10"> + From ea7740d6139c4cc88d55ecd07ccd958cf1d32e1c Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Wed, 8 May 2024 23:20:03 +0200 Subject: [PATCH 02/12] use Set Signed-off-by: Christoph Rueger --- .../aQute/bnd/osgi/repository/BaseRepository.java | 4 ++-- biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java | 12 +++++++----- .../maven/provider/MavenBndRepository.java | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java index 42bdc3f9a5..1baf34e565 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java @@ -37,7 +37,7 @@ public abstract class BaseRepository implements Repository, Tagged { PromiseFactory.inlineExecutor()); private static final String DEFAULT_TAG = "all"; - private static final List DEFAULT_TAGS = List.of(DEFAULT_TAG); + private static final Set DEFAULT_TAGS = Set.of(DEFAULT_TAG); static { Requirement requireAll = ResourceUtils.createWildcardRequirement(); @@ -249,7 +249,7 @@ public RequirementBuilder addAttribute(String name, Object value) { } @Override - public List getTags() { + public Set getTags() { return DEFAULT_TAGS; } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java index 71861ec68b..d2ec0a1517 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java @@ -1,7 +1,9 @@ package aQute.bnd.service; import java.util.Arrays; -import java.util.List; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.stream.Collectors; /** * Allows to add tags to implementing classes. Originally intended for tagging @@ -12,16 +14,16 @@ public interface Tagged { /** * @return a non-null list of tags. */ - List getTags(); + Set getTags(); - static List toTags(String csvTags) { + static Set toTags(String csvTags) { if (csvTags == null || csvTags.isBlank()) { - return List.of("all"); // default + return Set.of("all"); // default } return Arrays.stream(csvTags.split(",")) .map(String::trim) - .toList(); + .collect(Collectors.toCollection(LinkedHashSet::new)); } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java index b96ee9f2bd..1c7554b08c 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java @@ -1077,7 +1077,7 @@ public boolean isRemote() { } @Override - public List getTags() { + public Set getTags() { return Tagged.toTags(configuration.tags()); } } From 359a405089bab0ad54b68ad75d794c8f28b9d44b Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Thu, 9 May 2024 00:34:47 +0200 Subject: [PATCH 03/12] add tagged support to more repos and edit dialog Signed-off-by: Christoph Rueger --- .../src/aQute/bnd/service/package-info.java | 2 +- .../src/aQute/lib/deployer/FileRepo.java | 16 +++++++++++++++- .../src/aQute/lib/deployer/packageinfo | 2 +- .../deployer/repository/LocalIndexedRepo.java | 10 ++++++++++ .../bnd/deployer/repository/package-info.java | 2 +- .../maven/pom/provider/BndPomRepository.java | 6 ++++++ .../maven/pom/provider/PomConfiguration.java | 5 +++++ .../maven/pom/provider/package-info.java | 2 +- .../bnd/repository/osgi/OSGiRepository.java | 9 +++++++++ .../src/aQute/bnd/repository/osgi/packageinfo | 2 +- .../bnd/repository/p2/provider/P2Config.java | 5 +++++ .../bnd/repository/p2/provider/P2Repository.java | 7 +++++++ .../bnd/repository/p2/provider/package-info.java | 2 +- bndtools.core/_plugin.xml | 7 ++++++- 14 files changed, 69 insertions(+), 8 deletions(-) diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/package-info.java b/biz.aQute.bndlib/src/aQute/bnd/service/package-info.java index 366d1c0aaf..6a9f0a0594 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/package-info.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/package-info.java @@ -1,4 +1,4 @@ -@Version("4.8.0") +@Version("4.9.0") package aQute.bnd.service; import org.osgi.annotation.versioning.Version; diff --git a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java index 6f50b0ddc9..08d7f554c0 100644 --- a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java +++ b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java @@ -14,6 +14,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.jar.Manifest; @@ -34,6 +35,7 @@ import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; +import aQute.bnd.service.Tagged; import aQute.bnd.service.repository.SearchableRepository.ResourceDescriptor; import aQute.bnd.version.Version; import aQute.lib.collections.SortedList; @@ -75,7 +77,7 @@ */ @aQute.bnd.annotation.plugin.BndPlugin(name = "Filerepo", parameters = FileRepo.Config.class) -public class FileRepo implements Plugin, RepositoryPlugin, Refreshable, RegistryPlugin, Actionable, Closeable { +public class FileRepo implements Plugin, RepositoryPlugin, Refreshable, RegistryPlugin, Actionable, Closeable, Tagged { private final static Logger logger = LoggerFactory.getLogger(FileRepo.class); interface Config { @@ -143,6 +145,11 @@ interface Config { */ public final static String NAME = "name"; + /** + * A comma-separated list of tags. + */ + public final static String TAGS = "tags"; + /** * Should this file repo have an index? Either true or false (absent) */ @@ -252,6 +259,7 @@ interface Config { String name; boolean inited; boolean trace; + String tags; PersistentMap index; private boolean hasIndex; @@ -336,6 +344,7 @@ public void setProperties(Map map) { action = map.get(CMD_AFTER_ACTION); trace = Boolean.parseBoolean(map.get(TRACE)); + tags = map.get(TAGS); } /** @@ -1048,4 +1057,9 @@ private ResourceDescriptor buildDescriptor(File f, Jar jar, byte[] digest, Strin public void setIndex(boolean b) { hasIndex = b; } + + @Override + public Set getTags() { + return Tagged.toTags(tags); + } } diff --git a/biz.aQute.bndlib/src/aQute/lib/deployer/packageinfo b/biz.aQute.bndlib/src/aQute/lib/deployer/packageinfo index c2664475cd..b1793a21a7 100644 --- a/biz.aQute.bndlib/src/aQute/lib/deployer/packageinfo +++ b/biz.aQute.bndlib/src/aQute/lib/deployer/packageinfo @@ -1 +1 @@ -version 1.0.1 \ No newline at end of file +version 1.1.0 \ No newline at end of file diff --git a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java index 199b75597a..4aa7391b36 100644 --- a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java +++ b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java @@ -40,6 +40,7 @@ import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.ResourceHandle; import aQute.bnd.service.ResourceHandle.Location; +import aQute.bnd.service.Tagged; import aQute.bnd.version.Version; import aQute.bnd.version.VersionRange; import aQute.lib.hex.Hex; @@ -61,6 +62,7 @@ public class LocalIndexedRepo extends AbstractIndexedRepo implements Refreshable public static final String PROP_PRETTY = "pretty"; public static final String PROP_OVERWRITE = "overwrite"; public static final String PROP_ONLYDIRS = "onlydirs"; + public static final String PROP_TAGS = "tags"; // not actually used (yet). Just to get some parameters interface Config { @@ -81,6 +83,7 @@ interface Config { private boolean overwrite = true; private File storageDir; private String onlydirs = null; + private String tags = null; // @GuardedBy("newFilesInCoordination") private final List newFilesInCoordination = new ArrayList<>(); @@ -132,6 +135,8 @@ public synchronized void setProperties(Map map) { throw new IllegalArgumentException( String.format("Cannot create repository cache: '%s' already exists but is not directory.", cacheDir.getAbsolutePath())); + + tags = map.get(PROP_TAGS); } @Override @@ -614,4 +619,9 @@ public String title(Object... target) throws Exception { public void close() {} + @Override + public Set getTags() { + return Tagged.toTags(tags); + } + } diff --git a/biz.aQute.repository/src/aQute/bnd/deployer/repository/package-info.java b/biz.aQute.repository/src/aQute/bnd/deployer/repository/package-info.java index 70c3d89086..3949f66f82 100644 --- a/biz.aQute.repository/src/aQute/bnd/deployer/repository/package-info.java +++ b/biz.aQute.repository/src/aQute/bnd/deployer/repository/package-info.java @@ -1,4 +1,4 @@ -@Version("5.0.0") +@Version("5.1.0") package aQute.bnd.deployer.repository; import org.osgi.annotation.versioning.Version; diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java index c6bc7856c9..61814dcffc 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; @@ -44,6 +45,7 @@ import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; +import aQute.bnd.service.Tagged; import aQute.bnd.service.clipboard.Clipboard; import aQute.bnd.service.repository.Prepare; import aQute.bnd.util.repository.DownloadListenerPromise; @@ -507,4 +509,8 @@ private Archive trySources(String bsn, Version version) throws Exception { .getOther(Archive.JAR_EXTENSION, Archive.SOURCES_CLASSIFIER); } + @Override + public Set getTags() { + return Tagged.toTags(configuration.tags()); + } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/PomConfiguration.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/PomConfiguration.java index 30a44a6987..b1ac8b3d38 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/PomConfiguration.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/PomConfiguration.java @@ -93,4 +93,9 @@ public interface PomConfiguration { */ boolean dependencyManagement(boolean deflt); + /** + * @return a comma separated list of tags. + */ + String tags(); + } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/package-info.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/package-info.java index e4e783ee1f..0d50e3104f 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/package-info.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/package-info.java @@ -1,4 +1,4 @@ -@Version("2.1.0") +@Version("2.2.0") package aQute.bnd.repository.maven.pom.provider; import org.osgi.annotation.versioning.Version; diff --git a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java index bbcc47c6dc..2099f5ac33 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java @@ -12,6 +12,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.SortedSet; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -38,6 +39,7 @@ import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; +import aQute.bnd.service.Tagged; import aQute.bnd.service.repository.Prepare; import aQute.bnd.util.repository.DownloadListenerPromise; import aQute.bnd.version.Version; @@ -66,6 +68,8 @@ interface Config { String name(); + String tags(); + int poll_time(int pollTimeInSecs); } @@ -410,4 +414,9 @@ private void status(String s) { .concat(s); } } + + @Override + public Set getTags() { + return Tagged.toTags(config.tags()); + } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/osgi/packageinfo b/biz.aQute.repository/src/aQute/bnd/repository/osgi/packageinfo index 3ef1862dd5..d96c0b8c06 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/osgi/packageinfo +++ b/biz.aQute.repository/src/aQute/bnd/repository/osgi/packageinfo @@ -1 +1 @@ -version 1.1.1 \ No newline at end of file +version 1.2.0 \ No newline at end of file diff --git a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Config.java b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Config.java index 5cab944037..76ab6513a5 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Config.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Config.java @@ -32,6 +32,11 @@ public interface P2Config { */ String location(String string); + /** + * @return a comma separated list of tags. + */ + String tags(); + /** * If not set or false, this assumes a P2 repository, i.e. the url points to * a P2 repository directory. If set to true, the url is assumed to point to diff --git a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java index 3803bfaf52..04e08f054c 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java @@ -9,6 +9,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.SortedSet; import org.osgi.resource.Capability; @@ -25,6 +26,7 @@ import aQute.bnd.service.Registry; import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryPlugin; +import aQute.bnd.service.Tagged; import aQute.bnd.version.Version; import aQute.lib.converter.Converter; import aQute.lib.io.IO; @@ -193,4 +195,9 @@ public String title(Object... target) throws Exception { return null; } + @Override + public Set getTags() { + return Tagged.toTags(config.tags()); + } + } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/package-info.java b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/package-info.java index 61e5c7bb43..864b955a3d 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/package-info.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/package-info.java @@ -1,4 +1,4 @@ -@Version("1.4.0") +@Version("1.5.0") package aQute.bnd.repository.p2.provider; import org.osgi.annotation.versioning.Version; diff --git a/bndtools.core/_plugin.xml b/bndtools.core/_plugin.xml index 860f87b641..5b4acfedc7 100644 --- a/bndtools.core/_plugin.xml +++ b/bndtools.core/_plugin.xml @@ -839,6 +839,7 @@ helpUrl="https://bnd.bndtools.org/plugins/filerepo.html"> + @@ -849,6 +850,7 @@ helpUrl="https://bnd.bndtools.org/plugins/osgirepo.html"> + + + @@ -926,8 +930,9 @@ + helpUrl="https://bnd.bndtools.org/plugins/pomrepo.html"> + From dd36fe13f2078ceb986d52d8adaf4fc2723f060b Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Thu, 9 May 2024 00:48:51 +0200 Subject: [PATCH 04/12] allow to use tag in -runrepos in .bndrun example: -runrepos: \ Workspace,\ @resolve this adds the Workspace repo and all other repos tagged with the tag 'resolve' I used the '@' character as a marker for tags (for now). initially I wanted to use '#' but this is a comment in a .bndrun file. With this i got a successful resolution as before Signed-off-by: Christoph Rueger --- .../aQute/resolve/BndrunResolveContext.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java index ab26577420..e85c79603e 100644 --- a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java +++ b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java @@ -54,7 +54,9 @@ import aQute.bnd.service.Registry; import aQute.bnd.service.RepositoryPlugin; import aQute.bnd.service.Strategy; +import aQute.bnd.service.Tagged; import aQute.bnd.service.resolve.hook.ResolverHook; +import aQute.lib.collections.MultiMap; import aQute.lib.converter.Converter; import aQute.lib.strings.Strings; import aQute.lib.utf8properties.UTF8Properties; @@ -360,6 +362,7 @@ private Processor loadRepositories() throws Exception { // Map the repository names... + MultiMap reposTagMap = new MultiMap<>(); Map repoNameMap = new HashMap<>(allRepos.size()); for (Repository repo : allRepos) { String name; @@ -369,14 +372,29 @@ private Processor loadRepositories() throws Exception { name = repo.toString(); } repoNameMap.put(name, repo); + + // tags + if (repo instanceof Tagged taggedRepo) { + Set tags = taggedRepo.getTags(); + for (String tag : tags) { + reposTagMap.add(tag, repo); + } + } } // Create the result list orderedRepositories = new ArrayList<>(); for (String repoName : repoNames.keySet()) { - Repository repo = repoNameMap.get(repoName); - if (repo != null) - orderedRepositories.add(repo); + // tags prefixed with '@' e.g. '@baseline' + if (repoName.startsWith("@")) { + List repos = reposTagMap.get(repoName.substring(1)); + if (repos != null) + orderedRepositories.addAll(repos); + } else { + Repository repo = repoNameMap.get(repoName); + if (repo != null) + orderedRepositories.add(repo); + } } } From b9a574f0e919a751d5d52482ec1edb961f0f081c Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Fri, 10 May 2024 21:54:35 +0200 Subject: [PATCH 05/12] rework - repos now have 'resolve' tag by default - this commit partly reverts previous commit - repos now get the 'resolve' tag by default if not specified - .bndrun: empty -runrepos will be populated with all repos having the 'resolve' tag - .bndrun: resolution consider all repos having the 'resolve' tag. that means you can exclude a repo from resolution by manually assigning it a different tag (e.g. to exclude the baseline repo from resolution, you should give the baseline-repo e.g. the tag 'baseline' and make sure it does NOT have the 'resolve' tag Signed-off-by: Christoph Rueger --- .../bnd/osgi/repository/BaseRepository.java | 4 +- .../src/aQute/bnd/service/Registry.java | 14 ++++++ .../src/aQute/bnd/service/Tagged.java | 39 ++++++++++++++-- .../src/aQute/lib/deployer/FileRepo.java | 2 +- .../deployer/repository/LocalIndexedRepo.java | 2 +- .../maven/pom/provider/BndPomRepository.java | 2 +- .../maven/provider/MavenBndRepository.java | 2 +- .../bnd/repository/osgi/OSGiRepository.java | 2 +- .../repository/p2/provider/P2Repository.java | 2 +- .../maven/provider/WorkspaceTest.java | 45 ++++++++++++++++++- .../aQute/resolve/BndrunResolveContext.java | 29 +++--------- bndtools.core/_plugin.xml | 12 ++--- .../editor/project/RepositoriesEditModel.java | 6 ++- 13 files changed, 118 insertions(+), 43 deletions(-) diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java index 1baf34e565..1cfcfef450 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java @@ -36,8 +36,6 @@ public abstract class BaseRepository implements Repository, Tagged { private final PromiseFactory promiseFactory = new PromiseFactory( PromiseFactory.inlineExecutor()); - private static final String DEFAULT_TAG = "all"; - private static final Set DEFAULT_TAGS = Set.of(DEFAULT_TAG); static { Requirement requireAll = ResourceUtils.createWildcardRequirement(); @@ -250,6 +248,6 @@ public RequirementBuilder addAttribute(String name, Object value) { @Override public Set getTags() { - return DEFAULT_TAGS; + return Tagged.DEFAULT_REPO_TAGS; } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java index 584f8fa003..c4cccf764f 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java @@ -1,6 +1,9 @@ package aQute.bnd.service; +import static aQute.bnd.service.Tagged.matchesTags; + import java.util.List; +import java.util.stream.Collectors; /** * A registry for objects. @@ -8,5 +11,16 @@ public interface Registry { List getPlugins(Class c); + default List getPlugins(Class c, String... tags) { + + if (tags == null || tags.length == 0) { + return getPlugins(c); + } + + return getPlugins(c).stream() + .filter(repo -> matchesTags(repo, tags)) + .collect(Collectors.toList()); + } + T getPlugin(Class c); } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java index d2ec0a1517..6f7e976635 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java @@ -1,9 +1,11 @@ package aQute.bnd.service; +import static aQute.bnd.service.Tagged.RepoTags.resolve; +import static java.util.stream.Collectors.toCollection; + import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; -import java.util.stream.Collectors; /** * Allows to add tags to implementing classes. Originally intended for tagging @@ -11,19 +13,48 @@ */ public interface Tagged { + + enum RepoTags { + /** + * tag for repos which should be used for Resolving bundles. This is + * also the default tag for all repos which not have specified tags + * (also for bc reasons) Also see {@link Tagged#DEFAULT_REPO_TAGS} + */ + resolve + // add more if neded e.g. relase, baseline + } + + /** + * Each repo has by default the tag {@link RepoTags#resolve} if not tags are + * set at the repo definition in build.bnd That means it is consider + */ + Set DEFAULT_REPO_TAGS = Set.of(resolve.name()); + /** * @return a non-null list of tags. */ Set getTags(); - static Set toTags(String csvTags) { + static Set toTags(String csvTags, Set defaultTags) { if (csvTags == null || csvTags.isBlank()) { - return Set.of("all"); // default + return defaultTags; // default } return Arrays.stream(csvTags.split(",")) .map(String::trim) - .collect(Collectors.toCollection(LinkedHashSet::new)); + .collect(toCollection(LinkedHashSet::new)); + } + + static boolean matchesTags(T obj, String... tags) { + if (obj instanceof Tagged tagged) { + Set taggedTags = tagged.getTags(); + for (String tag : tags) { + if (taggedTags.contains(tag)) { + return true; + } + } + } + return false; } } diff --git a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java index 08d7f554c0..ec84a4cc35 100644 --- a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java +++ b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java @@ -1060,6 +1060,6 @@ public void setIndex(boolean b) { @Override public Set getTags() { - return Tagged.toTags(tags); + return Tagged.toTags(tags, Tagged.DEFAULT_REPO_TAGS); } } diff --git a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java index 4aa7391b36..491557f16b 100644 --- a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java +++ b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java @@ -621,7 +621,7 @@ public void close() {} @Override public Set getTags() { - return Tagged.toTags(tags); + return Tagged.toTags(tags, Tagged.DEFAULT_REPO_TAGS); } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java index 61814dcffc..58b86a1ed9 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java @@ -511,6 +511,6 @@ private Archive trySources(String bsn, Version version) throws Exception { @Override public Set getTags() { - return Tagged.toTags(configuration.tags()); + return Tagged.toTags(configuration.tags(), Tagged.DEFAULT_REPO_TAGS); } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java index 1c7554b08c..79ea6aceef 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java @@ -1078,6 +1078,6 @@ public boolean isRemote() { @Override public Set getTags() { - return Tagged.toTags(configuration.tags()); + return Tagged.toTags(configuration.tags(), Tagged.DEFAULT_REPO_TAGS); } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java index 2099f5ac33..7e9329de59 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java @@ -417,6 +417,6 @@ private void status(String s) { @Override public Set getTags() { - return Tagged.toTags(config.tags()); + return Tagged.toTags(config.tags(), Tagged.DEFAULT_REPO_TAGS); } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java index 04e08f054c..e35bfea9bf 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java @@ -197,7 +197,7 @@ public String title(Object... target) throws Exception { @Override public Set getTags() { - return Tagged.toTags(config.tags()); + return Tagged.toTags(config.tags(), Tagged.DEFAULT_REPO_TAGS); } } diff --git a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java index ff6813a434..95b760a8b3 100644 --- a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java +++ b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java @@ -1,17 +1,24 @@ package aQute.bnd.repository.maven.provider; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; +import java.util.ArrayList; import java.util.Formatter; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.osgi.service.repository.Repository; import aQute.bnd.build.Workspace; +import aQute.bnd.service.Tagged; +import aQute.bnd.service.Tagged.RepoTags; import aQute.bnd.test.jupiter.InjectTemporaryDirectory; import aQute.http.testservers.HttpTestServer.Config; import aQute.lib.io.IO; @@ -57,6 +64,37 @@ public void testEnv() throws Exception { assertNotNull(workspace); assertNotNull(repo); System.out.println(workspace.getBase()); + + // check repo tags + // repos should have the 'resolve' tag by default if no tag is specified + List repos = workspace.getPlugins(Repository.class); + List resolveRepos = workspace.getPlugins(Repository.class, RepoTags.resolve.name()); + assertEquals(repos, resolveRepos); + + Repository repo = repos.get(0); + assertTrue(repo instanceof Tagged); + assertEquals(1, ((Tagged) repo).getTags() + .size()); + assertEquals(RepoTags.resolve.name(), new ArrayList<>(((Tagged) repo).getTags()).get(0)); + + } + + @Test + public void testRepoWithDifferentTag() throws Exception { + // similar as testEnv() + // but override the tag with a different one and repeat the tests + config(Map.of("tags", "foo")); + + List resolveRepos = workspace.getPlugins(Repository.class, RepoTags.resolve.name()); + assertTrue(resolveRepos.isEmpty()); + + List repos = workspace.getPlugins(Repository.class); + Repository repo = repos.get(0); + assertTrue(repo instanceof Tagged); + assertEquals(1, ((Tagged) repo).getTags() + .size()); + assertEquals("foo", new ArrayList<>(((Tagged) repo).getTags()).get(0)); + } void config(Map override) throws Exception { @@ -74,7 +112,12 @@ void config(Map override) throws Exception { sb.format(" name=test; \\\n", MavenBndRepository.class.getName()); sb.format(" local=%s; \\\n", config.get("local")); sb.format(" releaseUrl=%s; \\\n", config.get("releaseUrl")); - sb.format(" index=%s\n", config.get("index")); + sb.format(" index=%s; \\\n", config.get("index")); + + String tags = config.get("tags"); + if (tags != null && !tags.isBlank()) { + sb.format(" tags=%s\n", tags); + } build.getParentFile() .mkdirs(); diff --git a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java index e85c79603e..ae5e048e8b 100644 --- a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java +++ b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java @@ -1,5 +1,7 @@ package biz.aQute.resolve; +import static aQute.bnd.service.Tagged.RepoTags.resolve; + import java.io.File; import java.io.InputStream; import java.net.URI; @@ -54,9 +56,7 @@ import aQute.bnd.service.Registry; import aQute.bnd.service.RepositoryPlugin; import aQute.bnd.service.Strategy; -import aQute.bnd.service.Tagged; import aQute.bnd.service.resolve.hook.ResolverHook; -import aQute.lib.collections.MultiMap; import aQute.lib.converter.Converter; import aQute.lib.strings.Strings; import aQute.lib.utf8properties.UTF8Properties; @@ -362,7 +362,6 @@ private Processor loadRepositories() throws Exception { // Map the repository names... - MultiMap reposTagMap = new MultiMap<>(); Map repoNameMap = new HashMap<>(allRepos.size()); for (Repository repo : allRepos) { String name; @@ -373,28 +372,14 @@ private Processor loadRepositories() throws Exception { } repoNameMap.put(name, repo); - // tags - if (repo instanceof Tagged taggedRepo) { - Set tags = taggedRepo.getTags(); - for (String tag : tags) { - reposTagMap.add(tag, repo); - } - } } // Create the result list orderedRepositories = new ArrayList<>(); for (String repoName : repoNames.keySet()) { - // tags prefixed with '@' e.g. '@baseline' - if (repoName.startsWith("@")) { - List repos = reposTagMap.get(repoName.substring(1)); - if (repos != null) - orderedRepositories.addAll(repos); - } else { - Repository repo = repoNameMap.get(repoName); - if (repo != null) - orderedRepositories.add(repo); - } + Repository repo = repoNameMap.get(repoName); + if (repo != null) + orderedRepositories.add(repo); } } @@ -420,12 +405,12 @@ private List getAllRepos() { List allRepos; if (project != null && !project.isStandalone()) { allRepos = project.getWorkspace() - .getPlugins(Repository.class); + .getPlugins(Repository.class, resolve.name()); allRepos.removeIf(WorkspaceRepositoryMarker.class::isInstance); WorkspaceResourcesRepository wr = new WorkspaceResourcesRepository(project.getWorkspace()); allRepos.add(wr); } else { - allRepos = registry.getPlugins(Repository.class); + allRepos = registry.getPlugins(Repository.class, resolve.name()); } return allRepos; } diff --git a/bndtools.core/_plugin.xml b/bndtools.core/_plugin.xml index 5b4acfedc7..a20e2fc9f0 100644 --- a/bndtools.core/_plugin.xml +++ b/bndtools.core/_plugin.xml @@ -839,7 +839,7 @@ helpUrl="https://bnd.bndtools.org/plugins/filerepo.html"> - + @@ -850,7 +850,7 @@ helpUrl="https://bnd.bndtools.org/plugins/osgirepo.html"> - + - + - + @@ -922,7 +922,7 @@ name="P2Repository" helpUrl="https://bnd.bndtools.org/plugins/p2repo.html"> - + @@ -932,7 +932,7 @@ name="Maven POM Repository" helpUrl="https://bnd.bndtools.org/plugins/pomrepo.html"> - + diff --git a/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java b/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java index 96be58a6e5..9f388fa754 100644 --- a/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java +++ b/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java @@ -1,5 +1,7 @@ package bndtools.editor.project; +import static aQute.bnd.service.Tagged.RepoTags.resolve; + import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -30,7 +32,7 @@ class RepositoriesEditModel { RepositoriesEditModel(BndEditModel model) { this.model = model; this.pluginOrder = model.getWorkspace() - .getPlugins(Repository.class); + .getPlugins(Repository.class, resolve.name()); this.standalone = model.getStandaloneLinks(); this.runrepos = model.getRunRepos(); this.ignoreStandalone = model.getIgnoreStandalone(); @@ -44,6 +46,7 @@ class RepositoriesEditModel { List remains = new ArrayList<>(pluginOrder); for (String name : runrepos) { + Repository r = find(name); if (r != null) { actualOrder.add(r); @@ -55,6 +58,7 @@ class RepositoriesEditModel { } } + private Repository find(String sought) { for (Repository r : pluginOrder) { String name = toName(r); From c08cce3e8135bf88e0ae1b8c7a51cd336c57629b Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Fri, 17 May 2024 23:03:25 +0200 Subject: [PATCH 06/12] implement suggestions - extend RepositoryPlugin with Tagged - make a Tags class, extending Set - not parsing the string all the time - replace RepoTags enum with Constants.REPOTAGS_RESOLVE Signed-off-by: Christoph Rueger --- .../src/aQute/bnd/maven/support/packageinfo | 2 +- .../src/aQute/bnd/osgi/Constants.java | 7 ++ .../bnd/osgi/repository/BaseRepository.java | 11 +++- .../src/aQute/bnd/service/Registry.java | 2 +- .../aQute/bnd/service/RepositoryPlugin.java | 18 ++++- .../src/aQute/bnd/service/Tagged.java | 50 +------------- .../src/aQute/bnd/service/Tags.java | 65 +++++++++++++++++++ .../aQute/bnd/service/repository/packageinfo | 2 +- .../src/aQute/lib/deployer/FileRepo.java | 12 ++-- .../deployer/repository/LocalIndexedRepo.java | 9 +-- .../maven/pom/provider/BndPomRepository.java | 9 +-- .../maven/provider/MavenBndRepository.java | 7 +- .../bnd/repository/osgi/OSGiRepository.java | 10 ++- .../repository/p2/provider/P2Repository.java | 9 +-- .../maven/provider/WorkspaceTest.java | 8 +-- .../aQute/resolve/BndrunResolveContext.java | 5 +- .../editor/project/RepositoriesEditModel.java | 4 +- 17 files changed, 133 insertions(+), 97 deletions(-) create mode 100644 biz.aQute.bndlib/src/aQute/bnd/service/Tags.java diff --git a/biz.aQute.bndlib/src/aQute/bnd/maven/support/packageinfo b/biz.aQute.bndlib/src/aQute/bnd/maven/support/packageinfo index e4869c59e8..eb994e33e0 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/maven/support/packageinfo +++ b/biz.aQute.bndlib/src/aQute/bnd/maven/support/packageinfo @@ -1 +1 @@ -version 3.1 +version 3.2.0 diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/Constants.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/Constants.java index d89044983a..2c52a44797 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/Constants.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/Constants.java @@ -258,6 +258,13 @@ public interface Constants { String REMOTEWORKSPACE = "-remoteworkspace"; + /** + * tag for repos which should be used for Resolving bundles. This is also + * the default tag for all repos which not have specified tags (also for bc + * reasons) + */ + String REPOTAGS_RESOLVE = "resolve"; + String RUNBLACKLIST = "-runblacklist"; String RUNREQUIRES = "-runrequires"; String RUNEE = "-runee"; diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java index 1cfcfef450..8c85a66443 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java @@ -25,7 +25,9 @@ import aQute.bnd.exceptions.Exceptions; import aQute.bnd.osgi.resource.ResourceUtils; +import aQute.bnd.service.RepositoryPlugin; import aQute.bnd.service.Tagged; +import aQute.bnd.service.Tags; /** * WARNING ! Not tested @@ -35,6 +37,7 @@ public abstract class BaseRepository implements Repository, Tagged { static IdentityExpression all; private final PromiseFactory promiseFactory = new PromiseFactory( PromiseFactory.inlineExecutor()); + private Tags tags = RepositoryPlugin.DEFAULT_REPO_TAGS; static { @@ -247,7 +250,11 @@ public RequirementBuilder addAttribute(String name, Object value) { } @Override - public Set getTags() { - return Tagged.DEFAULT_REPO_TAGS; + public Tags getTags() { + return this.tags; + } + + protected void setTags(Tags tags) { + this.tags = tags; } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java index c4cccf764f..1e31d3f3c3 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java @@ -1,6 +1,6 @@ package aQute.bnd.service; -import static aQute.bnd.service.Tagged.matchesTags; +import static aQute.bnd.service.Tags.matchesTags; import java.util.List; import java.util.stream.Collectors; diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java b/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java index 95f381fe09..04c4a359b2 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java @@ -9,6 +9,7 @@ import org.osgi.util.promise.Promise; +import aQute.bnd.osgi.Constants; import aQute.bnd.osgi.Processor; import aQute.bnd.version.Version; @@ -18,7 +19,15 @@ * combination. It is also possible to put revisions in a repository if the * repository is not read only. */ -public interface RepositoryPlugin { +public interface RepositoryPlugin extends Tagged { + + /** + * Each repo has by default the tag {@link Constants#REPOTAGS_RESOLVE} if no + * tags are set at the repo definition in build.bnd That means it is + * consider + */ + Tags DEFAULT_REPO_TAGS = Tags.of(Constants.REPOTAGS_RESOLVE); + /** * Options used to steer the put operation */ @@ -167,6 +176,8 @@ default void success(File file, Map attrs) throws Exception { boolean progress(File file, int percentage) throws Exception; } + + /** * Return a URL to a matching version of the given bundle. *

@@ -276,4 +287,9 @@ default Promise sync() throws Exception { return null; }); } + + @Override + default Tags getTags() { + return DEFAULT_REPO_TAGS; + } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java index 6f7e976635..2f9caeb507 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java @@ -1,60 +1,16 @@ package aQute.bnd.service; -import static aQute.bnd.service.Tagged.RepoTags.resolve; -import static java.util.stream.Collectors.toCollection; - -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; - /** * Allows to add tags to implementing classes. Originally intended for tagging * repositories. */ public interface Tagged { - - enum RepoTags { - /** - * tag for repos which should be used for Resolving bundles. This is - * also the default tag for all repos which not have specified tags - * (also for bc reasons) Also see {@link Tagged#DEFAULT_REPO_TAGS} - */ - resolve - // add more if neded e.g. relase, baseline - } - - /** - * Each repo has by default the tag {@link RepoTags#resolve} if not tags are - * set at the repo definition in build.bnd That means it is consider - */ - Set DEFAULT_REPO_TAGS = Set.of(resolve.name()); - /** - * @return a non-null list of tags. + * @return a non-null list of tags. Default is empty (meaning 'no tags'). */ - Set getTags(); - - static Set toTags(String csvTags, Set defaultTags) { - if (csvTags == null || csvTags.isBlank()) { - return defaultTags; // default - } - - return Arrays.stream(csvTags.split(",")) - .map(String::trim) - .collect(toCollection(LinkedHashSet::new)); - } - - static boolean matchesTags(T obj, String... tags) { - if (obj instanceof Tagged tagged) { - Set taggedTags = tagged.getTags(); - for (String tag : tags) { - if (taggedTags.contains(tag)) { - return true; - } - } - } - return false; + default Tags getTags() { + return Tags.NO_TAGS; } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java new file mode 100644 index 0000000000..26bbb6ef42 --- /dev/null +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java @@ -0,0 +1,65 @@ +package aQute.bnd.service; + +import static java.util.stream.Collectors.toCollection; + +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * A set of tags. A tag is a string-token which can be attached to an entity for + * categorization and filtering. Typically these entities then implement the + * {@link Tagged} interface. + */ +public final class Tags extends LinkedHashSet { + + private static final long serialVersionUID = 1L; + + public final static Tags NO_TAGS = of(); + + private Tags(Collection c) { + super(c); + } + + static Tags of(String... name) { + return new Tags(Set.of(name)); + } + + /** + * Parses a comma-separated string of tags into a Tags object. + * + * @param csvTags + * @param defaultTags a default used when csvTags is null or blank + * @return populated Tags or the passed defaultTags. + */ + public static Tags parse(String csvTags, Tags defaultTags) { + if (csvTags == null || csvTags.isBlank()) { + return defaultTags; // default + } + + return new Tags(Arrays.stream(csvTags.split(",")) + .map(String::trim) + .collect(toCollection(LinkedHashSet::new))); + } + + /** + * @param + * @param obj + * @param tags + * @return true if the passed object matches any of the given + * tags, otherwise returns false + */ + public static boolean matchesTags(T obj, String... tags) { + if (obj instanceof Tagged tagged) { + Tags taggedTags = tagged.getTags(); + for (String tag : tags) { + if (taggedTags.contains(tag)) { + return true; + } + } + } + return false; + } + +} diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/repository/packageinfo b/biz.aQute.bndlib/src/aQute/bnd/service/repository/packageinfo index fec6063b13..486d8c8790 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/repository/packageinfo +++ b/biz.aQute.bndlib/src/aQute/bnd/service/repository/packageinfo @@ -1 +1 @@ -version 1.6 +version 1.7.0 diff --git a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java index ec84a4cc35..6bcacbd9ca 100644 --- a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java +++ b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java @@ -1,5 +1,7 @@ package aQute.lib.deployer; +import static aQute.bnd.service.Tags.parse; + import java.io.Closeable; import java.io.File; import java.io.IOException; @@ -14,7 +16,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.jar.Manifest; @@ -36,6 +37,7 @@ import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; import aQute.bnd.service.Tagged; +import aQute.bnd.service.Tags; import aQute.bnd.service.repository.SearchableRepository.ResourceDescriptor; import aQute.bnd.version.Version; import aQute.lib.collections.SortedList; @@ -259,7 +261,7 @@ interface Config { String name; boolean inited; boolean trace; - String tags; + Tags tags = DEFAULT_REPO_TAGS; PersistentMap index; private boolean hasIndex; @@ -344,7 +346,7 @@ public void setProperties(Map map) { action = map.get(CMD_AFTER_ACTION); trace = Boolean.parseBoolean(map.get(TRACE)); - tags = map.get(TAGS); + tags = parse(map.get(TAGS), DEFAULT_REPO_TAGS); } /** @@ -1059,7 +1061,7 @@ public void setIndex(boolean b) { } @Override - public Set getTags() { - return Tagged.toTags(tags, Tagged.DEFAULT_REPO_TAGS); + public Tags getTags() { + return this.tags; } } diff --git a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java index 491557f16b..43114e0566 100644 --- a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java +++ b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java @@ -1,6 +1,7 @@ package aQute.bnd.deployer.repository; import static aQute.bnd.deployer.repository.RepoConstants.DEFAULT_CACHE_DIR; +import static aQute.bnd.service.Tags.parse; import java.io.ByteArrayOutputStream; import java.io.File; @@ -40,7 +41,6 @@ import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.ResourceHandle; import aQute.bnd.service.ResourceHandle.Location; -import aQute.bnd.service.Tagged; import aQute.bnd.version.Version; import aQute.bnd.version.VersionRange; import aQute.lib.hex.Hex; @@ -83,7 +83,6 @@ interface Config { private boolean overwrite = true; private File storageDir; private String onlydirs = null; - private String tags = null; // @GuardedBy("newFilesInCoordination") private final List newFilesInCoordination = new ArrayList<>(); @@ -136,7 +135,7 @@ public synchronized void setProperties(Map map) { String.format("Cannot create repository cache: '%s' already exists but is not directory.", cacheDir.getAbsolutePath())); - tags = map.get(PROP_TAGS); + super.setTags(parse(map.get(PROP_TAGS), DEFAULT_REPO_TAGS)); } @Override @@ -619,9 +618,5 @@ public String title(Object... target) throws Exception { public void close() {} - @Override - public Set getTags() { - return Tagged.toTags(tags, Tagged.DEFAULT_REPO_TAGS); - } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java index 58b86a1ed9..d71a0a1bd8 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java @@ -1,6 +1,7 @@ package aQute.bnd.repository.maven.pom.provider; import static aQute.bnd.osgi.Constants.BSN_SOURCE_SUFFIX; +import static aQute.bnd.service.Tags.parse; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; @@ -14,7 +15,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; @@ -45,7 +45,6 @@ import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; -import aQute.bnd.service.Tagged; import aQute.bnd.service.clipboard.Clipboard; import aQute.bnd.service.repository.Prepare; import aQute.bnd.util.repository.DownloadListenerPromise; @@ -273,6 +272,7 @@ public boolean refresh() throws Exception { @Override public void setProperties(Map map) throws Exception { configuration = Converter.cnv(PomConfiguration.class, map); + super.setTags(parse(configuration.tags(), DEFAULT_REPO_TAGS)); } @Override @@ -509,8 +509,5 @@ private Archive trySources(String bsn, Version version) throws Exception { .getOther(Archive.JAR_EXTENSION, Archive.SOURCES_CLASSIFIER); } - @Override - public Set getTags() { - return Tagged.toTags(configuration.tags(), Tagged.DEFAULT_REPO_TAGS); - } + } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java index 79ea6aceef..7753dd9c77 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java @@ -1,6 +1,7 @@ package aQute.bnd.repository.maven.provider; import static aQute.bnd.osgi.Constants.BSN_SOURCE_SUFFIX; +import static aQute.bnd.service.Tags.parse; import java.io.Closeable; import java.io.File; @@ -68,7 +69,6 @@ import aQute.bnd.service.Registry; import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryPlugin; -import aQute.bnd.service.Tagged; import aQute.bnd.service.clipboard.Clipboard; import aQute.bnd.service.maven.PomOptions; import aQute.bnd.service.maven.ToDependencyPom; @@ -774,6 +774,7 @@ public void setProperties(Map map) throws Exception { configuration = Converter.cnv(Configuration.class, map); name = configuration.name("Maven"); localRepo = IO.getFile(configuration.local(MAVEN_REPO_LOCAL)); + super.setTags(parse(configuration.tags(), DEFAULT_REPO_TAGS)); } @Override @@ -1076,8 +1077,4 @@ public boolean isRemote() { return remote; } - @Override - public Set getTags() { - return Tagged.toTags(configuration.tags(), Tagged.DEFAULT_REPO_TAGS); - } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java index 7e9329de59..722c17f1b3 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java @@ -1,5 +1,7 @@ package aQute.bnd.repository.osgi; +import static aQute.bnd.service.Tags.parse; + import java.io.Closeable; import java.io.File; import java.io.IOException; @@ -12,7 +14,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.SortedSet; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -39,7 +40,6 @@ import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; -import aQute.bnd.service.Tagged; import aQute.bnd.service.repository.Prepare; import aQute.bnd.util.repository.DownloadListenerPromise; import aQute.bnd.version.Version; @@ -300,6 +300,8 @@ public File getRoot() throws Exception { @Override public void setProperties(Map map) throws Exception { config = Converter.cnv(Config.class, map); + + super.setTags(parse(config.tags(), DEFAULT_REPO_TAGS)); } @Override @@ -415,8 +417,4 @@ private void status(String s) { } } - @Override - public Set getTags() { - return Tagged.toTags(config.tags(), Tagged.DEFAULT_REPO_TAGS); - } } diff --git a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java index e35bfea9bf..66ae77b62c 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java @@ -1,5 +1,7 @@ package aQute.bnd.repository.p2.provider; +import static aQute.bnd.service.Tags.parse; + import java.io.Closeable; import java.io.File; import java.io.IOException; @@ -9,7 +11,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.SortedSet; import org.osgi.resource.Capability; @@ -26,7 +27,6 @@ import aQute.bnd.service.Registry; import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryPlugin; -import aQute.bnd.service.Tagged; import aQute.bnd.version.Version; import aQute.lib.converter.Converter; import aQute.lib.io.IO; @@ -110,6 +110,7 @@ public String getLocation() { public void setProperties(Map map) throws Exception { this.config = Converter.cnv(P2Config.class, map); this.name = this.config.name("p2-" + config.url()); + super.setTags(parse(config.tags(), DEFAULT_REPO_TAGS)); } @Override @@ -195,9 +196,5 @@ public String title(Object... target) throws Exception { return null; } - @Override - public Set getTags() { - return Tagged.toTags(config.tags(), Tagged.DEFAULT_REPO_TAGS); - } } diff --git a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java index 95b760a8b3..cae65882aa 100644 --- a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java +++ b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java @@ -17,8 +17,8 @@ import org.osgi.service.repository.Repository; import aQute.bnd.build.Workspace; +import aQute.bnd.osgi.Constants; import aQute.bnd.service.Tagged; -import aQute.bnd.service.Tagged.RepoTags; import aQute.bnd.test.jupiter.InjectTemporaryDirectory; import aQute.http.testservers.HttpTestServer.Config; import aQute.lib.io.IO; @@ -68,14 +68,14 @@ public void testEnv() throws Exception { // check repo tags // repos should have the 'resolve' tag by default if no tag is specified List repos = workspace.getPlugins(Repository.class); - List resolveRepos = workspace.getPlugins(Repository.class, RepoTags.resolve.name()); + List resolveRepos = workspace.getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); assertEquals(repos, resolveRepos); Repository repo = repos.get(0); assertTrue(repo instanceof Tagged); assertEquals(1, ((Tagged) repo).getTags() .size()); - assertEquals(RepoTags.resolve.name(), new ArrayList<>(((Tagged) repo).getTags()).get(0)); + assertEquals(Constants.REPOTAGS_RESOLVE, new ArrayList<>(((Tagged) repo).getTags()).get(0)); } @@ -85,7 +85,7 @@ public void testRepoWithDifferentTag() throws Exception { // but override the tag with a different one and repeat the tests config(Map.of("tags", "foo")); - List resolveRepos = workspace.getPlugins(Repository.class, RepoTags.resolve.name()); + List resolveRepos = workspace.getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); assertTrue(resolveRepos.isEmpty()); List repos = workspace.getPlugins(Repository.class); diff --git a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java index ae5e048e8b..019c4d5d7c 100644 --- a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java +++ b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java @@ -1,6 +1,5 @@ package biz.aQute.resolve; -import static aQute.bnd.service.Tagged.RepoTags.resolve; import java.io.File; import java.io.InputStream; @@ -405,12 +404,12 @@ private List getAllRepos() { List allRepos; if (project != null && !project.isStandalone()) { allRepos = project.getWorkspace() - .getPlugins(Repository.class, resolve.name()); + .getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); allRepos.removeIf(WorkspaceRepositoryMarker.class::isInstance); WorkspaceResourcesRepository wr = new WorkspaceResourcesRepository(project.getWorkspace()); allRepos.add(wr); } else { - allRepos = registry.getPlugins(Repository.class, resolve.name()); + allRepos = registry.getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); } return allRepos; } diff --git a/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java b/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java index 9f388fa754..270262b398 100644 --- a/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java +++ b/bndtools.core/src/bndtools/editor/project/RepositoriesEditModel.java @@ -1,6 +1,5 @@ package bndtools.editor.project; -import static aQute.bnd.service.Tagged.RepoTags.resolve; import java.util.ArrayList; import java.util.Collections; @@ -15,6 +14,7 @@ import aQute.bnd.build.Workspace; import aQute.bnd.build.model.BndEditModel; import aQute.bnd.build.model.clauses.HeaderClause; +import aQute.bnd.osgi.Constants; import aQute.bnd.osgi.Processor; import aQute.bnd.service.RepositoryPlugin; import bndtools.central.Central; @@ -32,7 +32,7 @@ class RepositoriesEditModel { RepositoriesEditModel(BndEditModel model) { this.model = model; this.pluginOrder = model.getWorkspace() - .getPlugins(Repository.class, resolve.name()); + .getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); this.standalone = model.getStandaloneLinks(); this.runrepos = model.getRunRepos(); this.ignoreStandalone = model.getIgnoreStandalone(); From e990f0759e0fa020c43f2d6ed3f6a4a562baf794 Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Fri, 17 May 2024 23:18:49 +0200 Subject: [PATCH 07/12] move matchesTags back to Tagged Somehow I think it belongs there. Signed-off-by: Christoph Rueger --- .../src/aQute/bnd/service/Registry.java | 2 +- .../src/aQute/bnd/service/Tagged.java | 19 +++++++++++++++++++ .../src/aQute/bnd/service/Tags.java | 19 +------------------ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java index 1e31d3f3c3..c4cccf764f 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java @@ -1,6 +1,6 @@ package aQute.bnd.service; -import static aQute.bnd.service.Tags.matchesTags; +import static aQute.bnd.service.Tagged.matchesTags; import java.util.List; import java.util.stream.Collectors; diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java index 2f9caeb507..cff23f6c42 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java @@ -13,4 +13,23 @@ default Tags getTags() { return Tags.NO_TAGS; } + /** + * @param + * @param obj + * @param tags + * @return true if the passed object matches any of the given + * tags, otherwise returns false + */ + static boolean matchesTags(T obj, String... tags) { + if (obj instanceof Tagged tagged) { + Tags taggedTags = tagged.getTags(); + for (String tag : tags) { + if (taggedTags.contains(tag)) { + return true; + } + } + } + return false; + } + } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java index 26bbb6ef42..3f36d66255 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java @@ -43,23 +43,6 @@ public static Tags parse(String csvTags, Tags defaultTags) { .collect(toCollection(LinkedHashSet::new))); } - /** - * @param - * @param obj - * @param tags - * @return true if the passed object matches any of the given - * tags, otherwise returns false - */ - public static boolean matchesTags(T obj, String... tags) { - if (obj instanceof Tagged tagged) { - Tags taggedTags = tagged.getTags(); - for (String tag : tags) { - if (taggedTags.contains(tag)) { - return true; - } - } - } - return false; - } + } From 7857d51a22937b0a338938715dc826721b437154 Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Mon, 20 May 2024 12:12:05 +0200 Subject: [PATCH 08/12] Tags implement Set using an internal sorted set fix and improve testcase to test for consistent sorting of tags Signed-off-by: Christoph Rueger --- .../src/aQute/bnd/service/Tags.java | 101 ++++++++++++++++-- .../maven/provider/WorkspaceTest.java | 12 ++- 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java index 3f36d66255..17246d152d 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java @@ -1,25 +1,32 @@ package aQute.bnd.service; -import static java.util.stream.Collectors.toCollection; +import static java.util.Collections.unmodifiableSortedSet; import java.util.Arrays; import java.util.Collection; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; /** * A set of tags. A tag is a string-token which can be attached to an entity for * categorization and filtering. Typically these entities then implement the * {@link Tagged} interface. */ -public final class Tags extends LinkedHashSet { - - private static final long serialVersionUID = 1L; +public final class Tags implements Set { + private final SortedSet internalSet; public final static Tags NO_TAGS = of(); - private Tags(Collection c) { - super(c); + private Tags() { + this.internalSet = unmodifiableSortedSet(new TreeSet<>()); + } + + private Tags(Collection c) { + this.internalSet = unmodifiableSortedSet(new TreeSet<>(c)); } static Tags of(String... name) { @@ -40,7 +47,87 @@ public static Tags parse(String csvTags, Tags defaultTags) { return new Tags(Arrays.stream(csvTags.split(",")) .map(String::trim) - .collect(toCollection(LinkedHashSet::new))); + .collect(Collectors.toCollection(LinkedHashSet::new))); + } + + @Override + public int size() { + return internalSet.size(); + } + + @Override + public boolean isEmpty() { + return internalSet.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return internalSet.contains(o); + } + + @Override + public Iterator iterator() { + return internalSet.iterator(); + } + + @Override + public Object[] toArray() { + return internalSet.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return internalSet.toArray(a); + } + + @Override + public boolean add(String s) { + return internalSet.add(s); + } + + @Override + public boolean remove(Object o) { + return internalSet.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return internalSet.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return internalSet.addAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return internalSet.retainAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return internalSet.removeAll(c); + } + + @Override + public void clear() { + internalSet.clear(); + } + + @Override + public boolean equals(Object o) { + return internalSet.equals(o); + } + + @Override + public int hashCode() { + return internalSet.hashCode(); + } + + @Override + public String toString() { + return internalSet.toString(); } diff --git a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java index cae65882aa..31558ab391 100644 --- a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java +++ b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java @@ -83,7 +83,7 @@ public void testEnv() throws Exception { public void testRepoWithDifferentTag() throws Exception { // similar as testEnv() // but override the tag with a different one and repeat the tests - config(Map.of("tags", "foo")); + config(Map.of("tags", " foo,bar , a ")); List resolveRepos = workspace.getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); assertTrue(resolveRepos.isEmpty()); @@ -91,9 +91,13 @@ public void testRepoWithDifferentTag() throws Exception { List repos = workspace.getPlugins(Repository.class); Repository repo = repos.get(0); assertTrue(repo instanceof Tagged); - assertEquals(1, ((Tagged) repo).getTags() + assertEquals(3, ((Tagged) repo).getTags() .size()); - assertEquals("foo", new ArrayList<>(((Tagged) repo).getTags()).get(0)); + + // make sure tags are sorted consistently (alphabetically) + assertEquals("a", new ArrayList<>(((Tagged) repo).getTags()).get(0)); + assertEquals("bar", new ArrayList<>(((Tagged) repo).getTags()).get(1)); + assertEquals("foo", new ArrayList<>(((Tagged) repo).getTags()).get(2)); } @@ -116,7 +120,7 @@ void config(Map override) throws Exception { String tags = config.get("tags"); if (tags != null && !tags.isBlank()) { - sb.format(" tags=%s\n", tags); + sb.format(" tags=\"%s\"\n", tags); } build.getParentFile() From 53cb0dcba3674c90c60c3138c2ea153556c2f4ba Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Tue, 21 May 2024 16:34:19 +0200 Subject: [PATCH 09/12] improve tag matching - keep backwards compatibility so that Repos without tags return an empty set and empty set means "matches" - renamed Tags.matchesTags to Tags.isIncluded - move tags to own package aQute.bnd.service.tags Signed-off-by: Christoph Rueger --- .../bnd/osgi/repository/BaseRepository.java | 4 +-- .../src/aQute/bnd/service/Registry.java | 9 ++--- .../aQute/bnd/service/RepositoryPlugin.java | 7 ++-- .../src/aQute/bnd/service/Tagged.java | 35 ------------------- .../src/aQute/bnd/service/tags/Tagged.java | 21 +++++++++++ .../aQute/bnd/service/{ => tags}/Tags.java | 26 ++++++++++++-- .../aQute/bnd/service/tags/package-info.java | 4 +++ .../src/aQute/lib/deployer/FileRepo.java | 6 ++-- .../deployer/repository/LocalIndexedRepo.java | 4 +-- .../maven/pom/provider/BndPomRepository.java | 2 +- .../maven/provider/MavenBndRepository.java | 2 +- .../bnd/repository/osgi/OSGiRepository.java | 2 +- .../repository/p2/provider/P2Repository.java | 2 +- .../maven/provider/WorkspaceTest.java | 5 +-- 14 files changed, 70 insertions(+), 59 deletions(-) delete mode 100644 biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java create mode 100644 biz.aQute.bndlib/src/aQute/bnd/service/tags/Tagged.java rename biz.aQute.bndlib/src/aQute/bnd/service/{ => tags}/Tags.java (84%) create mode 100644 biz.aQute.bndlib/src/aQute/bnd/service/tags/package-info.java diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java index 8c85a66443..d9d04ab1c1 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/repository/BaseRepository.java @@ -26,8 +26,8 @@ import aQute.bnd.exceptions.Exceptions; import aQute.bnd.osgi.resource.ResourceUtils; import aQute.bnd.service.RepositoryPlugin; -import aQute.bnd.service.Tagged; -import aQute.bnd.service.Tags; +import aQute.bnd.service.tags.Tagged; +import aQute.bnd.service.tags.Tags; /** * WARNING ! Not tested diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java index c4cccf764f..506a3e1a46 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java @@ -1,10 +1,10 @@ package aQute.bnd.service; -import static aQute.bnd.service.Tagged.matchesTags; - import java.util.List; import java.util.stream.Collectors; +import aQute.bnd.service.tags.Tagged; + /** * A registry for objects. */ @@ -13,12 +13,13 @@ public interface Registry { default List getPlugins(Class c, String... tags) { - if (tags == null || tags.length == 0) { + if (tags.length == 0) { return getPlugins(c); } return getPlugins(c).stream() - .filter(repo -> matchesTags(repo, tags)) + .filter(repo -> repo instanceof Tagged taggedRepo && taggedRepo.getTags() + .isIncluded(tags)) .collect(Collectors.toList()); } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java b/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java index 04c4a359b2..36ff3e63b0 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/RepositoryPlugin.java @@ -11,6 +11,8 @@ import aQute.bnd.osgi.Constants; import aQute.bnd.osgi.Processor; +import aQute.bnd.service.tags.Tagged; +import aQute.bnd.service.tags.Tags; import aQute.bnd.version.Version; /** @@ -288,8 +290,5 @@ default Promise sync() throws Exception { }); } - @Override - default Tags getTags() { - return DEFAULT_REPO_TAGS; - } + } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java deleted file mode 100644 index cff23f6c42..0000000000 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tagged.java +++ /dev/null @@ -1,35 +0,0 @@ -package aQute.bnd.service; - -/** - * Allows to add tags to implementing classes. Originally intended for tagging - * repositories. - */ -public interface Tagged { - - /** - * @return a non-null list of tags. Default is empty (meaning 'no tags'). - */ - default Tags getTags() { - return Tags.NO_TAGS; - } - - /** - * @param - * @param obj - * @param tags - * @return true if the passed object matches any of the given - * tags, otherwise returns false - */ - static boolean matchesTags(T obj, String... tags) { - if (obj instanceof Tagged tagged) { - Tags taggedTags = tagged.getTags(); - for (String tag : tags) { - if (taggedTags.contains(tag)) { - return true; - } - } - } - return false; - } - -} diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tagged.java b/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tagged.java new file mode 100644 index 0000000000..e14a1a5e72 --- /dev/null +++ b/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tagged.java @@ -0,0 +1,21 @@ +package aQute.bnd.service.tags; + +/** + * Allows to add tags to implementing classes. Originally intended for tagging + * repositories. + */ +public interface Tagged { + + /** + * Dummy placeholder for "empty tags". + */ + String EMPTY_TAGS = "<>"; + + /** + * @return a non-null list of tags. Default is empty (meaning 'no tags'). + */ + default Tags getTags() { + return Tags.NO_TAGS; + } + +} diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java b/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java similarity index 84% rename from biz.aQute.bndlib/src/aQute/bnd/service/Tags.java rename to biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java index 17246d152d..0895296298 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Tags.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java @@ -1,4 +1,4 @@ -package aQute.bnd.service; +package aQute.bnd.service.tags; import static java.util.Collections.unmodifiableSortedSet; @@ -16,7 +16,7 @@ * categorization and filtering. Typically these entities then implement the * {@link Tagged} interface. */ -public final class Tags implements Set { +public class Tags implements Set { private final SortedSet internalSet; public final static Tags NO_TAGS = of(); @@ -29,7 +29,7 @@ private Tags(Collection c) { this.internalSet = unmodifiableSortedSet(new TreeSet<>(c)); } - static Tags of(String... name) { + public static Tags of(String... name) { return new Tags(Set.of(name)); } @@ -130,6 +130,26 @@ public String toString() { return internalSet.toString(); } + /** + * @param + * @param tags + * @return true if the passed object matches any of the given + * tags, otherwise returns false + */ + public boolean isIncluded(String... tags) { + + if (isEmpty()) { + return true; + } + + for (String tag : tags) { + if (contains(tag)) { + return true; + } + } + + return false; + } } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/tags/package-info.java b/biz.aQute.bndlib/src/aQute/bnd/service/tags/package-info.java new file mode 100644 index 0000000000..114baa10a6 --- /dev/null +++ b/biz.aQute.bndlib/src/aQute/bnd/service/tags/package-info.java @@ -0,0 +1,4 @@ +@Version("1.0.0") +package aQute.bnd.service.tags; + +import org.osgi.annotation.versioning.Version; diff --git a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java index 6bcacbd9ca..61ec6dfe4d 100644 --- a/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java +++ b/biz.aQute.bndlib/src/aQute/lib/deployer/FileRepo.java @@ -1,6 +1,6 @@ package aQute.lib.deployer; -import static aQute.bnd.service.Tags.parse; +import static aQute.bnd.service.tags.Tags.parse; import java.io.Closeable; import java.io.File; @@ -36,9 +36,9 @@ import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.RepositoryPlugin; -import aQute.bnd.service.Tagged; -import aQute.bnd.service.Tags; import aQute.bnd.service.repository.SearchableRepository.ResourceDescriptor; +import aQute.bnd.service.tags.Tagged; +import aQute.bnd.service.tags.Tags; import aQute.bnd.version.Version; import aQute.lib.collections.SortedList; import aQute.lib.hex.Hex; diff --git a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java index 43114e0566..ad8fc823ed 100644 --- a/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java +++ b/biz.aQute.repository/src/aQute/bnd/deployer/repository/LocalIndexedRepo.java @@ -1,7 +1,6 @@ package aQute.bnd.deployer.repository; import static aQute.bnd.deployer.repository.RepoConstants.DEFAULT_CACHE_DIR; -import static aQute.bnd.service.Tags.parse; import java.io.ByteArrayOutputStream; import java.io.File; @@ -41,6 +40,7 @@ import aQute.bnd.service.RepositoryListenerPlugin; import aQute.bnd.service.ResourceHandle; import aQute.bnd.service.ResourceHandle.Location; +import aQute.bnd.service.tags.Tags; import aQute.bnd.version.Version; import aQute.bnd.version.VersionRange; import aQute.lib.hex.Hex; @@ -135,7 +135,7 @@ public synchronized void setProperties(Map map) { String.format("Cannot create repository cache: '%s' already exists but is not directory.", cacheDir.getAbsolutePath())); - super.setTags(parse(map.get(PROP_TAGS), DEFAULT_REPO_TAGS)); + super.setTags(Tags.parse(map.get(PROP_TAGS), DEFAULT_REPO_TAGS)); } @Override diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java index d71a0a1bd8..1c2b6ab60d 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/pom/provider/BndPomRepository.java @@ -1,7 +1,7 @@ package aQute.bnd.repository.maven.pom.provider; import static aQute.bnd.osgi.Constants.BSN_SOURCE_SUFFIX; -import static aQute.bnd.service.Tags.parse; +import static aQute.bnd.service.tags.Tags.parse; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; diff --git a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java index 7753dd9c77..84b9c462a3 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/maven/provider/MavenBndRepository.java @@ -1,7 +1,7 @@ package aQute.bnd.repository.maven.provider; import static aQute.bnd.osgi.Constants.BSN_SOURCE_SUFFIX; -import static aQute.bnd.service.Tags.parse; +import static aQute.bnd.service.tags.Tags.parse; import java.io.Closeable; import java.io.File; diff --git a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java index 722c17f1b3..75f35e57a6 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/osgi/OSGiRepository.java @@ -1,6 +1,6 @@ package aQute.bnd.repository.osgi; -import static aQute.bnd.service.Tags.parse; +import static aQute.bnd.service.tags.Tags.parse; import java.io.Closeable; import java.io.File; diff --git a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java index 66ae77b62c..44bc2056a9 100644 --- a/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java +++ b/biz.aQute.repository/src/aQute/bnd/repository/p2/provider/P2Repository.java @@ -1,6 +1,6 @@ package aQute.bnd.repository.p2.provider; -import static aQute.bnd.service.Tags.parse; +import static aQute.bnd.service.tags.Tags.parse; import java.io.Closeable; import java.io.File; diff --git a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java index 31558ab391..dd7667493a 100644 --- a/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java +++ b/biz.aQute.repository/test/aQute/bnd/repository/maven/provider/WorkspaceTest.java @@ -18,7 +18,7 @@ import aQute.bnd.build.Workspace; import aQute.bnd.osgi.Constants; -import aQute.bnd.service.Tagged; +import aQute.bnd.service.tags.Tagged; import aQute.bnd.test.jupiter.InjectTemporaryDirectory; import aQute.http.testservers.HttpTestServer.Config; import aQute.lib.io.IO; @@ -66,7 +66,8 @@ public void testEnv() throws Exception { System.out.println(workspace.getBase()); // check repo tags - // repos should have the 'resolve' tag by default if no tag is specified + // we expect all repos to be returned for the 'resolve' tag by default + // if a repo has no tag specified List repos = workspace.getPlugins(Repository.class); List resolveRepos = workspace.getPlugins(Repository.class, Constants.REPOTAGS_RESOLVE); assertEquals(repos, resolveRepos); From e46fd43be9d81d0aab83a6050cd2c8babcd450eb Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Tue, 21 May 2024 16:47:23 +0200 Subject: [PATCH 10/12] mention <> placeholderin repo plugin UI Signed-off-by: Christoph Rueger --- bndtools.core/_plugin.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bndtools.core/_plugin.xml b/bndtools.core/_plugin.xml index a20e2fc9f0..1ab4ff787a 100644 --- a/bndtools.core/_plugin.xml +++ b/bndtools.core/_plugin.xml @@ -839,7 +839,7 @@ helpUrl="https://bnd.bndtools.org/plugins/filerepo.html"> - + @@ -850,7 +850,7 @@ helpUrl="https://bnd.bndtools.org/plugins/osgirepo.html"> - + - + - + @@ -922,7 +922,7 @@ name="P2Repository" helpUrl="https://bnd.bndtools.org/plugins/p2repo.html"> - + @@ -932,7 +932,7 @@ name="Maven POM Repository" helpUrl="https://bnd.bndtools.org/plugins/pomrepo.html"> - + From 7f04909bd4013c0c6d394f2ea5be7ab27b0271a6 Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Tue, 21 May 2024 17:13:00 +0200 Subject: [PATCH 11/12] make tags a combobox in Plugins UI Signed-off-by: Christoph Rueger --- bndtools.core/_plugin.xml | 12 +++--- .../workspace/PluginPropertiesPage.java | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/bndtools.core/_plugin.xml b/bndtools.core/_plugin.xml index 1ab4ff787a..64401dbdc3 100644 --- a/bndtools.core/_plugin.xml +++ b/bndtools.core/_plugin.xml @@ -839,7 +839,7 @@ helpUrl="https://bnd.bndtools.org/plugins/filerepo.html"> - + @@ -850,7 +850,7 @@ helpUrl="https://bnd.bndtools.org/plugins/osgirepo.html"> - + - + - + @@ -922,7 +922,7 @@ name="P2Repository" helpUrl="https://bnd.bndtools.org/plugins/p2repo.html"> - + @@ -932,7 +932,7 @@ name="Maven POM Repository" helpUrl="https://bnd.bndtools.org/plugins/pomrepo.html"> - + diff --git a/bndtools.core/src/bndtools/editor/workspace/PluginPropertiesPage.java b/bndtools.core/src/bndtools/editor/workspace/PluginPropertiesPage.java index d397967a58..8683d418cf 100644 --- a/bndtools.core/src/bndtools/editor/workspace/PluginPropertiesPage.java +++ b/bndtools.core/src/bndtools/editor/workspace/PluginPropertiesPage.java @@ -1,6 +1,10 @@ package bndtools.editor.workspace; import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.jface.fieldassist.ControlDecoration; @@ -15,6 +19,7 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; @@ -153,6 +158,30 @@ public void widgetSelected(SelectionEvent e) { changed = true; } }); + } + + else if ("combo".equals(propertyType)) { + final Combo combobox = new Combo(fieldContainer, SWT.BORDER); + combobox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + String options = propertyElement.getAttribute("options"); + if (options != null && !options.isBlank()) { + Collection optionValues = parseTrimmed(options); + combobox.setItems(optionValues.toArray(new String[0])); + } + + if (value != null) + combobox.setText(value); + + combobox.addModifyListener(e -> { + String value1 = combobox.getText(); + if (value1 == null || value1.length() == 0) + properties.remove(name); + else + properties.put(name, value1); + changed = true; + }); + } else { final Text text = new Text(fieldContainer, SWT.BORDER); text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); @@ -234,4 +263,13 @@ public void performHelp() { } } + static Collection parseTrimmed(String csvString) { + if (csvString == null || csvString.isBlank()) { + return List.of(); // empty + } + + return Arrays.stream(csvString.split(",")) + .map(String::trim) + .collect(Collectors.toList()); + } } From 7313fbce910caf7ca780a3a5e92f24e5a67065a0 Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Tue, 21 May 2024 20:32:08 +0200 Subject: [PATCH 12/12] rename to Tags.includesAny I think that better reflects the intent. - also adjusting javadoc accordingly - and move static methods to bottom Signed-off-by: Christoph Rueger --- .../src/aQute/bnd/service/Registry.java | 15 ++++- .../src/aQute/bnd/service/tags/Tags.java | 58 +++++++++++-------- 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java index 506a3e1a46..b149d81d09 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/Registry.java @@ -9,8 +9,21 @@ * A registry for objects. */ public interface Registry { + + /** + * @param + * @param c + * @return all plugins matching the given class + */ List getPlugins(Class c); + /** + * @param + * @param c + * @param tags + * @return all plugins matching the given class and any of the given tags. + * If no tags are given, all plugins are returned without filtering. + */ default List getPlugins(Class c, String... tags) { if (tags.length == 0) { @@ -19,7 +32,7 @@ default List getPlugins(Class c, String... tags) { return getPlugins(c).stream() .filter(repo -> repo instanceof Tagged taggedRepo && taggedRepo.getTags() - .isIncluded(tags)) + .includesAny(tags)) .collect(Collectors.toList()); } diff --git a/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java b/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java index 0895296298..b1ca71a129 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java +++ b/biz.aQute.bndlib/src/aQute/bnd/service/tags/Tags.java @@ -29,27 +29,6 @@ private Tags(Collection c) { this.internalSet = unmodifiableSortedSet(new TreeSet<>(c)); } - public static Tags of(String... name) { - return new Tags(Set.of(name)); - } - - /** - * Parses a comma-separated string of tags into a Tags object. - * - * @param csvTags - * @param defaultTags a default used when csvTags is null or blank - * @return populated Tags or the passed defaultTags. - */ - public static Tags parse(String csvTags, Tags defaultTags) { - if (csvTags == null || csvTags.isBlank()) { - return defaultTags; // default - } - - return new Tags(Arrays.stream(csvTags.split(",")) - .map(String::trim) - .collect(Collectors.toCollection(LinkedHashSet::new))); - } - @Override public int size() { return internalSet.size(); @@ -131,14 +110,19 @@ public String toString() { } /** - * @param * @param tags - * @return true if the passed object matches any of the given - * tags, otherwise returns false + * @return true if any of the given tags is included in the + * current set of tags, otherwise returns false. Also + * if the current set of tags is empty, also true is + * returned. */ - public boolean isIncluded(String... tags) { + public boolean includesAny(String... tags) { if (isEmpty()) { + // this is on purpose to maintain backwards compatibility for + // entities which do not handle tags yet and return an empty set. In + // other words: if the current set is + // empty that means "yes I match any of what you passed". return true; } @@ -151,5 +135,29 @@ public boolean isIncluded(String... tags) { return false; } + /** + * @param name + * @return a Tags instance with the given tags. + */ + public static Tags of(String... name) { + return new Tags(Set.of(name)); + } + + /** + * Parses a comma-separated string of tags into a Tags object. + * + * @param csvTags + * @param defaultTags a default used when csvTags is null or blank + * @return populated Tags or the passed defaultTags. + */ + public static Tags parse(String csvTags, Tags defaultTags) { + if (csvTags == null || csvTags.isBlank()) { + return defaultTags; // default + } + + return new Tags(Arrays.stream(csvTags.split(",")) + .map(String::trim) + .collect(Collectors.toCollection(LinkedHashSet::new))); + } }