Skip to content

Commit

Permalink
[xml] Improve ThingTypeXmlProvider exception handling (openhab#1136)
Browse files Browse the repository at this point in the history
* Improve ThingTypeXmlProvider exception handling

When a binding such as ZWave has hundereds of ThingTypes it's hard to debug thing type definition issues.
This PR adds a UID (ConfigDescription, ChannelType, ChannelGroupType and ThingType) to the logging so it will be easier to find the root cause of exceptions.
Because the exceptions are caught, an error in one ThingType definition will no longer prevent other perfectly fine ThingTypes to be registered so the impact of definition issues is reduced.

Signed-off-by: Wouter Born <github@maindrain.net>
  • Loading branch information
wborn authored and cweitkamp committed Oct 18, 2019
1 parent 11328bc commit e35a218
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
package org.eclipse.smarthome.core.thing.xml.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.smarthome.config.core.ConfigDescription;
import org.eclipse.smarthome.config.core.ConfigDescriptionProvider;
Expand Down Expand Up @@ -62,9 +60,9 @@ public class ThingTypeXmlProvider implements XmlDocumentProvider<List<?>> {
private final XmlThingTypeProvider thingTypeProvider;

// temporary cache
private final List<ThingTypeXmlResult> thingTypeRefs;
private final List<ChannelGroupTypeXmlResult> channelGroupTypeRefs;
private final List<ChannelTypeXmlResult> channelTypeRefs;
private final List<ThingTypeXmlResult> thingTypeRefs = new ArrayList<>(10);
private final List<ChannelGroupTypeXmlResult> channelGroupTypeRefs = new ArrayList<>(10);
private final List<ChannelTypeXmlResult> channelTypeRefs = new ArrayList<>(10);

private final XmlChannelTypeProvider channelTypeProvider;
private final XmlChannelGroupTypeProvider channelGroupTypeProvider;
Expand All @@ -89,10 +87,6 @@ public ThingTypeXmlProvider(Bundle bundle, AbstractXmlConfigDescriptionProvider
this.thingTypeProvider = thingTypeProvider;
this.channelTypeProvider = channelTypeProvider;
this.channelGroupTypeProvider = channelGroupTypeProvider;

this.thingTypeRefs = new ArrayList<>(10);
this.channelGroupTypeRefs = new ArrayList<>(10);
this.channelTypeRefs = new ArrayList<>(10);
}

@Override
Expand All @@ -102,13 +96,13 @@ public synchronized void addingObject(List<?> types) {
if (type instanceof ThingTypeXmlResult) {
ThingTypeXmlResult typeResult = (ThingTypeXmlResult) type;
addConfigDescription(typeResult.getConfigDescription());
this.thingTypeRefs.add(typeResult);
thingTypeRefs.add(typeResult);
} else if (type instanceof ChannelGroupTypeXmlResult) {
ChannelGroupTypeXmlResult typeResult = (ChannelGroupTypeXmlResult) type;
this.channelGroupTypeRefs.add(typeResult);
channelGroupTypeRefs.add(typeResult);
} else if (type instanceof ChannelTypeXmlResult) {
ChannelTypeXmlResult typeResult = (ChannelTypeXmlResult) type;
this.channelTypeRefs.add(typeResult);
channelTypeRefs.add(typeResult);
addConfigDescription(typeResult.getConfigDescription());
} else {
throw new ConversionException("Unknown data type for '" + type + "'!");
Expand All @@ -120,45 +114,55 @@ public synchronized void addingObject(List<?> types) {
private void addConfigDescription(ConfigDescription configDescription) {
if (configDescription != null) {
try {
this.configDescriptionProvider.add(this.bundle, configDescription);
} catch (Exception ex) {
this.logger.error("Could not register ConfigDescription!", ex);
configDescriptionProvider.add(bundle, configDescription);
} catch (RuntimeException e) {
logger.error("Could not register ConfigDescription: {}", configDescription.getUID(), e);
}
}
}

@Override
public synchronized void addingFinished() {
Map<String, ChannelType> channelTypes = new HashMap<>(10);
// create channel types
for (ChannelTypeXmlResult type : this.channelTypeRefs) {
for (ChannelTypeXmlResult type : channelTypeRefs) {
ChannelType channelType = type.toChannelType();
channelTypes.put(channelType.getUID().getAsString(), channelType);
this.channelTypeProvider.add(this.bundle, channelType);
try {
channelTypeProvider.add(bundle, channelType);
} catch (RuntimeException e) {
logger.error("Could not register ChannelType: {}", channelType.getUID(), e);
}
}

// create channel group types
for (ChannelGroupTypeXmlResult type : this.channelGroupTypeRefs) {
this.channelGroupTypeProvider.add(this.bundle, type.toChannelGroupType());
for (ChannelGroupTypeXmlResult type : channelGroupTypeRefs) {
try {
channelGroupTypeProvider.add(bundle, type.toChannelGroupType());
} catch (RuntimeException e) {
logger.error("Could not register ChannelGroupType: {}", type.getUID(), e);
}
}

// create thing and bridge types
for (ThingTypeXmlResult type : this.thingTypeRefs) {
this.thingTypeProvider.add(this.bundle, type.toThingType());
for (ThingTypeXmlResult type : thingTypeRefs) {
try {
thingTypeProvider.add(bundle, type.toThingType());
} catch (RuntimeException e) {
logger.error("Could not register ThingType: {}", type.getUID(), e);
}
}

// release temporary cache
this.thingTypeRefs.clear();
this.channelGroupTypeRefs.clear();
this.channelTypeRefs.clear();
thingTypeRefs.clear();
channelGroupTypeRefs.clear();
channelTypeRefs.clear();
}

@Override
public synchronized void release() {
this.thingTypeProvider.removeAll(bundle);
this.channelGroupTypeProvider.removeAll(bundle);
this.channelTypeProvider.removeAll(bundle);
this.configDescriptionProvider.removeAll(bundle);
thingTypeProvider.removeAll(bundle);
channelGroupTypeProvider.removeAll(bundle);
channelTypeProvider.removeAll(bundle);
configDescriptionProvider.removeAll(bundle);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ public ThingTypeXmlResult(ThingTypeUID thingTypeUID, List<String> supportedBridg
this.configDescription = (ConfigDescription) configDescriptionObjects[1];
}

public ThingTypeUID getUID() {
return thingTypeUID;
}

public ConfigDescription getConfigDescription() {
return this.configDescription;
return configDescription;
}

protected List<ChannelDefinition> toChannelDefinitions(List<ChannelXmlResult> channelTypeReferences)
Expand Down

0 comments on commit e35a218

Please sign in to comment.