/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.caldav_personal.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.math.NumberUtils;
import org.openhab.binding.caldav_personal.CalDavBindingProvider;
import org.openhab.binding.caldav_personal.internal.CalDavConfig.Type;
import org.openhab.binding.caldav_personal.internal.CalDavConfig.Value;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.DateTimeItem;
import org.openhab.core.library.items.StringItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.model.item.binding.AbstractGenericBindingProvider;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is responsible for parsing the binding configuration.
*
* caldavPresence="calendar:my type:presence"
* caldavPresence="calendar:my type:event eventNr:0 value:name"
* caldavPresence="calendar:my type:active eventNr:0 value:name filter-name:'.*Biotonne.*'"
* caldavPresence="calendar:my type:active eventNr:0 value:name filter-category:'Arbeit'"
* caldavPresence="calendar:my type:upcoming eventNr:0 value:place"
*
* valid values: name, description, place, start, end
*
* @author Robert Delbrück
* @since 1.8.0
*/
public class CalDavBindingProviderImpl extends AbstractGenericBindingProvider implements CalDavBindingProvider {
private static final Logger logger = LoggerFactory.getLogger(CalDavBindingProviderImpl.class);
private static final String REGEX_CALENDAR = "calendar:'?([A-Za-z-_]+(, ?[A-Za-z-_]+)*)'?";
private static final String REGEX_TYPE = "type:'?([A-Za-z]+)'?";
private static final String REGEX_EVENT_NR = "eventNr:'?([0-9]+)'?";
private static final String REGEX_VALUE = "value:'?([A-Za-z]+)'?";
private static final String REGEX_FILTER_NAME = "filter-name:'?([A-Za-z\\.\\*\\+\\- \\|]+)'?";
private static final String REGEX_FILTER_CATEGORY = "filter-category:'?([A-Za-z-_]+(, ?[A-Za-z-_]+)*)'?";
private static final String REGEX_FILTER_CATEGORY_ANY = "filter-category-any:'?([A-Za-z-_]+(, ?[A-Za-z-_]+)*)'?";
private boolean categoriesFiltersAny = false;
/**
* {@inheritDoc}
*/
@Override
public String getBindingType() {
return "caldavPersonal";
}
/**
* @{inheritDoc}
*/
@Override
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException {
if (!(item instanceof SwitchItem || item instanceof StringItem || item instanceof DateTimeItem)) {
throw new BindingConfigParseException("item '" + item.getName() + "' is of type '"
+ item.getClass().getSimpleName()
+ "', only Switch-, String and DateTimeItem are allowed - please check your *.items configuration");
}
}
/**
* {@inheritDoc}
*/
@Override
public void processBindingConfiguration(String context, Item item, String bindingConfig)
throws BindingConfigParseException {
super.processBindingConfiguration(context, item, bindingConfig);
if (bindingConfig == null) {
logger.debug("binding-configuration is currently not set for item: " + item.getName());
return;
}
logger.trace("handling config: {}", bindingConfig);
// calendar
String calendarString = CalDavBindingProviderImpl.getConfigValue(bindingConfig, REGEX_CALENDAR);
List<String> calendar = new ArrayList<String>();
if (calendarString != null) {
for (String str : calendarString.split(",")) {
calendar.add(str.trim());
}
}
String type = CalDavBindingProviderImpl.getConfigValue(bindingConfig, REGEX_TYPE);
Type typeEnum = null;
String eventNr = CalDavBindingProviderImpl.getConfigValue(bindingConfig, REGEX_EVENT_NR);
String value = CalDavBindingProviderImpl.getConfigValue(bindingConfig, REGEX_VALUE);
Value valueEnum = null;
String filterName = CalDavBindingProviderImpl.getConfigValue(bindingConfig, REGEX_FILTER_NAME);
String filterCategoryString = CalDavBindingProviderImpl.getConfigValue(bindingConfig, REGEX_FILTER_CATEGORY);
String filterCategoryAnyString = CalDavBindingProviderImpl.getConfigValue(bindingConfig,
REGEX_FILTER_CATEGORY_ANY);
List<String> filterCategory = new ArrayList<String>();
if (filterCategoryString != null && filterCategoryAnyString != null) {
throw new BindingConfigParseException(
bindingConfig + "filter-category and filter-category-any are mutually exclusive");
}
if (filterCategoryString != null) {
for (String str : filterCategoryString.split(",")) {
filterCategory.add(str.trim());
}
}
if (filterCategoryAnyString != null) {
for (String str : filterCategoryAnyString.split(",")) {
filterCategory.add(str.trim());
categoriesFiltersAny = true;
}
}
logger.trace("found values: calendar={}, type={}, eventNr={}, value={}, filterName={}, filterCategory={}",
calendar, type, eventNr, value, filterName, filterCategory);
if (calendar == null || calendar.size() == 0) {
throw new BindingConfigParseException("missing attribute 'calendar'");
}
if (type == null) {
throw new BindingConfigParseException("missing attribute 'type'");
}
try {
typeEnum = CalDavConfig.Type.valueOf(type.toUpperCase());
} catch (IllegalArgumentException e) {
throw new BindingConfigParseException("type '" + type + "' not valid");
}
if (typeEnum != Type.PRESENCE) {
if (eventNr == null) {
throw new BindingConfigParseException("missing attribute 'eventNr'");
}
if (value == null) {
throw new BindingConfigParseException("missing attribute 'value'");
}
if (!NumberUtils.isDigits(eventNr)) {
throw new BindingConfigParseException("attribute 'eventNr' must be a valid integer");
}
try {
valueEnum = CalDavConfig.Value.valueOf(value.toUpperCase());
} catch (IllegalArgumentException e) {
throw new BindingConfigParseException("value '" + type + "' not valid");
}
} else {
if (eventNr != null) {
throw new BindingConfigParseException("not required attribute 'eventNr'");
}
if (value != null) {
throw new BindingConfigParseException("not required attribute 'value'");
}
}
logger.debug("adding item: {}", item.getName());
if (categoriesFiltersAny == false) {
this.addBindingConfig(item, new CalDavConfig(calendar, typeEnum,
NumberUtils.toInt(eventNr == null ? "0" : eventNr), valueEnum, filterName, filterCategory));
} else {
this.addBindingConfig(item,
new CalDavConfig(calendar, typeEnum, NumberUtils.toInt(eventNr == null ? "0" : eventNr), valueEnum,
filterName, filterCategory, categoriesFiltersAny));
}
}
public static String getConfigValue(String input, String regex) {
Matcher matcher = Pattern.compile(regex).matcher(input);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
@Override
public CalDavConfig getConfig(String item) {
return (CalDavConfig) this.bindingConfigs.get(item);
}
}