forked from openhab/openhab-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce metadata for all add-ons (openhab#3050)
* Introduce addon.xml Signed-off-by: Jan N. Klug <[email protected]>
- Loading branch information
Showing
81 changed files
with
1,251 additions
and
1,357 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...les/org.openhab.core.binding.xml/.project → bundles/org.openhab.core.addon.xml/.project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" | ||
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0" | ||
targetNamespace="https://openhab.org/schemas/addon/v1.0.0"> | ||
|
||
<xs:import namespace="https://openhab.org/schemas/config-description/v1.0.0" | ||
schemaLocation="https://openhab.org/schemas/config-description-1.0.0.xsd"/> | ||
|
||
<xs:element name="addon"> | ||
<xs:complexType> | ||
<xs:sequence> | ||
<xs:element name="type" type="addonType"/> | ||
<xs:element name="name" type="xs:string"/> | ||
<xs:element name="description" type="xs:string"/> | ||
<xs:element name="author" type="xs:string" minOccurs="0"> | ||
<xs:annotation> | ||
<xs:documentation>The organization maintaining the add-on (e.g. openHAB). Individual developer names should be avoided.</xs:documentation> | ||
</xs:annotation> | ||
</xs:element> | ||
<xs:element name="connection" type="connectionType" minOccurs="0"/> | ||
<xs:element name="countries" type="countryType" minOccurs="0"> | ||
<xs:annotation> | ||
<xs:documentation>Comma-separated list of two-letter ISO country codes.</xs:documentation> | ||
</xs:annotation> | ||
</xs:element> | ||
<xs:element name="service-id" type="xs:string" minOccurs="0"> | ||
<xs:annotation> | ||
<xs:documentation>The ID (service.pid or component.name) of the main add-on service, which can be configured through OSGi configuration admin service. Should only be used in combination with a config description definition. The default value is <type>.<name></xs:documentation> | ||
</xs:annotation> | ||
</xs:element> | ||
<xs:choice minOccurs="0"> | ||
<xs:element name="config-description" type="config-description:configDescription"/> | ||
<xs:element name="config-description-ref" type="config-description:configDescriptionRef"/> | ||
</xs:choice> | ||
</xs:sequence> | ||
<xs:attribute name="id" type="config-description:idRestrictionPattern" use="required"> | ||
<xs:annotation> | ||
<xs:documentation>The id is used to construct the UID of this add-on to <type>-<name></xs:documentation> | ||
</xs:annotation> | ||
</xs:attribute> | ||
</xs:complexType> | ||
</xs:element> | ||
|
||
<xs:simpleType name="addonType"> | ||
<xs:restriction base="xs:string"> | ||
<xs:enumeration value="automation"/> | ||
<xs:enumeration value="binding"/> | ||
<xs:enumeration value="misc"/> | ||
<xs:enumeration value="persistence"/> | ||
<xs:enumeration value="transformation"/> | ||
<xs:enumeration value="ui"/> | ||
<xs:enumeration value="voice"/> | ||
</xs:restriction> | ||
</xs:simpleType> | ||
|
||
<xs:simpleType name="connectionType"> | ||
<xs:restriction base="xs:string"> | ||
<xs:enumeration value="local"/> | ||
<xs:enumeration value="cloud"/> | ||
<xs:enumeration value="cloudDiscovery"/> | ||
</xs:restriction> | ||
</xs:simpleType> | ||
|
||
<xs:simpleType name="countryType"> | ||
<xs:restriction base="xs:string"> | ||
<xs:pattern value="[a-z]{2}(,[a-z]{2})*"/> | ||
</xs:restriction> | ||
</xs:simpleType> | ||
|
||
</xs:schema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
....core.addon.xml/src/main/java/org/openhab/core/addon/xml/internal/AddonInfoConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* Copyright (c) 2010-2023 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.xml.internal; | ||
|
||
import java.net.URI; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.openhab.core.addon.AddonInfo; | ||
import org.openhab.core.config.core.ConfigDescription; | ||
import org.openhab.core.config.core.ConfigDescriptionBuilder; | ||
import org.openhab.core.config.xml.util.ConverterAttributeMapValidator; | ||
import org.openhab.core.config.xml.util.GenericUnmarshaller; | ||
import org.openhab.core.config.xml.util.NodeIterator; | ||
|
||
import com.thoughtworks.xstream.converters.Converter; | ||
import com.thoughtworks.xstream.converters.UnmarshallingContext; | ||
import com.thoughtworks.xstream.io.HierarchicalStreamReader; | ||
|
||
/** | ||
* The {@link AddonInfoConverter} is a concrete implementation of the {@code XStream} {@link Converter} interface used | ||
* to convert add-on information within an XML document into a {@link AddonInfoXmlResult} object. | ||
* This converter converts {@code addon} XML tags. | ||
* | ||
* @author Michael Grammling - Initial contribution | ||
* @author Andre Fuechsel - Made author tag optional | ||
* @author Jan N. Klug - Refactored to cover all add-ons | ||
*/ | ||
@NonNullByDefault | ||
public class AddonInfoConverter extends GenericUnmarshaller<AddonInfoXmlResult> { | ||
private static final String CONFIG_DESCRIPTION_URI_PLACEHOLDER = "addonInfoConverter:placeHolder"; | ||
private final ConverterAttributeMapValidator attributeMapValidator; | ||
|
||
public AddonInfoConverter() { | ||
super(AddonInfoXmlResult.class); | ||
|
||
attributeMapValidator = new ConverterAttributeMapValidator(Map.of("id", true, "schemaLocation", false)); | ||
} | ||
|
||
private @Nullable ConfigDescription readConfigDescription(NodeIterator nodeIterator) { | ||
Object nextNode = nodeIterator.next(); | ||
|
||
if (nextNode != null) { | ||
if (nextNode instanceof ConfigDescription configDescription) { | ||
return configDescription; | ||
} | ||
|
||
nodeIterator.revert(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@Override | ||
public @Nullable Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { | ||
// read attributes | ||
Map<String, String> attributes = attributeMapValidator.readValidatedAttributes(reader); | ||
|
||
String id = requireNonEmpty(attributes.get("id"), "Add-on id attribute is null or empty"); | ||
|
||
// set automatically extracted URI for a possible 'config-description' section | ||
context.put("config-description.uri", CONFIG_DESCRIPTION_URI_PLACEHOLDER); | ||
|
||
// read values | ||
List<?> nodes = (List<?>) context.convertAnother(context, List.class); | ||
NodeIterator nodeIterator = new NodeIterator(nodes); | ||
|
||
String type = requireNonEmpty((String) nodeIterator.nextValue("type", true), "Add-on type is null or empty"); | ||
|
||
String name = requireNonEmpty((String) nodeIterator.nextValue("name", true), | ||
"Add-on name attribute is null or empty"); | ||
String description = requireNonEmpty((String) nodeIterator.nextValue("description", true), | ||
"Add-on description is null or empty"); | ||
|
||
AddonInfo.Builder addonInfo = AddonInfo.builder(id, type).withName(name).withDescription(description); | ||
addonInfo.withAuthor((String) nodeIterator.nextValue("author", false)); | ||
addonInfo.withConnection((String) nodeIterator.nextValue("connection", false)); | ||
|
||
addonInfo.withServiceId((String) nodeIterator.nextValue("service-id", false)); | ||
|
||
String configDescriptionURI = nodeIterator.nextAttribute("config-description-ref", "uri", false); | ||
ConfigDescription configDescription = null; | ||
if (configDescriptionURI == null) { | ||
configDescription = readConfigDescription(nodeIterator); | ||
if (configDescription != null) { | ||
configDescriptionURI = configDescription.getUID().toString(); | ||
// if config description is missing the URI, recreate it with correct URI | ||
if (CONFIG_DESCRIPTION_URI_PLACEHOLDER.equals(configDescriptionURI)) { | ||
configDescriptionURI = type + ":" + id; | ||
configDescription = ConfigDescriptionBuilder.create(URI.create(configDescriptionURI)) | ||
.withParameterGroups(configDescription.getParameterGroups()) | ||
.withParameters(configDescription.getParameters()).build(); | ||
} | ||
} | ||
} | ||
addonInfo.withConfigDescriptionURI(configDescriptionURI); | ||
|
||
nodeIterator.assertEndOfType(); | ||
|
||
// create object | ||
return new AddonInfoXmlResult(addonInfo.build(), configDescription); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.