use of org.openhab.io.caldav.internal.EventStorage.CalendarRuntime in project openhab1-addons by openhab.
the class CalDavLoaderImpl method updated.
@Override
public void updated(Dictionary<String, ?> config) throws ConfigurationException {
if (config == null) {
log.debug("Update was called with a null configuration for CalDAV IO.");
return;
}
log.debug("Update was called for CalDAV IO.");
CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING, true);
Map<String, CalDavConfig> configMap = new HashMap<String, CalDavConfig>();
Enumeration<String> iter = config.keys();
while (iter.hasMoreElements()) {
String key = iter.nextElement();
if (key.equals("service.pid")) {
continue;
}
log.trace("processing configuration parameter: {}", key);
if (key.equals(PROP_TIMEZONE)) {
String newTimeZoneStr = Objects.toString(config.get(key), null);
if (StringUtils.isBlank(newTimeZoneStr)) {
log.info("The {} setting was configured with an empty value. Default value '{}' will be used instead.", PROP_TIMEZONE, defaultTimeZone);
continue;
}
DateTimeZone newTimeZone = DateTimeZone.forID(newTimeZoneStr);
if (newTimeZone == null) {
log.warn("Invalid timezone value: {}", newTimeZoneStr);
throw new ConfigurationException(PROP_TIMEZONE, "Invalid timezone value: " + newTimeZoneStr);
}
log.debug("Overriding default timezone {} with {}", defaultTimeZone, newTimeZone);
defaultTimeZone = newTimeZone;
continue;
}
String[] keys = key.split(":");
if (keys.length != 2) {
log.warn("Unable to parse configuration parameter: {}", key);
throw new ConfigurationException("CalDAV IO", "Unable to parse configuration parameter: " + key);
}
String id = keys[0];
String paramKey = keys[1];
CalDavConfig calDavConfig = configMap.get(id);
if (calDavConfig == null) {
calDavConfig = new CalDavConfig();
configMap.put(id, calDavConfig);
}
String value = Objects.toString(config.get(key), null);
calDavConfig.setKey(id);
if (paramKey.equals(PROP_USERNAME)) {
calDavConfig.setUsername(value);
} else if (paramKey.equals(PROP_PASSWORD)) {
calDavConfig.setPassword(value);
} else if (paramKey.equals(PROP_URL)) {
calDavConfig.setUrl(value);
} else if (paramKey.equals(PROP_RELOAD_INTERVAL)) {
calDavConfig.setReloadMinutes(Integer.parseInt(value));
} else if (paramKey.equals(PROP_PRELOAD_TIME)) {
calDavConfig.setPreloadMinutes(Integer.parseInt(value));
} else if (paramKey.equals(PROP_HISTORIC_LOAD_TIME)) {
calDavConfig.setHistoricLoadMinutes(Integer.parseInt(value));
} else if (paramKey.equals(PROP_LAST_MODIFIED_TIMESTAMP_VALID)) {
calDavConfig.setLastModifiedFileTimeStampValid(BooleanUtils.toBoolean(value));
} else if (paramKey.equals(PROP_DISABLE_CERTIFICATE_VERIFICATION)) {
calDavConfig.setDisableCertificateVerification(BooleanUtils.toBoolean(value));
} else if (paramKey.equals(PROP_CHARSET)) {
try {
Charset.forName(value);
calDavConfig.setCharset(value);
} catch (UnsupportedCharsetException e) {
log.warn("Character set not valid: {}", value);
}
}
}
// verify if all required parameters are set
for (String id : configMap.keySet()) {
if (StringUtils.isEmpty(configMap.get(id).getUrl())) {
log.warn("A URL must be configured for calendar '{}'", id);
throw new ConfigurationException("CalDAV IO", "A URL must be configured for calendar '" + id + "'");
}
log.trace("config for calendar '{}': {}", id, configMap.get(id));
}
// initialize event cache
for (CalDavConfig calDavConfig : configMap.values()) {
final CalendarRuntime eventRuntime = new CalendarRuntime();
eventRuntime.setConfig(calDavConfig);
File cachePath = Util.getCachePath(calDavConfig.getKey());
if (!cachePath.exists() && !cachePath.mkdirs()) {
log.warn("cannot create directory ({}) for calendar caching (missing rights?)", cachePath.getAbsoluteFile());
continue;
}
EventStorage.getInstance().getEventCache().put(calDavConfig.getKey(), eventRuntime);
}
log.info("CalDAV IO is properly configured.");
setProperlyConfigured(true);
}
use of org.openhab.io.caldav.internal.EventStorage.CalendarRuntime in project openhab1-addons by openhab.
the class CalDavLoaderImpl method addEvent.
@Override
public void addEvent(CalDavEvent calDavEvent) {
final CalendarRuntime calendarRuntime = EventStorage.getInstance().getEventCache().get(calDavEvent.getCalendarId());
CalDavConfig config = calendarRuntime.getConfig();
if (config == null) {
log.error("cannot find config for calendar id: {}", calDavEvent.getCalendarId());
}
Sardine sardine = Util.getConnection(config);
Calendar calendar = Util.createCalendar(calDavEvent, defaultTimeZone);
try {
final String fullIcsFile = config.getUrl() + "/" + calDavEvent.getFilename() + ".ics";
if (calendarRuntime.getEventContainerByFilename(calDavEvent.getFilename()) != null) {
log.debug("event will be updated: {}", fullIcsFile);
try {
sardine.delete(fullIcsFile);
} catch (IOException e) {
log.error("cannot remove old ics file: {}", fullIcsFile);
}
} else {
log.debug("event is new: {}", fullIcsFile);
}
sardine.put(fullIcsFile, calendar.toString().getBytes("UTF-8"));
EventContainer eventContainer = new EventContainer(calDavEvent.getCalendarId());
eventContainer.setEventId(calDavEvent.getId());
eventContainer.setFilename(Util.getFilename(calDavEvent.getFilename()));
eventContainer.getEventList().add(calDavEvent);
eventContainer.setLastChanged(calDavEvent.getLastChanged());
this.addEventToMap(eventContainer, false);
} catch (UnsupportedEncodingException e) {
log.error("cannot write event", e);
} catch (IOException e) {
log.error("cannot write event", e);
}
}
use of org.openhab.io.caldav.internal.EventStorage.CalendarRuntime in project openhab1-addons by openhab.
the class CalDavLoaderImpl method addEventToMap.
public synchronized void addEventToMap(EventContainer eventContainer, boolean createTimer) {
CalendarRuntime calendarRuntime = EventStorage.getInstance().getEventCache().get(eventContainer.getCalendarId());
ConcurrentHashMap<String, EventContainer> eventContainerMap = calendarRuntime.getEventMap();
if (eventContainerMap.containsKey(eventContainer.getEventId())) {
EventContainer eventContainerOld = eventContainerMap.get(eventContainer.getEventId());
// event is already in map
if (eventContainer.getLastChanged().isAfter(eventContainerOld.getLastChanged())) {
log.debug("event is already in event map and newer -> delete the old one, reschedule timer");
// cancel old jobs
for (String timerKey : eventContainerOld.getTimerMap()) {
try {
this.scheduler.deleteJob(JobKey.jobKey(timerKey));
} catch (SchedulerException e) {
log.error("cannot cancel event with job-id: " + timerKey, e);
}
}
eventContainerOld.getTimerMap().clear();
// override event
eventContainerMap.put(eventContainer.getEventId(), eventContainer);
for (EventNotifier notifier : eventListenerList) {
for (CalDavEvent event : eventContainerOld.getEventList()) {
log.trace("notify listener... {}", notifier);
try {
notifier.eventRemoved(event);
} catch (Exception e) {
log.error("error while invoking listener", e);
}
}
}
for (EventNotifier notifier : eventListenerList) {
for (CalDavEvent event : eventContainer.getEventList()) {
log.trace("notify listener... {}", notifier);
try {
notifier.eventLoaded(event);
} catch (Exception e) {
log.error("error while invoking listener", e);
}
}
}
if (createTimer) {
int index = 0;
for (CalDavEvent event : eventContainer.getEventList()) {
if (event.getEnd().isAfterNow()) {
try {
createJob(eventContainer, event, index);
} catch (SchedulerException e) {
log.error("cannot create jobs for event '{}': ", event.getShortName(), e.getMessage());
}
}
index++;
}
}
} else {
// event is already in map and not updated (eventContainerold and eventContainer have the same
// "lastchanged" date) : we need to reschedule possible new events from recurrent events
log.debug("event is already in map and not updated, we NEED to update eventlist and schedule new events jobs");
ArrayList<CalDavEvent> eventsToAdd = new ArrayList<>();
for (CalDavEvent event : eventContainer.getEventList()) {
boolean eventAlreadyKnown = false;
for (CalDavEvent oldevent : eventContainerOld.getEventList()) {
if (event.equals(oldevent)) {
eventAlreadyKnown = true;
log.trace("events match");
} else {
log.trace("eventsarenotequal : {} - {} - {} - {} - {}", event.getId(), event.getName(), event.getStart(), event.getEnd(), event.getLastChanged());
log.trace("eventsarenotequal : {} - {} - {} - {} - {}", oldevent.getId(), oldevent.getName(), oldevent.getStart(), oldevent.getEnd(), oldevent.getLastChanged());
}
}
if (!eventAlreadyKnown) {
eventsToAdd.add(event);
}
}
// add only new events
for (CalDavEvent event : eventsToAdd) {
if (event.getEnd().isAfterNow()) {
eventContainerOld.getEventList().add(event);
for (EventNotifier notifier : eventListenerList) {
log.trace("notify listener... {}", notifier);
try {
notifier.eventLoaded(event);
} catch (Exception e) {
log.error("error while invoking listener", e);
}
}
if (createTimer) {
try {
log.trace("creating job for event {} ", event.getShortName());
createJob(eventContainerOld, event, eventContainerOld.getEventList().size() - 1);
// -1 because we already added the event to eventContainerOld
} catch (SchedulerException e) {
log.error("cannot create jobs for event '{}': ", event.getShortName(), e.getMessage());
}
}
}
}
// update eventcontainer's calculateduntil
eventContainerOld.setCalculatedUntil(eventContainer.getCalculatedUntil());
}
} else {
// event is new
eventContainerMap.put(eventContainer.getEventId(), eventContainer);
log.trace("listeners for events: {}", eventListenerList.size());
for (EventNotifier notifier : eventListenerList) {
for (CalDavEvent event : eventContainer.getEventList()) {
log.trace("notify listener... {}", notifier);
try {
notifier.eventLoaded(event);
} catch (Exception e) {
log.error("error while invoking listener", e);
}
}
}
if (createTimer) {
int index = 0;
for (CalDavEvent event : eventContainer.getEventList()) {
if (event.getEnd().isAfterNow()) {
try {
createJob(eventContainer, event, index);
} catch (SchedulerException e) {
log.error("cannot create jobs for event: " + event.getShortName());
}
}
index++;
}
}
}
}
use of org.openhab.io.caldav.internal.EventStorage.CalendarRuntime in project openhab1-addons by openhab.
the class EventReloaderJob method removeDeletedEvents.
private synchronized void removeDeletedEvents(String calendarKey, List<String> oldMap) {
final CalendarRuntime eventRuntime = EventStorage.getInstance().getEventCache().get(calendarKey);
for (String filename : oldMap) {
EventContainer eventContainer = eventRuntime.getEventContainerByFilename(filename);
if (eventContainer == null) {
log.error("cannot find event container for filename: {}", filename);
continue;
}
// cancel old jobs
for (String jobId : eventContainer.getTimerMap()) {
try {
String group;
if (jobId.startsWith(CalDavLoaderImpl.JOB_NAME_EVENT_START)) {
group = CalDavLoaderImpl.JOB_NAME_EVENT_START;
} else if (jobId.startsWith(CalDavLoaderImpl.JOB_NAME_EVENT_END)) {
group = CalDavLoaderImpl.JOB_NAME_EVENT_END;
} else {
throw new SchedulerException("unknown job id: " + jobId);
}
boolean deleteJob = CalDavLoaderImpl.instance.getScheduler().deleteJob(JobKey.jobKey(jobId, group));
log.debug("old job ({}) deleted? {}", jobId, deleteJob);
} catch (SchedulerException e) {
log.error("cannot delete job '{}'", jobId);
}
}
eventContainer.getTimerMap().clear();
for (EventNotifier notifier : CalDavLoaderImpl.instance.getEventListenerList()) {
for (CalDavEvent event : eventContainer.getEventList()) {
try {
notifier.eventRemoved(event);
} catch (Exception e) {
log.error("error while invoking listener", e);
}
}
}
ConcurrentHashMap<String, EventContainer> eventContainerMap = eventRuntime.getEventMap();
if (eventContainer != null) {
this.removeFromDisk(eventContainer);
log.debug("remove deleted event: {}", eventContainer.getEventId());
eventContainerMap.remove(eventContainer.getEventId());
}
}
}
use of org.openhab.io.caldav.internal.EventStorage.CalendarRuntime in project openhab1-addons by openhab.
the class EventReloaderJob method execute.
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
final String config = context.getJobDetail().getJobDataMap().getString(KEY_CONFIG);
CalendarRuntime eventRuntime = EventStorage.getInstance().getEventCache().get(config);
log.debug("running EventReloaderJob for config : {}", config);
// reload cached events (if necessary)
if (!cachedEventsLoaded.containsKey(config)) {
try {
log.debug("reload cached events for config: {}", eventRuntime.getConfig().getKey());
for (File fileCalendarKeys : new File(CalDavLoaderImpl.CACHE_PATH).listFiles()) {
if (!eventRuntime.getConfig().getKey().equals(Util.getFilename(fileCalendarKeys.getName()))) {
log.trace("not our config : {}", Util.getFilename(fileCalendarKeys.getName()));
continue;
}
log.trace("found our config : {}", Util.getFilename(fileCalendarKeys.getName()));
final Collection<File> icsFiles = FileUtils.listFiles(fileCalendarKeys, new String[] { "ics" }, false);
for (File icsFile : icsFiles) {
try {
FileInputStream fis = new FileInputStream(icsFile);
log.debug("loading events from file : {}", icsFile);
loadEvents(Util.getFilename(icsFile.getAbsolutePath()), new org.joda.time.DateTime(icsFile.lastModified()), fis, eventRuntime.getConfig(), new ArrayList<String>(), true);
} catch (IOException e) {
log.error("cannot load events for file: " + icsFile, e);
} catch (ParserException e) {
log.error("cannot load events for file: " + icsFile, e);
}
}
break;
}
} catch (Throwable e) {
log.error("cannot load events", e);
} finally {
cachedEventsLoaded.put(config, true);
}
}
try {
log.debug("loading events for config: " + config);
List<String> oldEventIds = new ArrayList<String>();
for (EventContainer eventContainer : eventRuntime.getEventMap().values()) {
oldEventIds.add(eventContainer.getFilename());
log.debug("old eventcontainer -- id : {} -- filename : {} -- calcuntil : {} -- lastchanged : {} -- ishistoric : {}", eventContainer.getEventId(), eventContainer.getFilename(), eventContainer.getCalculatedUntil(), eventContainer.getLastChanged(), eventContainer.isHistoricEvent());
if (log.isDebugEnabled()) {
for (int i = 0; i < eventContainer.getEventList().size(); i++) {
CalDavEvent elem = eventContainer.getEventList().get(i);
log.debug("old eventlist contient l'evenement : {} -- deb : {} -- fin : {} -- lastchang {}", elem.getName(), elem.getStart(), elem.getEnd(), elem.getLastChanged());
}
}
}
loadEvents(eventRuntime, oldEventIds);
// stop all events in oldMap
removeDeletedEvents(config, oldEventIds);
for (EventNotifier notifier : CalDavLoaderImpl.instance.getEventListenerList()) {
try {
notifier.calendarReloaded(config);
} catch (Exception e) {
log.error("error while invoking listener", e);
}
}
// print All scheduled jobs :
if (log.isDebugEnabled()) {
log.debug("jobs scheduled : ");
Scheduler scheduler = CalDavLoaderImpl.instance.getScheduler();
for (String groupName : CalDavLoaderImpl.instance.getScheduler().getJobGroupNames()) {
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
String jobName = jobKey.getName();
String jobGroup = jobKey.getGroup();
// get job's trigger
List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
Date nextFireTime = triggers.get(0).getNextFireTime();
log.debug("[job] : {} - [groupName] : {} - {}", jobName, jobGroup, nextFireTime);
}
}
}
} catch (SardineException e) {
log.error("error while loading calendar entries: {} ({} - {} )", e.getMessage(), e.getStatusCode(), e.getResponsePhrase(), e);
throw new JobExecutionException("error while loading calendar entries", e, false);
} catch (Exception e) {
log.error("error while loading calendar entries: {}", e.getMessage(), e);
throw new JobExecutionException("error while loading calendar entries", e, false);
}
}
Aggregations