diff --git a/bundles/org.openhab.core.addon.marketplace/src/main/java/org/openhab/core/addon/marketplace/internal/community/CommunityMarketplaceAddonService.java b/bundles/org.openhab.core.addon.marketplace/src/main/java/org/openhab/core/addon/marketplace/internal/community/CommunityMarketplaceAddonService.java index 20a187f3e..0f5c03dc4 100644 --- a/bundles/org.openhab.core.addon.marketplace/src/main/java/org/openhab/core/addon/marketplace/internal/community/CommunityMarketplaceAddonService.java +++ b/bundles/org.openhab.core.addon.marketplace/src/main/java/org/openhab/core/addon/marketplace/internal/community/CommunityMarketplaceAddonService.java @@ -273,7 +273,7 @@ public class CommunityMarketplaceAddonService implements AddonService { return ""; } - private @Nullable AddonType getAddonType(@Nullable Integer category, String[] tags) { + private @Nullable AddonType getAddonType(@Nullable Integer category, List tags) { // check if we can determine the addon type from the category if (RULETEMPLATES_CATEGORY.equals(category)) { return TAG_ADDON_TYPE_MAP.get("automation"); @@ -281,26 +281,21 @@ public class CommunityMarketplaceAddonService implements AddonService { return TAG_ADDON_TYPE_MAP.get("ui"); } else if (BUNDLES_CATEGORY.equals(category)) { // try to get it from tags if we have tags - for (String tag : tags) { - AddonType addonType = TAG_ADDON_TYPE_MAP.get(tag); - if (addonType != null) { - return addonType; - } - } + return tags.stream().map(TAG_ADDON_TYPE_MAP::get).filter(Objects::nonNull).findFirst().orElse(null); } // or return null return null; } - private String getContentType(@Nullable Integer category, String[] tags) { + private String getContentType(@Nullable Integer category, List tags) { // check if we can determine the addon type from the category if (RULETEMPLATES_CATEGORY.equals(category)) { return RULETEMPLATES_CONTENT_TYPE; } else if (UIWIDGETS_CATEGORY.equals(category)) { return UIWIDGETS_CONTENT_TYPE; } else if (BUNDLES_CATEGORY.equals(category)) { - if (Arrays.asList(tags).contains("kar")) { + if (tags.contains("kar")) { return KAR_CONTENT_TYPE; } else { // default to plain jar bundle for addons @@ -319,14 +314,13 @@ public class CommunityMarketplaceAddonService implements AddonService { * @return the list item */ private Addon convertTopicItemToAddon(DiscourseTopicItem topic, List users) { - String id = ADDON_ID_PREFIX + topic.id.toString(); - String[] tags = Objects.requireNonNullElse(topic.tags, new String[0]); + List tags = Arrays.asList(Objects.requireNonNullElse(topic.tags, new String[0])); + String id = ADDON_ID_PREFIX + topic.id.toString(); AddonType addonType = getAddonType(topic.category_id, tags); String type = (addonType != null) ? addonType.getId() : ""; String contentType = getContentType(topic.category_id, tags); - String version = ""; String title = topic.title; String link = COMMUNITY_TOPIC_URL + topic.id.toString(); int likeCount = topic.like_count; @@ -334,51 +328,28 @@ public class CommunityMarketplaceAddonService implements AddonService { int postsCount = topic.posts_count; Date createdDate = topic.created_at; String author = ""; - boolean verifiedAuthor = false; for (DiscoursePosterInfo posterInfo : topic.posters) { if (posterInfo.description.contains("Original Poster")) { author = users.stream().filter(u -> u.id.equals(posterInfo.user_id)).findFirst().get().name; } } - String maturity = null; - for (String tag : tags) { - if (CODE_MATURITY_LEVELS.contains(tag)) { - maturity = tag; - break; - } - } + String maturity = tags.stream().filter(CODE_MATURITY_LEVELS::contains).findAny().orElse(null); HashMap properties = new HashMap<>(10); properties.put("created_at", createdDate); properties.put("like_count", likeCount); properties.put("views", views); properties.put("posts_count", postsCount); - properties.put("tags", tags); - - String description = ""; - String detailedDescription = ""; + properties.put("tags", tags.toArray(String[]::new)); // try to use an handler to determine if the add-on is installed - boolean installed = false; - for (MarketplaceAddonHandler handler : addonHandlers) { - if (handler.supports(type, contentType)) { - if (handler.isInstalled(id)) { - installed = true; - } - } - } + boolean installed = addonHandlers.stream() + .anyMatch(handler -> handler.supports(type, contentType) && handler.isInstalled(id)); - String configDescriptionURI = ""; - String keywords = ""; - String countries = ""; - String connection = ""; - String backgroundColor = ""; - String imageLink = topic.image_url; - Addon addon = new Addon(id, type, title, version, maturity, contentType, link, author, verifiedAuthor, - installed, description, detailedDescription, configDescriptionURI, keywords, countries, null, - connection, backgroundColor, imageLink, properties); - return addon; + return Addon.create(id).withType(type).withContentType(contentType).withImageLink(topic.image_url) + .withAuthor(author).withProperties(properties).withLabel(title).withInstalled(installed) + .withMaturity(maturity).withLink(link).build(); } /** @@ -400,31 +371,20 @@ public class CommunityMarketplaceAddonService implements AddonService { */ private Addon convertTopicToAddon(DiscourseTopicResponseDTO topic) { String id = ADDON_ID_PREFIX + topic.id.toString(); - String[] tags = Objects.requireNonNullElse(topic.tags, new String[0]); + List tags = Arrays.asList(Objects.requireNonNullElse(topic.tags, new String[0])); AddonType addonType = getAddonType(topic.category_id, tags); String type = (addonType != null) ? addonType.getId() : ""; String contentType = getContentType(topic.category_id, tags); - String version = ""; - String title = topic.title; - String link = COMMUNITY_TOPIC_URL + topic.id.toString(); int likeCount = topic.like_count; int views = topic.views; int postsCount = topic.posts_count; Date createdDate = topic.post_stream.posts[0].created_at; Date updatedDate = topic.post_stream.posts[0].updated_at; Date lastPostedDate = topic.last_posted; - String author = topic.post_stream.posts[0].display_username; - boolean verifiedAuthor = false; - String maturity = null; - for (String tag : tags) { - if (CODE_MATURITY_LEVELS.contains(tag)) { - maturity = tag; - break; - } - } + String maturity = tags.stream().filter(CODE_MATURITY_LEVELS::contains).findAny().orElse(null); HashMap properties = new HashMap<>(10); properties.put("created_at", createdDate); @@ -433,9 +393,8 @@ public class CommunityMarketplaceAddonService implements AddonService { properties.put("like_count", likeCount); properties.put("views", views); properties.put("posts_count", postsCount); - properties.put("tags", tags); + properties.put("tags", tags.toArray(String[]::new)); - String description = ""; String detailedDescription = topic.post_stream.posts[0].cooked; // try to extract contents or links @@ -469,24 +428,14 @@ public class CommunityMarketplaceAddonService implements AddonService { } // try to use an handler to determine if the add-on is installed - boolean installed = false; - for (MarketplaceAddonHandler handler : addonHandlers) { - if (handler.supports(type, contentType)) { - if (handler.isInstalled(id)) { - installed = true; - } - } - } + boolean installed = addonHandlers.stream() + .anyMatch(handler -> handler.supports(type, contentType) && handler.isInstalled(id)); - String configDescriptionURI = ""; - String keywords = ""; - String countries = ""; - String connection = ""; - String backgroundColor = ""; - Addon addon = new Addon(id, type, title, version, maturity, contentType, link, author, verifiedAuthor, - installed, description, detailedDescription, configDescriptionURI, keywords, countries, null, - connection, backgroundColor, null, properties); - return addon; + return Addon.create(id).withType(type).withContentType(contentType).withLabel(topic.title) + .withLink(COMMUNITY_TOPIC_URL + topic.id.toString()) + .withAuthor(topic.post_stream.posts[0].display_username).withMaturity(maturity) + .withDetailedDescription(detailedDescription).withInstalled(installed).withProperties(properties) + .build(); } private void postInstalledEvent(String extensionId) { diff --git a/bundles/org.openhab.core.addon.sample/src/main/java/org/openhab/core/addon/sample/internal/SampleAddonService.java b/bundles/org.openhab.core.addon.sample/src/main/java/org/openhab/core/addon/sample/internal/SampleAddonService.java index 20f27043d..b62473708 100644 --- a/bundles/org.openhab.core.addon.sample/src/main/java/org/openhab/core/addon/sample/internal/SampleAddonService.java +++ b/bundles/org.openhab.core.addon.sample/src/main/java/org/openhab/core/addon/sample/internal/SampleAddonService.java @@ -78,11 +78,11 @@ public class SampleAddonService implements AddonService { String version = "1.0"; String link = (Math.random() < 0.5) ? null : "http://lmgtfy.com/?q=" + name; String description = createDescription(); - String imageLink = null; String backgroundColor = createRandomColor(); - Addon extension = new Addon(id, typeId, label, version, "stable", "example/vnd.openhab.addon", link, - "John Doe", false, installed, description, backgroundColor, imageLink, null, null, null, null, - null, null, null); + Addon extension = Addon.create(id).withType(typeId).withLabel(label).withVersion(version) + .withMaturity("stable").withContentType("example/vnd.openhab.addon").withLink(link) + .withAuthor("John Doe", false).withInstalled(installed).withDescription(description) + .withBackgroundColor(backgroundColor).build(); extensions.put(extension.getId(), extension); } } diff --git a/bundles/org.openhab.core.karaf/src/main/java/org/openhab/core/karaf/internal/KarafAddonService.java b/bundles/org.openhab.core.karaf/src/main/java/org/openhab/core/karaf/internal/KarafAddonService.java index 3944c521e..65e658890 100644 --- a/bundles/org.openhab.core.karaf/src/main/java/org/openhab/core/karaf/internal/KarafAddonService.java +++ b/bundles/org.openhab.core.karaf/src/main/java/org/openhab/core/karaf/internal/KarafAddonService.java @@ -119,9 +119,6 @@ public class KarafAddonService implements AddonService { private Addon getAddon(Feature feature) { String name = getName(feature.getName()); String type = getType(feature.getName()); - String extId = type + "-" + name; - String label = feature.getDescription(); - String version = feature.getVersion(); String link = null; switch (type) { case FeatureInstaller.EXTENSION_TYPE_AUTOMATION: @@ -148,8 +145,10 @@ public class KarafAddonService implements AddonService { default: break; } - boolean installed = featuresService.isInstalled(feature); - return new Addon(extId, type, label, version, ADDONS_CONTENTTYPE, link, ADDONS_AUTHOR, true, installed); + + return Addon.create(type + "-" + name).withType(type).withLabel(feature.getDescription()) + .withVersion(feature.getVersion()).withContentType(ADDONS_CONTENTTYPE).withLink(link) + .withAuthor(ADDONS_AUTHOR, true).withInstalled(featuresService.isInstalled(feature)).build(); } @Override diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/addon/Addon.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/addon/Addon.java index c118154d4..68a3ade20 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/addon/Addon.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/addon/Addon.java @@ -12,6 +12,7 @@ */ package org.openhab.core.addon; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -45,25 +46,6 @@ public class Addon { private final String imageLink; private final Map properties; - /** - * Creates a new Addon instance - * - * @param id the id of the add-on - * @param type the type id of the add-on - * @param label the label of the add-on - * @param version the version of the add-on - * @param contentType the content type of the add-on - * @param link the link to find more information about the add-on (can be null) - * @param author the author of the add-on - * @param verifiedAuthor true, if the author is verified - * @param installed true, if the add-on is installed, false otherwise - */ - public Addon(String id, String type, String label, String version, String contentType, String link, String author, - boolean verifiedAuthor, boolean installed) { - this(id, type, label, version, null, contentType, link, author, verifiedAuthor, installed, null, null, null, - null, null, null, null, null, null, null); - } - /** * Creates a new Addon instance * @@ -89,10 +71,10 @@ public class Addon { * @param imageLink the link to an image (png/svg) (may be null) * @param properties a {@link Map} containing addition information */ - public Addon(String id, String type, String label, String version, String maturity, String contentType, String link, - String author, boolean verifiedAuthor, boolean installed, String description, String detailedDescription, - String configDescriptionURI, String keywords, String countries, String license, String connection, - String backgroundColor, String imageLink, Map properties) { + private Addon(String id, String type, String label, String version, String maturity, String contentType, + String link, String author, boolean verifiedAuthor, boolean installed, String description, + String detailedDescription, String configDescriptionURI, String keywords, String countries, String license, + String connection, String backgroundColor, String imageLink, Map properties) { this.id = id; this.label = label; this.version = version; @@ -261,4 +243,142 @@ public class Addon { public String getImageLink() { return imageLink; } + + public static Builder create(String id) { + return new Builder(id); + } + + public static class Builder { + private String id; + private String label; + private String version = ""; + private String maturity = null; + private String contentType; + private String link; + private String author = ""; + private boolean verifiedAuthor = false; + private boolean installed = false; + private String type; + private String description = ""; + private String detailedDescription; + private String configDescriptionURI = ""; + private String keywords = ""; + private String countries = ""; + private String license = null; + private String connection = ""; + private String backgroundColor; + private String imageLink = null; + private Map properties = new HashMap<>(); + + private Builder(String id) { + this.id = id; + } + + public Builder withLabel(String label) { + this.label = label; + return this; + } + + public Builder withVersion(String version) { + this.version = version; + return this; + } + + public Builder withMaturity(String maturity) { + this.maturity = maturity; + return this; + } + + public Builder withContentType(String contentType) { + this.contentType = contentType; + return this; + } + + public Builder withLink(String link) { + this.link = link; + return this; + } + + public Builder withAuthor(String author) { + this.author = author; + return this; + } + + public Builder withAuthor(String author, boolean verifiedAuthor) { + this.author = author; + this.verifiedAuthor = verifiedAuthor; + return this; + } + + public Builder withInstalled(boolean installed) { + this.installed = installed; + return this; + } + + public Builder withType(String type) { + this.type = type; + return this; + } + + public Builder withDescription(String description) { + this.description = description; + return this; + } + + public Builder withDetailedDescription(String detailedDescription) { + this.detailedDescription = detailedDescription; + return this; + } + + public Builder withConfigDescriptionURI(String configDescriptionURI) { + this.configDescriptionURI = configDescriptionURI; + return this; + } + + public Builder withKeywords(String keywords) { + this.keywords = keywords; + return this; + } + + public Builder withCountries(String countries) { + this.countries = countries; + return this; + } + + public Builder withLicense(String license) { + this.license = license; + return this; + } + + public Builder withConnection(String connection) { + this.connection = connection; + return this; + } + + public Builder withBackgroundColor(String backgroundColor) { + this.backgroundColor = backgroundColor; + return this; + } + + public Builder withImageLink(String imageLink) { + this.imageLink = imageLink; + return this; + } + + public Builder withProperty(String key, Object value) { + this.properties.put(key, value); + return this; + } + + public Builder withProperties(Map properties) { + this.properties.putAll(properties); + return this; + } + + public Addon build() { + return new Addon(id, type, label, version, maturity, contentType, link, author, verifiedAuthor, installed, + description, detailedDescription, configDescriptionURI, keywords, countries, license, connection, + backgroundColor, imageLink, properties.isEmpty() ? null : properties); + } + } }