use of io.openems.api.exception.ReflectionException in project openems by OpenEMS.
the class Config method parseJsonConfig.
public synchronized void parseJsonConfig(JsonObject jConfig) throws OpenemsException {
/*
* read Users
*/
if (jConfig.has("users")) {
JsonObject jUsers = JsonUtils.getAsJsonObject(jConfig, "users");
for (Entry<String, JsonElement> jUsersElement : jUsers.entrySet()) {
JsonObject jUser = JsonUtils.getAsJsonObject(jUsersElement.getValue());
String username = jUsersElement.getKey();
String passwordBase64 = JsonUtils.getAsString(jUser, "password");
String saltBase64 = JsonUtils.getAsString(jUser, "salt");
try {
User.getUserByName(username).initialize(passwordBase64, saltBase64);
} catch (OpenemsException e) {
log.error("Error parsing config: " + e.getMessage());
}
}
}
// important! no more setting of users allowed!
User.initializeFinished();
/*
* read each Bridge in "things" array
*/
JsonArray jThings = JsonUtils.getAsJsonArray(jConfig, "things");
for (JsonElement jBridgeElement : jThings) {
JsonObject jBridge = JsonUtils.getAsJsonObject(jBridgeElement);
String bridgeClass = JsonUtils.getAsString(jBridge, "class");
Bridge bridge = (Bridge) InjectionUtils.getThingInstance(bridgeClass);
thingRepository.addThing(bridge);
log.info("Add Bridge[" + bridge.id() + "], Implementation[" + bridge.getClass().getSimpleName() + "]");
ConfigUtils.injectConfigChannels(thingRepository.getConfigChannels(bridge), jBridge);
/*
* read each Device in "things" array
*/
List<Device> devices = new ArrayList<>();
JsonArray jDevices = JsonUtils.getAsJsonArray(jBridge, "devices");
for (JsonElement jDeviceElement : jDevices) {
JsonObject jDevice = JsonUtils.getAsJsonObject(jDeviceElement);
Device device = thingRepository.createDevice(jDevice, bridge);
devices.add(device);
bridge.addDevice(device);
}
}
/*
* Init bridge
*/
for (Bridge b : thingRepository.getBridges()) {
for (Device d : b.getDevices()) {
d.init();
}
b.init();
}
for (BridgeInitializedEventListener listener : bridgeInitEventListeners) {
listener.onBridgeInitialized();
}
/*
* read Scheduler
*/
if (jConfig.has("scheduler")) {
JsonObject jScheduler = JsonUtils.getAsJsonObject(jConfig, "scheduler");
String schedulerClass = JsonUtils.getAsString(jScheduler, "class");
Scheduler scheduler = (Scheduler) InjectionUtils.getThingInstance(schedulerClass);
thingRepository.addThing(scheduler);
log.debug("Add Scheduler[" + scheduler.id() + "], Implementation[" + scheduler.getClass().getSimpleName() + "]");
ConfigUtils.injectConfigChannels(thingRepository.getConfigChannels(scheduler), jScheduler);
/*
* read each Controller in "controllers" array
*/
JsonArray jControllers = JsonUtils.getAsJsonArray(jScheduler, "controllers");
for (JsonElement jControllerElement : jControllers) {
JsonObject jController = JsonUtils.getAsJsonObject(jControllerElement);
Controller controller = thingRepository.createController(jController);
scheduler.addController(controller);
controller.init();
}
scheduler.init();
}
for (SchedulerInitializedEventListener listener : schedulerInitEventListeners) {
listener.onSchedulerInitialized();
}
/*
* read Persistence
*/
if (jConfig.has("persistence")) {
JsonArray jPersistences = JsonUtils.getAsJsonArray(jConfig, "persistence");
for (JsonElement jPersistenceElement : jPersistences) {
JsonObject jPersistence = JsonUtils.getAsJsonObject(jPersistenceElement);
String persistenceClass = JsonUtils.getAsString(jPersistence, "class");
Persistence persistence = (Persistence) InjectionUtils.getThingInstance(persistenceClass);
thingRepository.addThing(persistence);
log.info("Add Persistence[" + persistence.id() + "], Implementation[" + persistence.getClass().getSimpleName() + "]");
ConfigUtils.injectConfigChannels(thingRepository.getConfigChannels(persistence), jPersistence);
persistence.init();
}
}
/*
* Configuration is finished -> apply again channel annotation to all of them because many channels are only
* defined during init()
*/
thingRepository.getThings().forEach(thing -> {
thingRepository.applyChannelAnnotation(thing);
});
/*
* Start all worker threads
*/
thingRepository.getThings().forEach(thing -> {
// TODO use executor
if (thing instanceof Thread) {
((Thread) thing).start();
}
});
/*
* Register myself as onChangeListener on all ConfigChannels
*/
for (ConfigChannel<?> channel : thingRepository.getConfigChannels()) {
channel.addChangeListener(this);
}
/*
* After 10 seconds: build the ClassRepository cache to speed up future calls
* (this speeds up the first opening of the UI, as the cache does not need to be built)
*/
Executors.newScheduledThreadPool(1).schedule(() -> {
try {
ClassRepository.getInstance().getAvailableThings();
} catch (ReflectionException e) {
/* ignore */
}
}, 10, TimeUnit.SECONDS);
}
use of io.openems.api.exception.ReflectionException in project openems by OpenEMS.
the class ConfigUtils method getConfigObject.
/**
* Receives a matching value for the ConfigChannel from a JsonElement
*
* @param channel
* @param j
* @return
* @throws OpenemsException
*/
public static Object getConfigObject(ConfigChannel<?> channel, JsonElement j, Object... args) throws OpenemsException {
Optional<Class<?>> typeOptional = channel.type();
if (!typeOptional.isPresent()) {
String clazz = channel.parent() != null ? " in implementation [" + channel.parent().getClass() + "]" : "";
throw new ReflectionException("Type is null for channel [" + channel.address() + "]" + clazz);
}
Class<?> type = typeOptional.get();
/*
* test for simple types
*/
try {
return JsonUtils.getAsType(type, j);
} catch (NotImplementedException e1) {
;
}
if (Thing.class.isAssignableFrom(type)) {
/*
* Asking for a Thing
*/
@SuppressWarnings("unchecked") Class<Thing> thingType = (Class<Thing>) type;
return getThingFromConfig(thingType, j, args);
} else if (ThingMap.class.isAssignableFrom(type)) {
/*
* Asking for a ThingMap
*/
return InjectionUtils.getThingMapsFromConfig(channel, j);
} else if (Inet4Address.class.isAssignableFrom(type)) {
/*
* Asking for an IPv4
*/
try {
return Inet4Address.getByName(j.getAsString());
} catch (UnknownHostException e) {
throw new ReflectionException("Unable to convert [" + j + "] to IPv4 address");
}
} else if (Long[].class.isAssignableFrom(type)) {
/*
* Asking for an Array of Long
*/
return getLongArrayFromConfig(channel, j);
}
throw new ReflectionException("Unable to match config [" + j + "] to class type [" + type + "]");
}
use of io.openems.api.exception.ReflectionException in project openems by OpenEMS.
the class InjectionUtils method getThingMapsFromConfig.
public static Object getThingMapsFromConfig(ConfigChannel<?> channel, JsonElement j) throws ReflectionException {
/*
* Get "Field" in Channels parent class
*/
Field field;
try {
field = channel.parent().getClass().getField(channel.id());
} catch (NoSuchFieldException | SecurityException e) {
throw new ReflectionException("Field for ConfigChannel [" + channel.address() + "] is not named [" + channel.id() + "] in [" + channel.getClass().getSimpleName() + "]");
}
/*
* Get expected Object Type (List, Set, simple Object)
*/
Type expectedObjectType = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
if (expectedObjectType instanceof ParameterizedType) {
expectedObjectType = ((ParameterizedType) expectedObjectType).getRawType();
}
Class<?> expectedObjectClass = (Class<?>) expectedObjectType;
/*
* Get the ThingMap class
*/
Class<?> thingMapClass = channel.type().get();
/*
* Get the referenced Thing class
*/
IsThingMap isThingMapAnnotation = thingMapClass.getAnnotation(IsThingMap.class);
Class<? extends Thing> thingClass = isThingMapAnnotation.type();
/*
* Prepare filter for matching Things
* - Empty filter: accept nothing
* - Asterisk: accept everything
* - Otherwise: accept only exact string matches on the thing id
*/
Set<String> filter = new HashSet<>();
if (j.isJsonPrimitive()) {
String id = j.getAsJsonPrimitive().getAsString();
filter.add(id);
} else if (j.isJsonArray()) {
j.getAsJsonArray().forEach(id -> filter.add(id.getAsString()));
}
/*
* Create ThingMap instance(s) for each matching Thing
*/
ThingRepository thingRepository = ThingRepository.getInstance();
Set<Thing> matchingThings = thingRepository.getThingsAssignableByClass(thingClass);
Set<ThingMap> thingMaps = new HashSet<>();
for (Thing thing : matchingThings) {
if (filter.contains(thing.id()) || filter.contains("*")) {
ThingMap thingMap = (ThingMap) InjectionUtils.getInstance(thingMapClass, thing);
thingMaps.add(thingMap);
}
}
/*
* Prepare return
*/
if (thingMaps.isEmpty() && !filter.isEmpty()) {
throw new ReflectionException("No matching ThingMap found for ConfigChannel [" + channel.address() + "]");
}
if (Collection.class.isAssignableFrom(expectedObjectClass)) {
if (Set.class.isAssignableFrom(expectedObjectClass)) {
return thingMaps;
} else if (List.class.isAssignableFrom(expectedObjectClass)) {
return new ArrayList<>(thingMaps);
} else {
throw new ReflectionException("Only List and Set ConfigChannels are currently implemented, not [" + expectedObjectClass + "]. ConfigChannel [" + channel.address() + "]");
}
} else {
// No collection
if (thingMaps.size() > 1) {
throw new ReflectionException("Field for ConfigChannel [" + channel.address() + "] is no collection, but more than one ThingMaps [" + thingMaps + "] is fitting for [" + channel.id() + "] in [" + channel.getClass().getSimpleName() + "]");
} else {
return thingMaps.iterator().next();
}
}
}
use of io.openems.api.exception.ReflectionException in project openems by OpenEMS.
the class FaultsAndWarningsTranspiler method getEnums.
@SuppressWarnings("unchecked")
private static Set<Class<ThingStateEnum>> getEnums() throws ReflectionException {
String topLevelPackage = "io.openems.impl";
Class<ThingStateEnum> searchClazz = ThingStateEnum.class;
Set<Class<ThingStateEnum>> clazzes = new HashSet<>();
try {
ClassPath classpath = ClassPath.from(ClassLoader.getSystemClassLoader());
for (ClassPath.ClassInfo classInfo : classpath.getTopLevelClassesRecursive(topLevelPackage)) {
Class<?> thisClazz = classInfo.load();
if (searchClazz.isAssignableFrom(thisClazz)) {
clazzes.add((Class<ThingStateEnum>) thisClazz);
}
}
} catch (IllegalArgumentException | IOException e) {
throw new ReflectionException(e.getMessage());
}
return clazzes;
}
Aggregations