mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
Support 'keywords' field in addon.xml schema (#5352)
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
This commit is contained in:
+1
@@ -144,6 +144,7 @@ public class EclipseAddonService implements AddonService {
|
||||
if (addonInfo != null) {
|
||||
// only enrich if this add-on is installed, otherwise wrong data might be added
|
||||
addon = addon.withLabel(addonInfo.getName()).withDescription(addonInfo.getDescription())
|
||||
.withKeywords(Objects.requireNonNullElse(addonInfo.getKeywords(), ""))
|
||||
.withConnection(addonInfo.getConnection()).withCountries(addonInfo.getCountries())
|
||||
.withLink(getDefaultDocumentationLink(type, name))
|
||||
.withConfigDescriptionURI(addonInfo.getConfigDescriptionURI());
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ public class JsonAddonService extends AbstractRemoteAddonService {
|
||||
.withDetailedDescription(addonEntry.description).withContentType(addonEntry.contentType)
|
||||
.withAuthor(addonEntry.author).withVersion(addonEntry.version).withLabel(addonEntry.title)
|
||||
.withCompatible(compatible).withMaturity(addonEntry.maturity).withProperties(properties)
|
||||
.withLink(addonEntry.link).withImageLink(addonEntry.imageUrl)
|
||||
.withLink(addonEntry.link).withImageLink(addonEntry.imageUrl).withKeywords(addonEntry.keywords)
|
||||
.withConfigDescriptionURI(addonEntry.configDescriptionURI).withLoggerPackages(addonEntry.loggerPackages)
|
||||
.withConnection(addonEntry.connection).withCountries(addonEntry.countries).build();
|
||||
}
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ public class AddonEntryDTO {
|
||||
public String id = "";
|
||||
public String type = "";
|
||||
public String description = "";
|
||||
public String keywords = "";
|
||||
public String title = "";
|
||||
public String link = "";
|
||||
public String version = "";
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
<xs:element name="type" type="addon:addonType"/>
|
||||
<xs:element name="name" type="xs:string"/>
|
||||
<xs:element name="description" type="xs:string"/>
|
||||
<xs:element name="keywords" type="xs:string" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Comma-separated list of key words for search.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="connection" type="addon:connectionType" minOccurs="0"/>
|
||||
<xs:element name="countries" type="addon:countryType" minOccurs="0">
|
||||
<xs:annotation>
|
||||
|
||||
@@ -41,6 +41,7 @@ public class AddonInfo implements Identifiable<String> {
|
||||
private final String uid;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final @Nullable String keywords;
|
||||
private final @Nullable String connection;
|
||||
private final List<String> countries;
|
||||
private final @Nullable String configDescriptionURI;
|
||||
@@ -49,8 +50,8 @@ public class AddonInfo implements Identifiable<String> {
|
||||
private @Nullable List<AddonDiscoveryMethod> discoveryMethods;
|
||||
|
||||
private AddonInfo(String id, String type, @Nullable String uid, String name, String description,
|
||||
@Nullable String connection, List<String> countries, @Nullable String configDescriptionURI,
|
||||
@Nullable String serviceId, @Nullable String sourceBundle,
|
||||
@Nullable String keywords, @Nullable String connection, List<String> countries,
|
||||
@Nullable String configDescriptionURI, @Nullable String serviceId, @Nullable String sourceBundle,
|
||||
@Nullable List<AddonDiscoveryMethod> discoveryMethods) throws IllegalArgumentException {
|
||||
// mandatory fields
|
||||
if (id.isBlank()) {
|
||||
@@ -73,6 +74,7 @@ public class AddonInfo implements Identifiable<String> {
|
||||
this.description = description;
|
||||
|
||||
// optional fields
|
||||
this.keywords = keywords;
|
||||
this.connection = connection;
|
||||
this.countries = countries;
|
||||
this.configDescriptionURI = configDescriptionURI;
|
||||
@@ -127,6 +129,15 @@ public class AddonInfo implements Identifiable<String> {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comma-separated list of keywords related to the add-on. e.g. "bluetooth".
|
||||
*
|
||||
* @return a comma-separated list of keywords, or null if no keywords string available
|
||||
*/
|
||||
public @Nullable String getKeywords() {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link to a concrete {@link org.openhab.core.config.core.ConfigDescription}.
|
||||
*
|
||||
@@ -168,6 +179,7 @@ public class AddonInfo implements Identifiable<String> {
|
||||
private @Nullable String uid;
|
||||
private String name = "";
|
||||
private String description = "";
|
||||
private @Nullable String keywords;
|
||||
private @Nullable String connection;
|
||||
private List<String> countries = List.of();
|
||||
private @Nullable String configDescriptionURI = "";
|
||||
@@ -186,6 +198,7 @@ public class AddonInfo implements Identifiable<String> {
|
||||
this.uid = addonInfo.uid;
|
||||
this.name = addonInfo.name;
|
||||
this.description = addonInfo.description;
|
||||
this.keywords = addonInfo.keywords;
|
||||
this.connection = addonInfo.connection;
|
||||
this.countries = addonInfo.countries;
|
||||
this.configDescriptionURI = addonInfo.configDescriptionURI;
|
||||
@@ -209,6 +222,11 @@ public class AddonInfo implements Identifiable<String> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withKeywords(@Nullable String keywords) {
|
||||
this.keywords = keywords;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withConnection(@Nullable String connection) {
|
||||
this.connection = connection;
|
||||
return this;
|
||||
@@ -251,8 +269,8 @@ public class AddonInfo implements Identifiable<String> {
|
||||
* @throws IllegalArgumentException if any of the information in this builder is invalid
|
||||
*/
|
||||
public AddonInfo build() throws IllegalArgumentException {
|
||||
return new AddonInfo(id, type, uid, name, description, connection, countries, configDescriptionURI,
|
||||
serviceId, sourceBundle, discoveryMethods);
|
||||
return new AddonInfo(id, type, uid, name, description, keywords, connection, countries,
|
||||
configDescriptionURI, serviceId, sourceBundle, discoveryMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.core.addon;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
@@ -98,6 +99,16 @@ public class AddonInfoRegistry {
|
||||
if (a.getDescription().isBlank()) {
|
||||
builder.withDescription(b.getDescription());
|
||||
}
|
||||
Set<String> keywords = new HashSet<>();
|
||||
if (a.getKeywords() instanceof String ka) {
|
||||
Arrays.stream(ka.split(",")).map(String::trim).filter(s -> !s.isEmpty()).forEach(keywords::add);
|
||||
}
|
||||
if (b.getKeywords() instanceof String kb) {
|
||||
Arrays.stream(kb.split(",")).map(String::trim).filter(s -> !s.isEmpty()).forEach(keywords::add);
|
||||
}
|
||||
if (!keywords.isEmpty()) {
|
||||
builder.withKeywords(keywords.stream().collect(Collectors.joining(",")));
|
||||
}
|
||||
if (a.getConnection() == null && b.getConnection() != null) {
|
||||
builder.withConnection(b.getConnection());
|
||||
}
|
||||
|
||||
+1
@@ -157,6 +157,7 @@ public class JarFileAddonService extends BundleTracker<Bundle> implements AddonS
|
||||
.withConnection(addonInfo.getConnection()).withCountries(addonInfo.getCountries())
|
||||
.withConfigDescriptionURI(addonInfo.getConfigDescriptionURI())
|
||||
.withDescription(Objects.requireNonNullElse(addonInfo.getDescription(), bundle.getSymbolicName()))
|
||||
.withKeywords(Objects.requireNonNullElse(addonInfo.getKeywords(), ""))
|
||||
.withContentType(ADDONS_CONTENT_TYPE).withLoggerPackages(List.of(bundle.getSymbolicName())).build();
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -87,6 +87,8 @@ public class AddonInfoConverter extends GenericUnmarshaller<AddonInfoXmlResult>
|
||||
"Add-on description is null or empty");
|
||||
|
||||
AddonInfo.Builder addonInfo = AddonInfo.builder(id, type).withName(name).withDescription(description);
|
||||
|
||||
addonInfo.withKeywords((String) nodeIterator.nextValue("keywords", false));
|
||||
addonInfo.withConnection((String) nodeIterator.nextValue("connection", false));
|
||||
addonInfo.withCountries((String) nodeIterator.nextValue("countries", false));
|
||||
addonInfo.withServiceId((String) nodeIterator.nextValue("service-id", false));
|
||||
|
||||
+1
@@ -82,6 +82,7 @@ public class AddonInfoListReader extends XmlDocumentReader<AddonInfoList> {
|
||||
xstream.alias("name", NodeValue.class);
|
||||
xstream.alias("description", NodeValue.class);
|
||||
xstream.alias("type", NodeValue.class);
|
||||
xstream.alias("keywords", NodeValue.class);
|
||||
xstream.alias("connection", NodeValue.class);
|
||||
xstream.alias("countries", NodeValue.class);
|
||||
xstream.alias("config-description", ConfigDescription.class);
|
||||
|
||||
+1
@@ -81,6 +81,7 @@ public class AddonInfoReader extends XmlDocumentReader<AddonInfoXmlResult> {
|
||||
xstream.alias("name", NodeValue.class);
|
||||
xstream.alias("description", NodeValue.class);
|
||||
xstream.alias("type", NodeValue.class);
|
||||
xstream.alias("keywords", NodeValue.class);
|
||||
xstream.alias("connection", NodeValue.class);
|
||||
xstream.alias("countries", NodeValue.class);
|
||||
xstream.alias("config-description", ConfigDescription.class);
|
||||
|
||||
+2
@@ -37,6 +37,7 @@ class AddonInfoListReaderTest {
|
||||
+ " <type>automation</type>"
|
||||
+ " <name>Groovy Scripting</name>"
|
||||
+ " <description>This adds a Groovy script engine.</description>"
|
||||
+ " <keywords>The,quick,brown,fox</keywords>"
|
||||
+ " <connection>none</connection>"
|
||||
+ " <discovery-methods>"
|
||||
+ " <discovery-method>"
|
||||
@@ -86,6 +87,7 @@ class AddonInfoListReaderTest {
|
||||
assertEquals(1, addonsInfos.size());
|
||||
AddonInfo addon = addonsInfos.getFirst();
|
||||
assertNotNull(addon);
|
||||
assertEquals("The,quick,brown,fox", addon.getKeywords());
|
||||
List<AddonDiscoveryMethod> discoveryMethods = addon.getDiscoveryMethods();
|
||||
assertNotNull(discoveryMethods);
|
||||
assertEquals(2, discoveryMethods.size());
|
||||
|
||||
+8
-2
@@ -13,6 +13,7 @@
|
||||
package org.openhab.core.addon;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.List;
|
||||
@@ -47,7 +48,7 @@ class AddonInfoRegistryMergeTest {
|
||||
}
|
||||
|
||||
private AddonInfoProvider createAddonInfoProvider0() {
|
||||
AddonInfo addonInfo = AddonInfo.builder("hue", "binding").withName("name-zero")
|
||||
AddonInfo addonInfo = AddonInfo.builder("hue", "binding").withName("name-zero").withKeywords("the,quick")
|
||||
.withDescription("description-zero").build();
|
||||
AddonInfoProvider provider = mock(AddonInfoProvider.class);
|
||||
when(provider.getAddonInfo(anyString(), any(Locale.class))).thenReturn(null);
|
||||
@@ -60,7 +61,7 @@ class AddonInfoRegistryMergeTest {
|
||||
private AddonInfoProvider createAddonInfoProvider1() {
|
||||
AddonDiscoveryMethod discoveryMethod = new AddonDiscoveryMethod().setServiceType("mdns")
|
||||
.setParameters(List.of(new AddonParameter("mdnsServiceType", "_hue._tcp.local.")));
|
||||
AddonInfo addonInfo = AddonInfo.builder("hue", "binding").withName("name-one")
|
||||
AddonInfo addonInfo = AddonInfo.builder("hue", "binding").withName("name-one").withKeywords("brown,fox")
|
||||
.withDescription("description-one").withCountries("GB,NL").withConnection("local")
|
||||
.withDiscoveryMethods(List.of(discoveryMethod)).build();
|
||||
AddonInfoProvider provider = mock(AddonInfoProvider.class);
|
||||
@@ -150,6 +151,11 @@ class AddonInfoRegistryMergeTest {
|
||||
assertNotEquals("http://www.openhab.org", addonInfo.getConfigDescriptionURI());
|
||||
assertEquals("binding.hue", addonInfo.getServiceId());
|
||||
assertEquals(1, addonInfo.getDiscoveryMethods().size());
|
||||
|
||||
assertTrue(addonInfo.getKeywords().contains("the"));
|
||||
assertTrue(addonInfo.getKeywords().contains("quick"));
|
||||
assertTrue(addonInfo.getKeywords().contains("brown"));
|
||||
assertTrue(addonInfo.getKeywords().contains("fox"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
@@ -21,6 +21,7 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.karaf.features.Feature;
|
||||
import org.apache.karaf.features.FeaturesService;
|
||||
@@ -135,6 +136,7 @@ public class KarafAddonService implements AddonService {
|
||||
|
||||
if (addonInfo != null) {
|
||||
addon = addon.withLabel(addonInfo.getName()).withDescription(addonInfo.getDescription())
|
||||
.withKeywords(Objects.requireNonNullElse(addonInfo.getKeywords(), ""))
|
||||
.withConnection(addonInfo.getConnection()).withCountries(addonInfo.getCountries())
|
||||
.withLink(getDefaultDocumentationLink(type, name))
|
||||
.withConfigDescriptionURI(addonInfo.getConfigDescriptionURI());
|
||||
|
||||
Reference in New Issue
Block a user