use of org.openhab.io.caldav.internal.EventStorage.EventContainer 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.EventContainer 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.EventContainer 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.EventContainer 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);
}
}
use of org.openhab.io.caldav.internal.EventStorage.EventContainer in project openhab1-addons by openhab.
the class EventReloaderJob method loadEvents.
public void loadEvents(String filename, org.joda.time.DateTime lastResourceChangeFS, final InputStream inputStream, final CalDavConfig config, final List<String> oldEventIds, boolean readFromFile) throws IOException, ParserException {
CalendarBuilder builder = new CalendarBuilder();
InputStreamReader is = new InputStreamReader(inputStream, config.getCharset());
BufferedReader in = new BufferedReader(is, 50);
final UnfoldingReader uin = new UnfoldingReader(in, 50, true);
Calendar calendar = builder.build(uin);
uin.close();
// log.trace("calendar: {}", calendar);
EventContainer eventContainer = new EventContainer(config.getKey());
eventContainer.setFilename(filename);
eventContainer.setLastChanged(lastResourceChangeFS);
org.joda.time.DateTime loadFrom = org.joda.time.DateTime.now().minusMinutes(config.getHistoricLoadMinutes());
org.joda.time.DateTime loadTo = org.joda.time.DateTime.now().plusMinutes(config.getPreloadMinutes());
final ComponentList<CalendarComponent> vEventComponents = calendar.getComponents(Component.VEVENT);
if (vEventComponents.size() == 0) {
log.debug("could not find a VEVENT from calendar build, based on file {}", filename);
// no events inside
if (!readFromFile) {
Util.storeToDisk(config.getKey(), filename, calendar);
}
return;
}
org.joda.time.DateTime lastModifedVEventOverAll = null;
for (CalendarComponent comp : vEventComponents) {
VEvent vEvent = (VEvent) comp;
log.trace("loading event: " + vEvent.getUid().getValue() + ":" + vEvent.getSummary().getValue());
// fallback, because 'LastModified' in VEvent is optional
org.joda.time.DateTime lastModifedVEvent = lastResourceChangeFS;
if (vEvent.getLastModified() != null) {
lastModifedVEvent = new org.joda.time.DateTime(vEvent.getLastModified().getDateTime());
log.trace("overriding lastmodified from file FS ({}) with event's last-modified property ({})", lastResourceChangeFS, lastModifedVEvent);
}
if (!config.isLastModifiedFileTimeStampValid()) {
if (lastModifedVEventOverAll == null || lastModifedVEvent.isAfter(lastModifedVEventOverAll)) {
lastModifedVEventOverAll = lastModifedVEvent;
}
if (eventContainer != null && !lastModifedVEvent.isBefore(eventContainer.getLastChanged())) {
// to be created
if (eventContainer.getCalculatedUntil() != null && vEventComponents.size() == 1 && eventContainer.getCalculatedUntil().isAfter(org.joda.time.DateTime.now().plusMinutes(config.getReloadMinutes()))) {
// the event is calculated as long as the next reload
// interval can handle this
log.trace("skipping resource processing {}, not changed", filename);
continue;
}
if (eventContainer.isHistoricEvent()) {
// no more upcoming events, do nothing
log.trace("skipping resource processing {}, not changed", filename);
continue;
}
}
}
Period period = new Period(new DateTime(loadFrom.toDate()), new DateTime(loadTo.toDate()));
PeriodList periods = vEvent.calculateRecurrenceSet(period);
periods = periods.normalise();
String eventId = vEvent.getUid().getValue();
final String eventName = vEvent.getSummary().getValue();
// no more upcoming events
if (periods.size() > 0) {
if (vEvent.getConsumedTime(new net.fortuna.ical4j.model.Date(), new net.fortuna.ical4j.model.Date(org.joda.time.DateTime.now().plusYears(10).getMillis())).size() == 0) {
log.trace("event will never be occur (historic): {}", eventName);
eventContainer.setHistoricEvent(true);
}
}
// expecting this is for every vEvent inside a calendar equals
eventContainer.setEventId(eventId);
eventContainer.setCalculatedUntil(loadTo);
for (Period p : periods) {
org.joda.time.DateTime start = getDateTime("start", p.getStart(), p.getRangeStart());
org.joda.time.DateTime end = getDateTime("end", p.getEnd(), p.getRangeEnd());
CalDavEvent event = new CalDavEvent(eventName, vEvent.getUid().getValue(), config.getKey(), start, end);
event.setLastChanged(lastModifedVEvent);
if (vEvent.getLocation() != null) {
event.setLocation(vEvent.getLocation().getValue());
}
if (vEvent.getDescription() != null) {
event.setContent(vEvent.getDescription().getValue());
}
event.getCategoryList().addAll(readCategory(vEvent));
event.setFilename(filename);
log.trace("adding event: " + event.getShortName());
eventContainer.getEventList().add(event);
}
}
if (lastModifedVEventOverAll != null && !config.isLastModifiedFileTimeStampValid()) {
eventContainer.setLastChanged(lastModifedVEventOverAll);
log.debug("changing eventcontainer last modified to {}", lastModifedVEventOverAll);
}
// if (!eventContainer.getEventList().isEmpty()) {
CalDavLoaderImpl.instance.addEventToMap(eventContainer, true);
if (!readFromFile) {
Util.storeToDisk(config.getKey(), filename, calendar);
}
// }
}
Aggregations