Skip to content

Commit

Permalink
Merge branch 'main' into YAMLfile_semantic_tag_provider
Browse files Browse the repository at this point in the history
  • Loading branch information
lolodomo committed Jul 9, 2023
2 parents 3d34399 + 591b16f commit e193512
Show file tree
Hide file tree
Showing 94 changed files with 3,060 additions and 390 deletions.
2 changes: 1 addition & 1 deletion bom/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@
<dependency>
<groupId>org.apache.aries.spifly</groupId>
<artifactId>org.apache.aries.spifly.dynamic.bundle</artifactId>
<version>1.3.4</version>
<version>1.3.6</version>
</dependency>

<!-- END: Slightly modified EnRoute implementation index artifacts -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -29,6 +30,8 @@
import org.openhab.core.OpenHAB;
import org.openhab.core.addon.Addon;
import org.openhab.core.addon.AddonEventFactory;
import org.openhab.core.addon.AddonInfo;
import org.openhab.core.addon.AddonInfoRegistry;
import org.openhab.core.addon.AddonService;
import org.openhab.core.addon.AddonType;
import org.openhab.core.cache.ExpiringCache;
Expand Down Expand Up @@ -66,13 +69,15 @@ public abstract class AbstractRemoteAddonService implements AddonService {
protected final ConfigurationAdmin configurationAdmin;
protected final ExpiringCache<List<Addon>> cachedRemoteAddons = new ExpiringCache<>(Duration.ofMinutes(15),
this::getRemoteAddons);
protected final AddonInfoRegistry addonInfoRegistry;
protected List<Addon> cachedAddons = List.of();
protected List<String> installedAddons = List.of();

private final Logger logger = LoggerFactory.getLogger(AbstractRemoteAddonService.class);

public AbstractRemoteAddonService(EventPublisher eventPublisher, ConfigurationAdmin configurationAdmin,
StorageService storageService, String servicePid) {
StorageService storageService, AddonInfoRegistry addonInfoRegistry, String servicePid) {
this.addonInfoRegistry = addonInfoRegistry;
this.eventPublisher = eventPublisher;
this.configurationAdmin = configurationAdmin;
this.installedAddonStorage = storageService.getStorage(servicePid);
Expand All @@ -83,6 +88,16 @@ protected BundleVersion getCoreVersion() {
return new BundleVersion(FrameworkUtil.getBundle(OpenHAB.class).getVersion().toString());
}

private Addon convertFromStorage(Map.Entry<String, @Nullable String> entry) {
Addon storedAddon = Objects.requireNonNull(gson.fromJson(entry.getValue(), Addon.class));
AddonInfo addonInfo = addonInfoRegistry.getAddonInfo(storedAddon.getType() + "-" + storedAddon.getId());
if (addonInfo != null && storedAddon.getConfigDescriptionURI().isBlank()) {
return Addon.create(storedAddon).withConfigDescriptionURI(addonInfo.getConfigDescriptionURI()).build();
} else {
return storedAddon;
}
}

@Override
public void refreshSource() {
if (!addonHandlers.stream().allMatch(MarketplaceAddonHandler::isReady)) {
Expand All @@ -92,8 +107,7 @@ public void refreshSource() {
}
List<Addon> addons = new ArrayList<>();
try {
installedAddonStorage.stream().map(e -> Objects.requireNonNull(gson.fromJson(e.getValue(), Addon.class)))
.forEach(addons::add);
installedAddonStorage.stream().map(this::convertFromStorage).forEach(addons::add);
} catch (JsonSyntaxException e) {
List.copyOf(installedAddonStorage.getKeys()).forEach(installedAddonStorage::remove);
logger.error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.addon.Addon;
import org.openhab.core.addon.AddonInfoRegistry;
import org.openhab.core.addon.AddonService;
import org.openhab.core.addon.AddonType;
import org.openhab.core.addon.marketplace.AbstractRemoteAddonService;
Expand Down Expand Up @@ -115,8 +116,8 @@ public class CommunityMarketplaceAddonService extends AbstractRemoteAddonService
@Activate
public CommunityMarketplaceAddonService(final @Reference EventPublisher eventPublisher,
@Reference ConfigurationAdmin configurationAdmin, @Reference StorageService storageService,
Map<String, Object> config) {
super(eventPublisher, configurationAdmin, storageService, SERVICE_PID);
@Reference AddonInfoRegistry addonInfoRegistry, Map<String, Object> config) {
super(eventPublisher, configurationAdmin, storageService, addonInfoRegistry, SERVICE_PID);
modified(config);
}

Expand Down Expand Up @@ -200,10 +201,13 @@ protected List<Addon> getRemoteAddons() {

@Override
public @Nullable Addon getAddon(String uid, @Nullable Locale locale) {
String queryId = uid.startsWith(ADDON_ID_PREFIX) ? uid : ADDON_ID_PREFIX + uid;

// check if it is an installed add-on (cachedAddons also contains possibly incomplete results from the remote
// side, we need to retrieve them from Discourse)
if (installedAddons.contains(uid)) {
return cachedAddons.stream().filter(e -> uid.equals(e.getUid())).findAny().orElse(null);

if (installedAddons.contains(queryId)) {
return cachedAddons.stream().filter(e -> queryId.equals(e.getUid())).findAny().orElse(null);
}

if (!remoteEnabled()) {
Expand Down Expand Up @@ -437,11 +441,13 @@ private Addon convertTopicToAddon(DiscourseTopicResponseDTO topic) {
boolean installed = addonHandlers.stream()
.anyMatch(handler -> handler.supports(type, contentType) && handler.isInstalled(uid));

return Addon.create(uid).withType(type).withId(id).withContentType(contentType).withLabel(topic.title)
.withImageLink(topic.imageUrl).withLink(COMMUNITY_TOPIC_URL + topic.id.toString())
Addon.Builder builder = Addon.create(uid).withType(type).withId(id).withContentType(contentType)
.withLabel(topic.title).withImageLink(topic.imageUrl)
.withLink(COMMUNITY_TOPIC_URL + topic.id.toString())
.withAuthor(topic.postStream.posts[0].displayUsername).withMaturity(maturity)
.withDetailedDescription(detailedDescription).withInstalled(installed).withProperties(properties)
.build();
.withDetailedDescription(detailedDescription).withInstalled(installed).withProperties(properties);

return builder.build();
}

private @Nullable String determineIdFromUrl(String url) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.addon.Addon;
import org.openhab.core.addon.AddonInfoRegistry;
import org.openhab.core.addon.AddonService;
import org.openhab.core.addon.marketplace.AbstractRemoteAddonService;
import org.openhab.core.addon.marketplace.MarketplaceAddonHandler;
Expand Down Expand Up @@ -78,8 +79,9 @@ public class JsonAddonService extends AbstractRemoteAddonService {

@Activate
public JsonAddonService(@Reference EventPublisher eventPublisher, @Reference StorageService storageService,
@Reference ConfigurationAdmin configurationAdmin, Map<String, Object> config) {
super(eventPublisher, configurationAdmin, storageService, SERVICE_PID);
@Reference ConfigurationAdmin configurationAdmin, @Reference AddonInfoRegistry addonInfoRegistry,
Map<String, Object> config) {
super(eventPublisher, configurationAdmin, storageService, addonInfoRegistry, SERVICE_PID);
modified(config);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.core.addon.Addon;
import org.openhab.core.addon.AddonInfoRegistry;
import org.openhab.core.addon.marketplace.test.TestAddonHandler;
import org.openhab.core.addon.marketplace.test.TestAddonService;
import org.openhab.core.events.Event;
Expand All @@ -64,6 +65,7 @@
@NonNullByDefault
public class AbstractRemoteAddonServiceTest {
private @Mock @NonNullByDefault({}) StorageService storageService;
private @Mock @NonNullByDefault({}) AddonInfoRegistry addonInfoRegistry;
private @Mock @NonNullByDefault({}) ConfigurationAdmin configurationAdmin;
private @Mock @NonNullByDefault({}) EventPublisher eventPublisher;
private @Mock @NonNullByDefault({}) Configuration configuration;
Expand All @@ -82,7 +84,7 @@ public void initialize() throws IOException {

addonHandler = new TestAddonHandler();

addonService = new TestAddonService(eventPublisher, configurationAdmin, storageService);
addonService = new TestAddonService(eventPublisher, configurationAdmin, storageService, addonInfoRegistry);
addonService.addAddonHandler(addonHandler);
}

Expand All @@ -93,7 +95,7 @@ public void testSourceNotRefreshedIfAddonHandlerNotReady() {
addonHandler = new TestAddonHandler();
addonHandler.setReady(false);

addonService = new TestAddonService(eventPublisher, configurationAdmin, storageService);
addonService = new TestAddonService(eventPublisher, configurationAdmin, storageService, addonInfoRegistry);
addonService.addAddonHandler(addonHandler);

List<Addon> addons = addonService.getAddons(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.addon.Addon;
import org.openhab.core.addon.AddonInfoRegistry;
import org.openhab.core.addon.marketplace.AbstractRemoteAddonService;
import org.openhab.core.addon.marketplace.BundleVersion;
import org.openhab.core.addon.marketplace.MarketplaceAddonHandler;
Expand Down Expand Up @@ -51,8 +52,8 @@ public class TestAddonService extends AbstractRemoteAddonService {
private int remoteCalls = 0;

public TestAddonService(EventPublisher eventPublisher, ConfigurationAdmin configurationAdmin,
StorageService storageService) {
super(eventPublisher, configurationAdmin, storageService, SERVICE_PID);
StorageService storageService, AddonInfoRegistry addonInfoRegistry) {
super(eventPublisher, configurationAdmin, storageService, addonInfoRegistry, SERVICE_PID);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,33 @@ public static Builder create(String uid) {
return new Builder(uid);
}

public static Builder create(Addon addon) {
Addon.Builder builder = new Builder(addon.uid);
builder.id = addon.id;
builder.label = addon.label;
builder.version = addon.version;
builder.maturity = addon.maturity;
builder.compatible = addon.compatible;
builder.contentType = addon.contentType;
builder.link = addon.link;
builder.author = addon.author;
builder.verifiedAuthor = addon.verifiedAuthor;
builder.installed = addon.installed;
builder.type = addon.type;
builder.description = addon.description;
builder.detailedDescription = addon.detailedDescription;
builder.configDescriptionURI = addon.configDescriptionURI;
builder.keywords = addon.keywords;
builder.countries = addon.countries;
builder.license = addon.license;
builder.connection = addon.connection;
builder.backgroundColor = addon.backgroundColor;
builder.imageLink = addon.imageLink;
builder.properties = addon.properties;
builder.loggerPackages = addon.loggerPackages;
return builder;
}

public static class Builder {
private final String uid;
private String id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
public class JarFileAddonService extends BundleTracker<Bundle> implements AddonService {
public static final String SERVICE_ID = "jar";
public static final String SERVICE_NAME = "JAR-File add-on service";
private static final String ADDONS_CONTENT_TYPE = "application/vnd.openhab.bundle";

private static final Map<String, AddonType> ADDON_TYPE_MAP = Map.of( //
"automation", new AddonType("automation", "Automation"), //
Expand Down Expand Up @@ -155,7 +156,7 @@ private Addon toAddon(Bundle bundle, AddonInfo addonInfo) {
.withVersion(bundle.getVersion().toString()).withLabel(addonInfo.getName())
.withConfigDescriptionURI(addonInfo.getConfigDescriptionURI())
.withDescription(Objects.requireNonNullElse(addonInfo.getDescription(), bundle.getSymbolicName()))
.build();
.withContentType(ADDONS_CONTENT_TYPE).build();
}

@Override
Expand All @@ -168,7 +169,8 @@ public List<Addon> getAddons(@Nullable Locale locale) {

@Override
public @Nullable Addon getAddon(String id, @Nullable Locale locale) {
return addons.get(id);
String queryId = id.startsWith(ADDON_ID_PREFIX) ? id : ADDON_ID_PREFIX + id;
return addons.get(queryId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ public String toString() {
+ (bigEndian != null ? "bigEndian=" + bigEndian + ", " : "")
+ (bitDepth != null ? "bitDepth=" + bitDepth + ", " : "")
+ (bitRate != null ? "bitRate=" + bitRate + ", " : "")
+ (frequency != null ? "frequency=" + frequency : "") + (channels != null ? "channels=" + channels : "")
+ "]";
+ (frequency != null ? "frequency=" + frequency + ", " : "")
+ (channels != null ? "channels=" + channels : "") + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public interface AudioHTTPServer {
/**
* Creates a relative url for a given {@link AudioStream} where it can be requested a single time.
* Note that the HTTP header only contains "Content-length", if the passed stream is an instance of
* {@link FixedLengthAudioStream}.
* {@link SizeableAudioStream}.
* If the client that requests the url expects this header field to be present, make sure to pass such an instance.
* Streams are closed after having been served.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* This is an implementation of a {@link FixedLengthAudioStream}, which is based on a simple byte array.
* This is an implementation of an {@link AudioStream} with known length and a clone method, which is based on a simple
* byte array.
*
* @author Kai Kreuzer - Initial contribution
*/
Expand Down Expand Up @@ -60,4 +61,19 @@ public long length() {
public InputStream getClonedStream() {
return new ByteArrayAudioStream(bytes, format);
}

@Override
public synchronized void mark(int readlimit) {
stream.mark(readlimit);
}

@Override
public synchronized void reset() throws IOException {
stream.reset();
}

@Override
public boolean markSupported() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* This is an {@link AudioStream}, that can be cloned
* This is for an {@link AudioStream}, that can be cloned
*
* @author Gwendal Roulleau - Initial contribution, separation from FixedLengthAudioStream
* @author Gwendal Roulleau - Initial contribution, separation from {@link FixedLengthAudioStream}
*/
@NonNullByDefault
public abstract class ClonableAudioStream extends AudioStream {
public interface ClonableAudioStream {

/**
* Returns a new, fully independent stream instance, which can be read and closed without impacting the original
Expand All @@ -31,5 +31,5 @@ public abstract class ClonableAudioStream extends AudioStream {
* @return a new input stream that can be consumed by the caller
* @throws AudioException if stream cannot be created
*/
public abstract InputStream getClonedStream() throws AudioException;
public InputStream getClonedStream() throws AudioException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ public class FileAudioStream extends FixedLengthAudioStream implements Disposabl

private final File file;
private final AudioFormat audioFormat;
private InputStream inputStream;
private FileInputStream inputStream;
private final long length;
private final boolean isTemporaryFile;
private int markedOffset = 0;
private int alreadyRead = 0;

public FileAudioStream(File file) throws AudioException {
this(file, getAudioFormat(file));
Expand Down Expand Up @@ -87,7 +89,7 @@ private static AudioFormat parseWavFormat(File file) throws AudioException {
}
}

private static InputStream getInputStream(File file) throws AudioException {
private static FileInputStream getInputStream(File file) throws AudioException {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
Expand All @@ -102,7 +104,9 @@ public AudioFormat getFormat() {

@Override
public int read() throws IOException {
return inputStream.read();
int read = inputStream.read();
alreadyRead++;
return read;
}

@Override
Expand All @@ -124,11 +128,23 @@ public synchronized void reset() throws IOException {
}
try {
inputStream = getInputStream(file);
inputStream.skipNBytes(markedOffset);
alreadyRead = markedOffset;
} catch (AudioException e) {
throw new IOException("Cannot reset file input stream: " + e.getMessage(), e);
}
}

@Override
public synchronized void mark(int readlimit) {
markedOffset = alreadyRead;
}

@Override
public boolean markSupported() {
return true;
}

@Override
public InputStream getClonedStream() throws AudioException {
return getInputStream(file);
Expand Down
Loading

0 comments on commit e193512

Please sign in to comment.