Skip to content

Commit

Permalink
[addonservices] allow uninstalling of removed addons
Browse files Browse the repository at this point in the history
Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
  • Loading branch information
J-N-K committed Dec 11, 2021
1 parent 8a29b07 commit ef2078c
Showing 1 changed file with 40 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import org.openhab.core.config.core.ConfigurableService;
import org.openhab.core.events.Event;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.storage.Storage;
import org.openhab.core.storage.StorageService;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
Expand All @@ -58,12 +60,13 @@
* @author Yannick Schaus - Initial contribution
* @author Jan N. Klug - Refactored for JSON marketplaces
*/
@Component(immediate = true, configurationPid = "org.openhab.jsonaddonservice", //
property = Constants.SERVICE_PID + "=org.openhab.jsonaddonservice")
@Component(immediate = true, configurationPid = JsonAddonService.SERVICE_PID, //
property = Constants.SERVICE_PID + "=" + JsonAddonService.SERVICE_PID)
@ConfigurableService(category = "system", label = JsonAddonService.SERVICE_NAME, description_uri = JsonAddonService.CONFIG_URI)
public class JsonAddonService implements AddonService {
static final String SERVICE_NAME = "Json 3rd Party Add-on Service";
static final String CONFIG_URI = "system:jsonaddonservice";
static final String SERVICE_PID = "org.openhab.jsonaddonservice";

private static final String SERVICE_ID = "json";
private static final String ADDON_ID_PREFIX = SERVICE_ID + ":";
Expand All @@ -82,6 +85,7 @@ public class JsonAddonService implements AddonService {

private final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
private final Set<MarketplaceAddonHandler> addonHandlers = new HashSet<>();
private final Storage<String> installedAddonStorage;

private List<String> addonserviceUrls = List.of();
private List<AddonEntryDTO> cachedAddons = List.of();
Expand All @@ -91,8 +95,10 @@ public class JsonAddonService implements AddonService {
private final EventPublisher eventPublisher;

@Activate
public JsonAddonService(@Reference EventPublisher eventPublisher, Map<String, Object> config) {
public JsonAddonService(@Reference EventPublisher eventPublisher, @Reference StorageService storageService,
Map<String, Object> config) {
this.eventPublisher = eventPublisher;
this.installedAddonStorage = storageService.getStorage(SERVICE_PID);
modified(config);
}

Expand Down Expand Up @@ -126,7 +132,14 @@ public String getName() {
@Override
@SuppressWarnings("unchecked")
public void refreshSource() {
cachedAddons = (List<AddonEntryDTO>) addonserviceUrls.stream().map(urlString -> {
List<AddonEntryDTO> addons = new ArrayList<>();
// all addons from storage
installedAddonStorage.stream().map(e -> fromAddon(e.getKey(), gson.fromJson(e.getValue(), Addon.class)))
.forEach(addons::add);
// create lookup list to make sure installed addons take precedence
List<String> installedAddons = addons.stream().map(e -> e.id).collect(Collectors.toList());

addonserviceUrls.stream().map(urlString -> {
try {
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
Expand All @@ -138,8 +151,9 @@ public void refreshSource() {
} catch (IOException e) {
return List.of();
}
}).flatMap(List::stream).filter(e -> showUnstable || "stable".equals(((AddonEntryDTO) e).maturity))
.collect(Collectors.toList());
}).flatMap(List::stream).map(e -> (AddonEntryDTO) e).filter(e -> showUnstable || "stable".equals(e.maturity))
.filter(e -> !installedAddons.contains(e.id)).forEach(addons::add);
cachedAddons = addons;
}

@Override
Expand Down Expand Up @@ -172,6 +186,7 @@ public void install(String id) {
if (!handler.isInstalled(addon.getId())) {
try {
handler.install(addon);
installedAddonStorage.put(id, gson.toJson(addon));
postInstalledEvent(addon.getId());
} catch (MarketplaceHandlerException e) {
postFailureEvent(addon.getId(), e.getMessage());
Expand All @@ -197,6 +212,7 @@ public void uninstall(String id) {
if (handler.isInstalled(addon.getId())) {
try {
handler.uninstall(addon);
installedAddonStorage.remove(id);
postUninstalledEvent(addon.getId());
} catch (MarketplaceHandlerException e) {
postFailureEvent(addon.getId(), e.getMessage());
Expand Down Expand Up @@ -238,6 +254,24 @@ private Addon fromAddonEntry(AddonEntryDTO addonEntry) {
.withConfigDescriptionURI(addonEntry.configDescriptionURI).build();
}

private AddonEntryDTO fromAddon(String id, Addon addon) {
AddonEntryDTO dto = new AddonEntryDTO();
dto.id = id;
dto.type = addon.getType();
dto.description = addon.getDetailedDescription();
dto.title = addon.getLabel();
dto.link = addon.getLink();
dto.version = addon.getVersion();
dto.author = addon.getAuthor();
dto.configDescriptionURI = addon.getConfigDescriptionURI();
dto.maturity = addon.getMaturity();
dto.contentType = addon.getContentType();
Map<String, Object> properties = addon.getProperties();
dto.url = (String) properties.entrySet().stream().filter(p -> p.getKey().endsWith("url")).findFirst()
.map(Map.Entry::getValue).orElse("");
return dto;
}

private void postInstalledEvent(String extensionId) {
Event event = AddonEventFactory.createAddonInstalledEvent(extensionId);
eventPublisher.post(event);
Expand Down

0 comments on commit ef2078c

Please sign in to comment.