[cleanup] refactored Extension to Addon (#1560)
* refactored Extension to Addon Signed-off-by: Kai Kreuzer <kai@openhab.org>pull/1567/head
parent
65b16404c0
commit
8218f44667
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.core.extension.sample</name>
|
||||
<name>org.openhab.core.addon.sample</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
|
@ -10,9 +10,9 @@
|
|||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.core.extension.sample</artifactId>
|
||||
<artifactId>org.openhab.core.addon.sample</artifactId>
|
||||
|
||||
<name>openHAB Core :: Bundles :: Sample Extension Service</name>
|
||||
<name>openHAB Core :: Bundles :: Sample Add-on Service</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.extension.sample.internal;
|
||||
package org.openhab.core.addon.sample.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -21,26 +21,26 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.openhab.core.addon.Addon;
|
||||
import org.openhab.core.addon.AddonEventFactory;
|
||||
import org.openhab.core.addon.AddonService;
|
||||
import org.openhab.core.addon.AddonType;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.extension.Extension;
|
||||
import org.openhab.core.extension.ExtensionEventFactory;
|
||||
import org.openhab.core.extension.ExtensionService;
|
||||
import org.openhab.core.extension.ExtensionType;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Deactivate;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* This is an implementation of an {@link ExtensionService} that can be used as a dummy service for testing the
|
||||
* This is an implementation of an {@link AddonService} that can be used as a dummy service for testing the
|
||||
* functionality.
|
||||
* It is not meant to be used anywhere productively.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@Component
|
||||
public class SampleExtensionService implements ExtensionService {
|
||||
public class SampleAddonService implements AddonService {
|
||||
|
||||
private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
|
||||
|
||||
|
@ -48,8 +48,8 @@ public class SampleExtensionService implements ExtensionService {
|
|||
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
List<ExtensionType> types = new ArrayList<>(3);
|
||||
Map<String, Extension> extensions = new HashMap<>(30);
|
||||
List<AddonType> types = new ArrayList<>(3);
|
||||
Map<String, Addon> extensions = new HashMap<>(30);
|
||||
|
||||
@Reference
|
||||
protected void setEventPublisher(EventPublisher eventPublisher) {
|
||||
|
@ -62,11 +62,11 @@ public class SampleExtensionService implements ExtensionService {
|
|||
|
||||
@Activate
|
||||
protected void activate() {
|
||||
types.add(new ExtensionType("binding", "Bindings"));
|
||||
types.add(new ExtensionType("ui", "User Interfaces"));
|
||||
types.add(new ExtensionType("persistence", "Persistence Services"));
|
||||
types.add(new AddonType("binding", "Bindings"));
|
||||
types.add(new AddonType("ui", "User Interfaces"));
|
||||
types.add(new AddonType("persistence", "Persistence Services"));
|
||||
|
||||
for (ExtensionType type : types) {
|
||||
for (AddonType type : types) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String id = type.getId() + Integer.toString(i);
|
||||
boolean installed = Math.random() > 0.5;
|
||||
|
@ -80,8 +80,8 @@ public class SampleExtensionService implements ExtensionService {
|
|||
String description = createDescription();
|
||||
String imageLink = null;
|
||||
String backgroundColor = createRandomColor();
|
||||
Extension extension = new Extension(id, typeId, label, version, link, installed, description,
|
||||
backgroundColor, imageLink);
|
||||
Addon extension = new Addon(id, typeId, label, version, link, installed, description, backgroundColor,
|
||||
imageLink);
|
||||
extensions.put(extension.getId(), extension);
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ public class SampleExtensionService implements ExtensionService {
|
|||
public void install(String id) {
|
||||
try {
|
||||
Thread.sleep((long) (Math.random() * 10000));
|
||||
Extension extension = getExtension(id, null);
|
||||
Addon extension = getAddon(id, null);
|
||||
extension.setInstalled(true);
|
||||
postInstalledEvent(id);
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -126,7 +126,7 @@ public class SampleExtensionService implements ExtensionService {
|
|||
public void uninstall(String id) {
|
||||
try {
|
||||
Thread.sleep((long) (Math.random() * 5000));
|
||||
Extension extension = getExtension(id, null);
|
||||
Addon extension = getAddon(id, null);
|
||||
extension.setInstalled(false);
|
||||
postUninstalledEvent(id);
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -134,35 +134,35 @@ public class SampleExtensionService implements ExtensionService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Extension> getExtensions(Locale locale) {
|
||||
public List<Addon> getAddons(Locale locale) {
|
||||
return new ArrayList<>(extensions.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extension getExtension(String id, Locale locale) {
|
||||
public Addon getAddon(String id, Locale locale) {
|
||||
return extensions.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionType> getTypes(Locale locale) {
|
||||
public List<AddonType> getTypes(Locale locale) {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtensionId(URI extensionURI) {
|
||||
public String getAddonId(URI extensionURI) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void postInstalledEvent(String extensionId) {
|
||||
if (eventPublisher != null) {
|
||||
Event event = ExtensionEventFactory.createExtensionInstalledEvent(extensionId);
|
||||
Event event = AddonEventFactory.createAddonInstalledEvent(extensionId);
|
||||
eventPublisher.post(event);
|
||||
}
|
||||
}
|
||||
|
||||
private void postUninstalledEvent(String extensionId) {
|
||||
if (eventPublisher != null) {
|
||||
Event event = ExtensionEventFactory.createExtensionUninstalledEvent(extensionId);
|
||||
Event event = AddonEventFactory.createAddonUninstalledEvent(extensionId);
|
||||
eventPublisher.post(event);
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ import org.osgi.service.component.annotations.Component;
|
|||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* This Script-Extension provides types and presets to support writing Rules using a ScriptEngine.
|
||||
* This Script-Addon provides types and presets to support writing Rules using a ScriptEngine.
|
||||
* One can write and register Rules and Modules by adding them through the HandlerRegistry and/or RuleRegistry
|
||||
*
|
||||
* @author Simon Merschjohann - Initial contribution
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.io.rest.core.internal.extensions;
|
||||
package org.openhab.core.io.rest.core.internal.addons;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -37,14 +37,14 @@ import javax.ws.rs.core.UriInfo;
|
|||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.addon.Addon;
|
||||
import org.openhab.core.addon.AddonEventFactory;
|
||||
import org.openhab.core.addon.AddonService;
|
||||
import org.openhab.core.addon.AddonType;
|
||||
import org.openhab.core.auth.Role;
|
||||
import org.openhab.core.common.ThreadPoolManager;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.extension.Extension;
|
||||
import org.openhab.core.extension.ExtensionEventFactory;
|
||||
import org.openhab.core.extension.ExtensionService;
|
||||
import org.openhab.core.extension.ExtensionType;
|
||||
import org.openhab.core.io.rest.JSONResponse;
|
||||
import org.openhab.core.io.rest.LocaleService;
|
||||
import org.openhab.core.io.rest.RESTConstants;
|
||||
|
@ -70,7 +70,7 @@ import io.swagger.annotations.ApiResponse;
|
|||
import io.swagger.annotations.ApiResponses;
|
||||
|
||||
/**
|
||||
* This class acts as a REST resource for extensions and provides methods to install and uninstall them.
|
||||
* This class acts as a REST resource for add-ons and provides methods to install and uninstall them.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
* @author Franck Dechavanne - Added DTOs to ApiResponses
|
||||
|
@ -78,45 +78,44 @@ import io.swagger.annotations.ApiResponses;
|
|||
*/
|
||||
@Component
|
||||
@JaxrsResource
|
||||
@JaxrsName(ExtensionResource.PATH_EXTENSIONS)
|
||||
@JaxrsName(AddonResource.PATH_ADDONS)
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + RESTConstants.JAX_RS_NAME + ")")
|
||||
@JSONRequired
|
||||
@Path(ExtensionResource.PATH_EXTENSIONS)
|
||||
@Path(AddonResource.PATH_ADDONS)
|
||||
@RolesAllowed({ Role.ADMIN })
|
||||
@Api(ExtensionResource.PATH_EXTENSIONS)
|
||||
@Api(AddonResource.PATH_ADDONS)
|
||||
@NonNullByDefault
|
||||
public class ExtensionResource implements RESTResource {
|
||||
public class AddonResource implements RESTResource {
|
||||
|
||||
private static final String THREAD_POOL_NAME = "extensionService";
|
||||
private static final String THREAD_POOL_NAME = "addonService";
|
||||
|
||||
public static final String PATH_EXTENSIONS = "extensions";
|
||||
public static final String PATH_ADDONS = "addons";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ExtensionResource.class);
|
||||
private final Set<ExtensionService> extensionServices = new CopyOnWriteArraySet<>();
|
||||
private final Logger logger = LoggerFactory.getLogger(AddonResource.class);
|
||||
private final Set<AddonService> addonServices = new CopyOnWriteArraySet<>();
|
||||
private final EventPublisher eventPublisher;
|
||||
private final LocaleService localeService;
|
||||
|
||||
private @Context @NonNullByDefault({}) UriInfo uriInfo;
|
||||
|
||||
@Activate
|
||||
public ExtensionResource(final @Reference EventPublisher eventPublisher,
|
||||
final @Reference LocaleService localeService) {
|
||||
public AddonResource(final @Reference EventPublisher eventPublisher, final @Reference LocaleService localeService) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
this.localeService = localeService;
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
|
||||
protected void addExtensionService(ExtensionService featureService) {
|
||||
this.extensionServices.add(featureService);
|
||||
protected void addExtensionService(AddonService featureService) {
|
||||
this.addonServices.add(featureService);
|
||||
}
|
||||
|
||||
protected void removeExtensionService(ExtensionService featureService) {
|
||||
this.extensionServices.remove(featureService);
|
||||
protected void removeExtensionService(AddonService featureService) {
|
||||
this.addonServices.remove(featureService);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get all extensions.")
|
||||
@ApiOperation(value = "Get all add-ons.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = String.class) })
|
||||
public Response getExtensions(
|
||||
@HeaderParam("Accept-Language") @ApiParam(value = "language") @Nullable String language) {
|
||||
|
@ -128,27 +127,27 @@ public class ExtensionResource implements RESTResource {
|
|||
@GET
|
||||
@Path("/types")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get all extension types.")
|
||||
@ApiOperation(value = "Get all add-on types.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = String.class) })
|
||||
public Response getTypes(@HeaderParam("Accept-Language") @ApiParam(value = "language") @Nullable String language) {
|
||||
logger.debug("Received HTTP GET request at '{}'", uriInfo.getPath());
|
||||
Locale locale = localeService.getLocale(language);
|
||||
Stream<ExtensionType> extensionTypeStream = getAllExtensionTypes(locale).stream().distinct();
|
||||
return Response.ok(new Stream2JSONInputStream(extensionTypeStream)).build();
|
||||
Stream<AddonType> addonTypeStream = getAllExtensionTypes(locale).stream().distinct();
|
||||
return Response.ok(new Stream2JSONInputStream(addonTypeStream)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{extensionId: [a-zA-Z_0-9-:]+}")
|
||||
@Path("/{addonId: [a-zA-Z_0-9-:]+}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get extension with given ID.")
|
||||
@ApiOperation(value = "Get add-on with given ID.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = String.class),
|
||||
@ApiResponse(code = 404, message = "Not found") })
|
||||
public Response getById(@HeaderParam("Accept-Language") @ApiParam(value = "language") @Nullable String language,
|
||||
@PathParam("extensionId") @ApiParam(value = "extension ID") String extensionId) {
|
||||
@PathParam("addonId") @ApiParam(value = "addon ID") String addonId) {
|
||||
logger.debug("Received HTTP GET request at '{}'.", uriInfo.getPath());
|
||||
Locale locale = localeService.getLocale(language);
|
||||
ExtensionService extensionService = getExtensionService(extensionId);
|
||||
Extension responseObject = extensionService.getExtension(extensionId, locale);
|
||||
AddonService addonService = getAddonService(addonId);
|
||||
Addon responseObject = addonService.getAddon(addonId, locale);
|
||||
if (responseObject != null) {
|
||||
return Response.ok(responseObject).build();
|
||||
}
|
||||
|
@ -157,18 +156,17 @@ public class ExtensionResource implements RESTResource {
|
|||
}
|
||||
|
||||
@POST
|
||||
@Path("/{extensionId: [a-zA-Z_0-9-:]+}/install")
|
||||
@ApiOperation(value = "Installs the extension with the given ID.")
|
||||
@Path("/{addonId: [a-zA-Z_0-9-:]+}/install")
|
||||
@ApiOperation(value = "Installs the add-on with the given ID.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
public Response installExtension(
|
||||
final @PathParam("extensionId") @ApiParam(value = "extension ID") String extensionId) {
|
||||
public Response installAddon(final @PathParam("addonId") @ApiParam(value = "addon ID") String addonId) {
|
||||
ThreadPoolManager.getPool(THREAD_POOL_NAME).submit(() -> {
|
||||
try {
|
||||
ExtensionService extensionService = getExtensionService(extensionId);
|
||||
extensionService.install(extensionId);
|
||||
AddonService addonService = getAddonService(addonId);
|
||||
addonService.install(addonId);
|
||||
} catch (Exception e) {
|
||||
logger.error("Exception while installing extension: {}", e.getMessage());
|
||||
postFailureEvent(extensionId, e.getMessage());
|
||||
logger.error("Exception while installing add-on: {}", e.getMessage());
|
||||
postFailureEvent(addonId, e.getMessage());
|
||||
}
|
||||
});
|
||||
return Response.ok(null, MediaType.TEXT_PLAIN).build();
|
||||
|
@ -176,17 +174,16 @@ public class ExtensionResource implements RESTResource {
|
|||
|
||||
@POST
|
||||
@Path("/url/{url}/install")
|
||||
@ApiOperation(value = "Installs the extension from the given URL.")
|
||||
@ApiOperation(value = "Installs the add-on from the given URL.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 400, message = "The given URL is malformed or not valid.") })
|
||||
public Response installExtensionByURL(
|
||||
final @PathParam("url") @ApiParam(value = "extension install URL") String url) {
|
||||
public Response installExtensionByURL(final @PathParam("url") @ApiParam(value = "addon install URL") String url) {
|
||||
try {
|
||||
URI extensionURI = new URI(url);
|
||||
String extensionId = getExtensionId(extensionURI);
|
||||
installExtension(extensionId);
|
||||
URI addonURI = new URI(url);
|
||||
String addonId = getAddonId(addonURI);
|
||||
installAddon(addonId);
|
||||
} catch (URISyntaxException | IllegalArgumentException e) {
|
||||
logger.error("Exception while parsing the extension URL '{}': {}", url, e.getMessage());
|
||||
logger.error("Exception while parsing the addon URL '{}': {}", url, e.getMessage());
|
||||
return JSONResponse.createErrorResponse(Status.BAD_REQUEST, "The given URL is malformed or not valid.");
|
||||
}
|
||||
|
||||
|
@ -194,66 +191,65 @@ public class ExtensionResource implements RESTResource {
|
|||
}
|
||||
|
||||
@POST
|
||||
@Path("/{extensionId: [a-zA-Z_0-9-:]+}/uninstall")
|
||||
@ApiOperation(value = "Uninstalls the extension with the given ID.")
|
||||
@Path("/{addonId: [a-zA-Z_0-9-:]+}/uninstall")
|
||||
@ApiOperation(value = "Uninstalls the add-on with the given ID.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
public Response uninstallExtension(
|
||||
final @PathParam("extensionId") @ApiParam(value = "extension ID") String extensionId) {
|
||||
public Response uninstallExtension(final @PathParam("addonId") @ApiParam(value = "addon ID") String addonId) {
|
||||
ThreadPoolManager.getPool(THREAD_POOL_NAME).submit(() -> {
|
||||
try {
|
||||
ExtensionService extensionService = getExtensionService(extensionId);
|
||||
extensionService.uninstall(extensionId);
|
||||
AddonService addonService = getAddonService(addonId);
|
||||
addonService.uninstall(addonId);
|
||||
} catch (Exception e) {
|
||||
logger.error("Exception while uninstalling extension: {}", e.getMessage());
|
||||
postFailureEvent(extensionId, e.getMessage());
|
||||
logger.error("Exception while uninstalling add-on: {}", e.getMessage());
|
||||
postFailureEvent(addonId, e.getMessage());
|
||||
}
|
||||
});
|
||||
return Response.ok(null, MediaType.TEXT_PLAIN).build();
|
||||
}
|
||||
|
||||
private void postFailureEvent(String extensionId, String msg) {
|
||||
Event event = ExtensionEventFactory.createExtensionFailureEvent(extensionId, msg);
|
||||
private void postFailureEvent(String addonId, String msg) {
|
||||
Event event = AddonEventFactory.createAddonFailureEvent(addonId, msg);
|
||||
eventPublisher.post(event);
|
||||
}
|
||||
|
||||
private Stream<Extension> getAllExtensions(Locale locale) {
|
||||
return extensionServices.stream().map(s -> s.getExtensions(locale)).flatMap(l -> l.stream());
|
||||
private Stream<Addon> getAllExtensions(Locale locale) {
|
||||
return addonServices.stream().map(s -> s.getAddons(locale)).flatMap(l -> l.stream());
|
||||
}
|
||||
|
||||
private Set<ExtensionType> getAllExtensionTypes(Locale locale) {
|
||||
private Set<AddonType> getAllExtensionTypes(Locale locale) {
|
||||
final Collator coll = Collator.getInstance(locale);
|
||||
coll.setStrength(Collator.PRIMARY);
|
||||
Set<ExtensionType> ret = new TreeSet<>(new Comparator<ExtensionType>() {
|
||||
Set<AddonType> ret = new TreeSet<>(new Comparator<AddonType>() {
|
||||
@Override
|
||||
public int compare(ExtensionType o1, ExtensionType o2) {
|
||||
public int compare(AddonType o1, AddonType o2) {
|
||||
return coll.compare(o1.getLabel(), o2.getLabel());
|
||||
}
|
||||
});
|
||||
for (ExtensionService extensionService : extensionServices) {
|
||||
ret.addAll(extensionService.getTypes(locale));
|
||||
for (AddonService addonService : addonServices) {
|
||||
ret.addAll(addonService.getTypes(locale));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private ExtensionService getExtensionService(final String extensionId) {
|
||||
for (ExtensionService extensionService : extensionServices) {
|
||||
for (Extension extension : extensionService.getExtensions(Locale.getDefault())) {
|
||||
if (extensionId.equals(extension.getId())) {
|
||||
return extensionService;
|
||||
private AddonService getAddonService(final String addonId) {
|
||||
for (AddonService addonService : addonServices) {
|
||||
for (Addon addon : addonService.getAddons(Locale.getDefault())) {
|
||||
if (addonId.equals(addon.getId())) {
|
||||
return addonService;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No extension service registered for " + extensionId);
|
||||
throw new IllegalArgumentException("No add-on service registered for " + addonId);
|
||||
}
|
||||
|
||||
private String getExtensionId(URI extensionURI) {
|
||||
for (ExtensionService extensionService : extensionServices) {
|
||||
String extensionId = extensionService.getExtensionId(extensionURI);
|
||||
if (extensionId != null && !extensionId.isBlank()) {
|
||||
return extensionId;
|
||||
private String getAddonId(URI addonURI) {
|
||||
for (AddonService addonService : addonServices) {
|
||||
String addonId = addonService.getAddonId(addonURI);
|
||||
if (addonId != null && !addonId.isBlank()) {
|
||||
return addonId;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("No extension service registered for URI " + extensionURI);
|
||||
throw new IllegalArgumentException("No add-on service registered for URI " + addonURI);
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ import java.util.List;
|
|||
*/
|
||||
public class RootBean {
|
||||
|
||||
public final String version = "3";
|
||||
public final String version = "4";
|
||||
|
||||
public final List<Links> links = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Extension of the default OSGi bundle activator
|
||||
* Addon of the default OSGi bundle activator
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
|
|
|
@ -37,11 +37,11 @@ import java.util.stream.Collectors;
|
|||
import org.apache.karaf.features.Feature;
|
||||
import org.apache.karaf.features.FeaturesService;
|
||||
import org.openhab.core.OpenHAB;
|
||||
import org.openhab.core.addon.AddonEventFactory;
|
||||
import org.openhab.core.config.core.ConfigConstants;
|
||||
import org.openhab.core.config.core.ConfigurableService;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.extension.ExtensionEventFactory;
|
||||
import org.osgi.service.cm.Configuration;
|
||||
import org.osgi.service.cm.ConfigurationAdmin;
|
||||
import org.osgi.service.cm.ConfigurationEvent;
|
||||
|
@ -520,7 +520,7 @@ public class FeatureInstaller implements ConfigurationListener {
|
|||
private static void postInstalledEvent(String featureName) {
|
||||
String extensionId = featureName.substring(PREFIX.length());
|
||||
if (eventPublisher != null) {
|
||||
Event event = ExtensionEventFactory.createExtensionInstalledEvent(extensionId);
|
||||
Event event = AddonEventFactory.createAddonInstalledEvent(extensionId);
|
||||
eventPublisher.post(event);
|
||||
}
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ public class FeatureInstaller implements ConfigurationListener {
|
|||
private static void postUninstalledEvent(String featureName) {
|
||||
String extensionId = featureName.substring(PREFIX.length());
|
||||
if (eventPublisher != null) {
|
||||
Event event = ExtensionEventFactory.createExtensionUninstalledEvent(extensionId);
|
||||
Event event = AddonEventFactory.createAddonUninstalledEvent(extensionId);
|
||||
eventPublisher.post(event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.util.Locale;
|
|||
|
||||
import org.apache.karaf.features.Feature;
|
||||
import org.apache.karaf.features.FeaturesService;
|
||||
import org.openhab.core.extension.Extension;
|
||||
import org.openhab.core.extension.ExtensionService;
|
||||
import org.openhab.core.extension.ExtensionType;
|
||||
import org.openhab.core.addon.Addon;
|
||||
import org.openhab.core.addon.AddonService;
|
||||
import org.openhab.core.addon.AddonType;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
@ -33,49 +33,49 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This service is an implementation of an openHAB {@link ExtensionService} using the Karaf features service. This
|
||||
* This service is an implementation of an openHAB {@link AddonService} using the Karaf features service. This
|
||||
* exposes all openHAB add-ons through the REST API and allows UIs to dynamically install and uninstall them.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@Component(name = "org.openhab.core.karafextension")
|
||||
public class KarafExtensionService implements ExtensionService {
|
||||
@Component(name = "org.openhab.core.karafaddons")
|
||||
public class KarafAddonService implements AddonService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(KarafExtensionService.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(KarafAddonService.class);
|
||||
|
||||
private final List<ExtensionType> typeList = new ArrayList<>(FeatureInstaller.EXTENSION_TYPES.length);
|
||||
private final List<AddonType> typeList = new ArrayList<>(FeatureInstaller.EXTENSION_TYPES.length);
|
||||
|
||||
private final FeaturesService featuresService;
|
||||
private final FeatureInstaller featureInstaller;
|
||||
|
||||
@Activate
|
||||
public KarafExtensionService(final @Reference FeatureInstaller featureInstaller,
|
||||
public KarafAddonService(final @Reference FeatureInstaller featureInstaller,
|
||||
final @Reference FeaturesService featuresService) {
|
||||
this.featureInstaller = featureInstaller;
|
||||
this.featuresService = featuresService;
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_BINDING, "Bindings"));
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_MISC, "Misc"));
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_VOICE, "Voice"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_BINDING, "Bindings"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_MISC, "Misc"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_VOICE, "Voice"));
|
||||
if (!FeatureInstaller.SIMPLE_PACKAGE.equals(featureInstaller.getCurrentPackage())) {
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_ACTION, "Actions"));
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_PERSISTENCE, "Persistence"));
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_TRANSFORMATION, "Transformations"));
|
||||
typeList.add(new ExtensionType(FeatureInstaller.EXTENSION_TYPE_UI, "User Interfaces"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_ACTION, "Actions"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_PERSISTENCE, "Persistence"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_TRANSFORMATION, "Transformations"));
|
||||
typeList.add(new AddonType(FeatureInstaller.EXTENSION_TYPE_UI, "User Interfaces"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Extension> getExtensions(Locale locale) {
|
||||
List<Extension> extensions = new LinkedList<>();
|
||||
public List<Addon> getAddons(Locale locale) {
|
||||
List<Addon> addons = new LinkedList<>();
|
||||
try {
|
||||
for (Feature feature : featuresService.listFeatures()) {
|
||||
if (feature.getName().startsWith(FeatureInstaller.PREFIX)
|
||||
&& Arrays.asList(FeatureInstaller.EXTENSION_TYPES).contains(getType(feature.getName()))) {
|
||||
Extension extension = getExtension(feature);
|
||||
Addon addon = getAddon(feature);
|
||||
// for simple packaging, we filter out all openHAB 1 add-ons as they cannot be used through the UI
|
||||
if (!FeatureInstaller.SIMPLE_PACKAGE.equals(featureInstaller.getCurrentPackage())
|
||||
|| !extension.getVersion().startsWith("1.")) {
|
||||
extensions.add(extension);
|
||||
|| !addon.getVersion().startsWith("1.")) {
|
||||
addons.add(addon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,23 +85,23 @@ public class KarafExtensionService implements ExtensionService {
|
|||
}
|
||||
|
||||
// let's sort the result alphabetically
|
||||
extensions.sort(Comparator.comparing(Extension::getLabel));
|
||||
return extensions;
|
||||
addons.sort(Comparator.comparing(Addon::getLabel));
|
||||
return addons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extension getExtension(String id, Locale locale) {
|
||||
public Addon getAddon(String id, Locale locale) {
|
||||
Feature feature;
|
||||
try {
|
||||
feature = featuresService.getFeature(FeatureInstaller.PREFIX + id);
|
||||
return getExtension(feature);
|
||||
return getAddon(feature);
|
||||
} catch (Exception e) {
|
||||
logger.error("Exception while querying feature '{}'", id);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Extension getExtension(Feature feature) {
|
||||
private Addon getAddon(Feature feature) {
|
||||
String name = getName(feature.getName());
|
||||
String type = getType(feature.getName());
|
||||
String extId = type + "-" + name;
|
||||
|
@ -134,11 +134,11 @@ public class KarafExtensionService implements ExtensionService {
|
|||
break;
|
||||
}
|
||||
boolean installed = featuresService.isInstalled(feature);
|
||||
return new Extension(extId, type, label, version, link, installed);
|
||||
return new Addon(extId, type, label, version, link, installed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionType> getTypes(Locale locale) {
|
||||
public List<AddonType> getTypes(Locale locale) {
|
||||
return typeList;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ public class KarafExtensionService implements ExtensionService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getExtensionId(URI extensionURI) {
|
||||
public String getAddonId(URI addonURI) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Extension of the default OSGi bundle activator
|
||||
* Addon of the default OSGi bundle activator
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.extension;
|
||||
package org.openhab.core.addon;
|
||||
|
||||
/**
|
||||
* This class defines an extension.
|
||||
* This class defines an add-on.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
public class Extension {
|
||||
public class Addon {
|
||||
|
||||
private final String id;
|
||||
private final String label;
|
||||
|
@ -30,33 +30,33 @@ public class Extension {
|
|||
private final String imageLink;
|
||||
|
||||
/**
|
||||
* Creates a new Extension instance
|
||||
* Creates a new Addon instance
|
||||
*
|
||||
* @param id the id of the extension
|
||||
* @param type the type id of the extension
|
||||
* @param label the label of the extension
|
||||
* @param version the version of the extension
|
||||
* @param link the link to find more information about the extension (can be null)
|
||||
* @param installed true, if the extension is installed, false otherwise
|
||||
* @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 link the link to find more information about the add-on (can be null)
|
||||
* @param installed true, if the add-on is installed, false otherwise
|
||||
*/
|
||||
public Extension(String id, String type, String label, String version, String link, boolean installed) {
|
||||
public Addon(String id, String type, String label, String version, String link, boolean installed) {
|
||||
this(id, type, label, version, link, installed, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Extension instance
|
||||
* Creates a new Addon instance
|
||||
*
|
||||
* @param id the id of the extension
|
||||
* @param type the type id of the extension
|
||||
* @param label the label of the extension
|
||||
* @param version the version of the extension
|
||||
* @param description the detailed description of the extension (may be null)
|
||||
* @param backgroundColor for displaying the extension (may be null)
|
||||
* @param link the link to find more information about the extension (may be null)
|
||||
* @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 description the detailed description of the add-on (may be null)
|
||||
* @param backgroundColor for displaying the add-on (may be null)
|
||||
* @param link the link to find more information about the add-on (may be null)
|
||||
* @param imageLink the link to an image (png/svg) (may be null)
|
||||
* @param installed true, if the extension is installed, false otherwise
|
||||
* @param installed true, if the add-on is installed, false otherwise
|
||||
*/
|
||||
public Extension(String id, String type, String label, String version, String link, boolean installed,
|
||||
public Addon(String id, String type, String label, String version, String link, boolean installed,
|
||||
String description, String backgroundColor, String imageLink) {
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
|
@ -70,42 +70,42 @@ public class Extension {
|
|||
}
|
||||
|
||||
/**
|
||||
* The id of the {@ExtensionType} of the extension
|
||||
* The id of the {@AddonType} of the add-on
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the extension
|
||||
* The id of the add-on
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The label of the extension
|
||||
* The label of the add-on
|
||||
*/
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* The (optional) link to find more information about the extension
|
||||
* The (optional) link to find more information about the add-on
|
||||
*/
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of the extension
|
||||
* The version of the add-on
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* true, if the extension is installed, false otherwise
|
||||
* true, if the add-on is installed, false otherwise
|
||||
*/
|
||||
public boolean isInstalled() {
|
||||
return installed;
|
||||
|
@ -119,21 +119,21 @@ public class Extension {
|
|||
}
|
||||
|
||||
/**
|
||||
* The description of the extension
|
||||
* The description of the add-on
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The background color for rendering the extension
|
||||
* The background color for rendering the add-on
|
||||
*/
|
||||
public String getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* A link to an image (png/svg) for the extension
|
||||
* A link to an image (png/svg) for the add-on
|
||||
*/
|
||||
public String getImageLink() {
|
||||
return imageLink;
|
|
@ -10,47 +10,47 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.extension;
|
||||
package org.openhab.core.addon;
|
||||
|
||||
import org.openhab.core.events.AbstractEvent;
|
||||
|
||||
/**
|
||||
* This is an {@link Event} that is sent on extension operations, such as installing and uninstalling.
|
||||
* This is an {@link Event} that is sent on add-on operations, such as installing and uninstalling.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
public class ExtensionEvent extends AbstractEvent {
|
||||
public class AddonEvent extends AbstractEvent {
|
||||
|
||||
/**
|
||||
* The extension event type.
|
||||
* The add-on event type.
|
||||
*/
|
||||
public static final String TYPE = ExtensionEvent.class.getSimpleName();
|
||||
public static final String TYPE = AddonEvent.class.getSimpleName();
|
||||
|
||||
private String msg;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Constructs a new extension event object.
|
||||
* Constructs a new add-on event object.
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param payload the payload
|
||||
* @param id the id of the extension
|
||||
* @param id the id of the add-on
|
||||
* @param msg the message text
|
||||
*/
|
||||
public ExtensionEvent(String topic, String payload, String id, String msg) {
|
||||
public AddonEvent(String topic, String payload, String id, String msg) {
|
||||
super(topic, payload, null);
|
||||
this.id = id;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new extension event object.
|
||||
* Constructs a new add-on event object.
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param payload the payload
|
||||
* @param id the id of the extension
|
||||
* @param id the id of the add-on
|
||||
*/
|
||||
public ExtensionEvent(String topic, String payload, String id) {
|
||||
public AddonEvent(String topic, String payload, String id) {
|
||||
this(topic, payload, id, null);
|
||||
}
|
||||
|
||||
|
@ -61,12 +61,11 @@ public class ExtensionEvent extends AbstractEvent {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (getTopic()
|
||||
.equals(ExtensionEventFactory.buildTopic(ExtensionEventFactory.EXTENSION_INSTALLED_EVENT_TOPIC, id))) {
|
||||
return "Extension '" + id + "' has been installed.";
|
||||
} else if (getTopic().equals(
|
||||
ExtensionEventFactory.buildTopic(ExtensionEventFactory.EXTENSION_UNINSTALLED_EVENT_TOPIC, id))) {
|
||||
return "Extension '" + id + "' has been uninstalled.";
|
||||
if (getTopic().equals(AddonEventFactory.buildTopic(AddonEventFactory.ADDON_INSTALLED_EVENT_TOPIC, id))) {
|
||||
return "Addon '" + id + "' has been installed.";
|
||||
} else if (getTopic()
|
||||
.equals(AddonEventFactory.buildTopic(AddonEventFactory.ADDON_UNINSTALLED_EVENT_TOPIC, id))) {
|
||||
return "Addon '" + id + "' has been uninstalled.";
|
||||
} else {
|
||||
return id + ": " + (msg != null ? msg : "Operation failed.");
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.addon;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.openhab.core.events.AbstractEventFactory;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* This is an {@link EventFactory} for creating add-on events. The following event types are supported by this
|
||||
* factory:
|
||||
*
|
||||
* {@link AddonEventFactory#TYPE}
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@Component(service = EventFactory.class, immediate = true)
|
||||
public class AddonEventFactory extends AbstractEventFactory {
|
||||
|
||||
static final String TOPIC_PREFIX = "smarthome/addons/{id}";
|
||||
|
||||
static final String ADDON_INSTALLED_EVENT_TOPIC_POSTFIX = "/installed";
|
||||
static final String ADDON_UNINSTALLED_EVENT_TOPIC_POSTFIX = "/uninstalled";
|
||||
static final String ADDON_FAILURE_EVENT_TOPIC_POSTFIX = "/failed";
|
||||
|
||||
static final String ADDON_INSTALLED_EVENT_TOPIC = TOPIC_PREFIX + ADDON_INSTALLED_EVENT_TOPIC_POSTFIX;
|
||||
static final String ADDON_UNINSTALLED_EVENT_TOPIC = TOPIC_PREFIX + ADDON_UNINSTALLED_EVENT_TOPIC_POSTFIX;
|
||||
static final String ADDON_FAILURE_EVENT_TOPIC = TOPIC_PREFIX + ADDON_FAILURE_EVENT_TOPIC_POSTFIX;
|
||||
|
||||
/**
|
||||
* Constructs a new AddonEventFactory.
|
||||
*/
|
||||
public AddonEventFactory() {
|
||||
super(Collections.singleton(AddonEvent.TYPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Event createEventByType(String eventType, String topic, String payload, String source) throws Exception {
|
||||
if (topic.endsWith(ADDON_FAILURE_EVENT_TOPIC_POSTFIX)) {
|
||||
String[] properties = deserializePayload(payload, String[].class);
|
||||
Event event = new AddonEvent(topic, payload, properties[0], properties[1]);
|
||||
return event;
|
||||
} else {
|
||||
String id = deserializePayload(payload, String.class);
|
||||
Event event = new AddonEvent(topic, payload, id);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "add-on installed" event.
|
||||
*
|
||||
* @param id the id of the installed add-on
|
||||
* @return the according event
|
||||
*/
|
||||
public static AddonEvent createAddonInstalledEvent(String id) {
|
||||
String topic = buildTopic(ADDON_INSTALLED_EVENT_TOPIC, id);
|
||||
String payload = serializePayload(id);
|
||||
return new AddonEvent(topic, payload, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "add-on uninstalled" event.
|
||||
*
|
||||
* @param id the id of the uninstalled add-on
|
||||
* @return the according event
|
||||
*/
|
||||
public static AddonEvent createAddonUninstalledEvent(String id) {
|
||||
String topic = buildTopic(ADDON_UNINSTALLED_EVENT_TOPIC, id);
|
||||
String payload = serializePayload(id);
|
||||
return new AddonEvent(topic, payload, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "add-on failure" event.
|
||||
*
|
||||
* @param id the id of the add-on that caused a failure
|
||||
* @param msg the message text of the failure
|
||||
* @return the according event
|
||||
*/
|
||||
public static AddonEvent createAddonFailureEvent(String id, String msg) {
|
||||
String topic = buildTopic(ADDON_FAILURE_EVENT_TOPIC, id);
|
||||
String[] properties = new String[] { id, msg };
|
||||
String payload = serializePayload(properties);
|
||||
return new AddonEvent(topic, payload, id, msg);
|
||||
}
|
||||
|
||||
static String buildTopic(String topic, String id) {
|
||||
return topic.replace("{id}", id);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.extension;
|
||||
package org.openhab.core.addon;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
@ -18,68 +18,68 @@ import java.util.Locale;
|
|||
|
||||
/**
|
||||
* Classes implementing this interface can be registered as an OSGi service in order to provide functionality for
|
||||
* managing extensions, such as listing, installing and uninstalling them.
|
||||
* managing add-ons, such as listing, installing and uninstalling them.
|
||||
* The REST API offers an uri that exposes this functionality.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
public interface ExtensionService {
|
||||
public interface AddonService {
|
||||
|
||||
/**
|
||||
* Retrieves all extensions
|
||||
* Retrieves all add-ons
|
||||
*
|
||||
* It is expected that this method is rather cheap to call and will return quickly, i.e. some caching should be
|
||||
* implemented if required.
|
||||
*
|
||||
* @param locale the locale to use for the result
|
||||
* @return the localized extensions
|
||||
* @return the localized add-ons
|
||||
*/
|
||||
List<Extension> getExtensions(Locale locale);
|
||||
List<Addon> getAddons(Locale locale);
|
||||
|
||||
/**
|
||||
* Retrieves the extension for the given id.
|
||||
* Retrieves the add-on for the given id.
|
||||
*
|
||||
* @param id the id of the extension
|
||||
* @param id the id of the add-on
|
||||
* @param locale the locale to use for the result
|
||||
* @return the localized extension or null, if no extension exists with this id
|
||||
* @return the localized add-on or null, if no add-on exists with this id
|
||||
*/
|
||||
Extension getExtension(String id, Locale locale);
|
||||
Addon getAddon(String id, Locale locale);
|
||||
|
||||
/**
|
||||
* Retrieves all possible types of extensions.
|
||||
* Retrieves all possible types of add-ons.
|
||||
*
|
||||
* @param locale the locale to use for the result
|
||||
* @return the localized types
|
||||
*/
|
||||
List<ExtensionType> getTypes(Locale locale);
|
||||
List<AddonType> getTypes(Locale locale);
|
||||
|
||||
/**
|
||||
* Installs the given extension.
|
||||
* Installs the given add-on.
|
||||
*
|
||||
* This can be a long running process. The framework makes sure that this is called within a separate thread and
|
||||
* ExtensionEvents will be sent upon its completion.
|
||||
* add-on events will be sent upon its completion.
|
||||
*
|
||||
* @param id the id of the extension to install
|
||||
* @param id the id of the add-on to install
|
||||
*/
|
||||
void install(String id);
|
||||
|
||||
/**
|
||||
* Uninstalls the given extension.
|
||||
* Uninstalls the given add-on.
|
||||
*
|
||||
* This can be a long running process. The framework makes sure that this is called within a separate thread and
|
||||
* ExtensionEvents will be sent upon its completion.
|
||||
* add-on events will be sent upon its completion.
|
||||
*
|
||||
* @param id the id of the extension to uninstall
|
||||
* @param id the id of the add-on to uninstall
|
||||
*/
|
||||
void uninstall(String id);
|
||||
|
||||
/**
|
||||
* Parses the given URI and extracts an extension Id.
|
||||
* Parses the given URI and extracts an add-on Id.
|
||||
*
|
||||
* This must not be a long running process but return immediately.
|
||||
*
|
||||
* @param extensionURI the URI from which to parse the extension Id.
|
||||
* @return the extension Id if the URI can be parsed, otherwise <code>null</code>.
|
||||
* @param addonURI the URI from which to parse the add-on Id.
|
||||
* @return the add-on Id if the URI can be parsed, otherwise <code>null</code>.
|
||||
*/
|
||||
String getExtensionId(URI extensionURI);
|
||||
String getAddonId(URI addonURI);
|
||||
}
|
|
@ -10,14 +10,14 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.extension;
|
||||
package org.openhab.core.addon;
|
||||
|
||||
/**
|
||||
* This class defines an extension type.
|
||||
* This class defines an add-on type.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
public class ExtensionType {
|
||||
public class AddonType {
|
||||
|
||||
private final String id;
|
||||
private final String label;
|
||||
|
@ -28,7 +28,7 @@ public class ExtensionType {
|
|||
* @param id
|
||||
* @param label
|
||||
*/
|
||||
public ExtensionType(String id, String label) {
|
||||
public AddonType(String id, String label) {
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class ExtensionType {
|
|||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ExtensionType other = (ExtensionType) obj;
|
||||
AddonType other = (AddonType) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null) {
|
||||
return false;
|
|
@ -1,104 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.extension;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.openhab.core.events.AbstractEventFactory;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* This is an {@link EventFactory} for creating extension events. The following event types are supported by this
|
||||
* factory:
|
||||
*
|
||||
* {@link ExtensionEventFactory#TYPE}
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
@Component(service = EventFactory.class, immediate = true)
|
||||
public class ExtensionEventFactory extends AbstractEventFactory {
|
||||
|
||||
static final String TOPIC_PREFIX = "smarthome/extensions/{id}";
|
||||
|
||||
static final String EXTENSION_INSTALLED_EVENT_TOPIC_POSTFIX = "/installed";
|
||||
static final String EXTENSION_UNINSTALLED_EVENT_TOPIC_POSTFIX = "/uninstalled";
|
||||
static final String EXTENSION_FAILURE_EVENT_TOPIC_POSTFIX = "/failed";
|
||||
|
||||
static final String EXTENSION_INSTALLED_EVENT_TOPIC = TOPIC_PREFIX + EXTENSION_INSTALLED_EVENT_TOPIC_POSTFIX;
|
||||
static final String EXTENSION_UNINSTALLED_EVENT_TOPIC = TOPIC_PREFIX + EXTENSION_UNINSTALLED_EVENT_TOPIC_POSTFIX;
|
||||
static final String EXTENSION_FAILURE_EVENT_TOPIC = TOPIC_PREFIX + EXTENSION_FAILURE_EVENT_TOPIC_POSTFIX;
|
||||
|
||||
/**
|
||||
* Constructs a new ExtensionEventFactory.
|
||||
*/
|
||||
public ExtensionEventFactory() {
|
||||
super(Collections.singleton(ExtensionEvent.TYPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Event createEventByType(String eventType, String topic, String payload, String source) throws Exception {
|
||||
if (topic.endsWith(EXTENSION_FAILURE_EVENT_TOPIC_POSTFIX)) {
|
||||
String[] properties = deserializePayload(payload, String[].class);
|
||||
Event event = new ExtensionEvent(topic, payload, properties[0], properties[1]);
|
||||
return event;
|
||||
} else {
|
||||
String id = deserializePayload(payload, String.class);
|
||||
Event event = new ExtensionEvent(topic, payload, id);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "extension installed" event.
|
||||
*
|
||||
* @param id the id of the installed extension
|
||||
* @return the according event
|
||||
*/
|
||||
public static ExtensionEvent createExtensionInstalledEvent(String id) {
|
||||
String topic = buildTopic(EXTENSION_INSTALLED_EVENT_TOPIC, id);
|
||||
String payload = serializePayload(id);
|
||||
return new ExtensionEvent(topic, payload, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "extension uninstalled" event.
|
||||
*
|
||||
* @param id the id of the uninstalled extension
|
||||
* @return the according event
|
||||
*/
|
||||
public static ExtensionEvent createExtensionUninstalledEvent(String id) {
|
||||
String topic = buildTopic(EXTENSION_UNINSTALLED_EVENT_TOPIC, id);
|
||||
String payload = serializePayload(id);
|
||||
return new ExtensionEvent(topic, payload, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "extension failure" event.
|
||||
*
|
||||
* @param id the id of the extension that caused a failure
|
||||
* @param msg the message text of the failure
|
||||
* @return the according event
|
||||
*/
|
||||
public static ExtensionEvent createExtensionFailureEvent(String id, String msg) {
|
||||
String topic = buildTopic(EXTENSION_FAILURE_EVENT_TOPIC, id);
|
||||
String[] properties = new String[] { id, msg };
|
||||
String payload = serializePayload(properties);
|
||||
return new ExtensionEvent(topic, payload, id, msg);
|
||||
}
|
||||
|
||||
static String buildTopic(String topic, String id) {
|
||||
return topic.replace("{id}", id);
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@
|
|||
<module>org.openhab.core.audio</module>
|
||||
<module>org.openhab.core.binding.xml</module>
|
||||
<module>org.openhab.core.ephemeris</module>
|
||||
<module>org.openhab.core.extension.sample</module>
|
||||
<module>org.openhab.core.addon.sample</module>
|
||||
<module>org.openhab.core.id</module>
|
||||
<module>org.openhab.core.persistence</module>
|
||||
<module>org.openhab.core.semantics</module>
|
||||
|
|
Loading…
Reference in New Issue