From 9db1b0bc69d461d177c3af35bddafcafdafb9991 Mon Sep 17 00:00:00 2001 From: Amit Kumar Mondal Date: Tue, 27 Jun 2017 13:03:07 +0200 Subject: [PATCH] Added composite job for range events if scheduled at same time instant Also-by: Markus Rathgeb Signed-off-by: Amit Kumar Mondal --- .../astro/internal/job/CompositeJob.java | 51 +++++++++++++++++++ .../binding/astro/internal/job/Job.java | 39 +++++++++++--- 2 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/CompositeJob.java diff --git a/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/CompositeJob.java b/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/CompositeJob.java new file mode 100644 index 00000000000..9c70245fbfc --- /dev/null +++ b/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/CompositeJob.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2014-2017 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.eclipse.smarthome.binding.astro.internal.job; + +import java.util.List; + +/** + * {@link CompositeJob} comprises multiple {@link Job}s to be executed in order + * + * @author Markus Rathgeb - Initial contribution + * @author Amit Kumar Mondal - Minor modifications + */ +public final class CompositeJob extends AbstractJob { + + private final List jobs; + + /** + * Constructor + * + * @param thingUID thing UID + * @param jobs the jobs to execute + * @throws IllegalArgumentException + * if {@code jobs} is {@code null} or empty + */ + public CompositeJob(String thingUID, List jobs) { + super(thingUID); + checkArgument(jobs != null, "Jobs must not be null"); + checkArgument(!jobs.isEmpty(), "Jobs must not be empty"); + + this.jobs = jobs; + + boolean notMatched = jobs.stream().anyMatch(j -> !j.getThingUID().equals(thingUID)); + checkArgument(!notMatched, "The jobs must associate the same thing UID"); + } + + @Override + public void run() { + jobs.forEach(j -> { + try { + j.run(); + } catch (RuntimeException ex) { + logger.warn("Job execution failed.", ex); + } + }); + } +} \ No newline at end of file diff --git a/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/Job.java b/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/Job.java index c34d7946593..b77dd22a9f0 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/Job.java +++ b/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/internal/job/Job.java @@ -7,12 +7,18 @@ */ package org.eclipse.smarthome.binding.astro.internal.job; +import static java.util.Arrays.asList; +import static java.util.Calendar.SECOND; +import static java.util.Collections.singletonList; import static java.util.Objects.isNull; +import static java.util.stream.Collectors.toList; +import static org.apache.commons.lang.time.DateUtils.truncatedEquals; import static org.eclipse.smarthome.binding.astro.AstroBindingConstants.*; import static org.eclipse.smarthome.binding.astro.internal.util.DateTimeUtils.*; import java.lang.invoke.MethodHandles; import java.util.Calendar; +import java.util.List; import org.eclipse.smarthome.binding.astro.handler.AstroThingHandler; import org.eclipse.smarthome.binding.astro.internal.config.AstroChannelConfig; @@ -65,20 +71,34 @@ public static void schedule(String thingUID, AstroThingHandler astroHandler, Job */ public static void scheduleEvent(String thingUID, AstroThingHandler astroHandler, Calendar eventAt, String event, String channelId) { + scheduleEvent(thingUID, astroHandler, eventAt, singletonList(event), channelId); + } + + /** + * Schedules an {@link EventJob} instance + * + * @param thingUID the Thing UID + * @param astroHandler the {@link ThingHandler} instance + * @param eventAt the {@link Calendar} instance denoting scheduled instant + * @param events the event IDs to schedule + * @param channelId the channel ID + */ + public static void scheduleEvent(String thingUID, AstroThingHandler astroHandler, Calendar eventAt, + List events, String channelId) { boolean thingNull = checkNull(thingUID, "Thing UID is null"); boolean astroHandlerNull = checkNull(astroHandler, "AstroThingHandler is null"); boolean eventAtNull = checkNull(eventAt, "Scheduled Instant is null"); - boolean eventNull = checkNull(event, "Event is null"); + boolean eventsNull = checkNull(events, "Events list is null"); boolean channelIdNull = checkNull(channelId, "Channel ID is null"); - if (thingNull || astroHandlerNull || eventAtNull || eventNull || channelIdNull) { + if (thingNull || astroHandlerNull || eventAtNull || eventsNull || channelIdNull || events.isEmpty()) { return; } AstroChannelConfig config = astroHandler.getThing().getChannel(channelId).getConfiguration() .as(AstroChannelConfig.class); Calendar instant = applyConfig(eventAt, config); - Job eventJob = new EventJob(thingUID, channelId, event); - schedule(thingUID, astroHandler, eventJob, instant); + List jobs = events.stream().map(e -> new EventJob(thingUID, channelId, e)).collect(toList()); + schedule(thingUID, astroHandler, new CompositeJob(thingUID, jobs), instant); } /** @@ -98,8 +118,15 @@ public static void scheduleRange(String thingUID, AstroThingHandler astroHandler if (thingNull || astroHandlerNull || rangeNull || channelIdNull) { return; } - scheduleEvent(thingUID, astroHandler, range.getStart(), EVENT_START, channelId); - scheduleEvent(thingUID, astroHandler, range.getEnd(), EVENT_END, channelId); + + Calendar start = range.getStart(); + Calendar end = range.getEnd(); + if (truncatedEquals(start, end, SECOND)) { + scheduleEvent(thingUID, astroHandler, start, asList(EVENT_START, EVENT_END), channelId); + } else { + scheduleEvent(thingUID, astroHandler, start, EVENT_START, channelId); + scheduleEvent(thingUID, astroHandler, end, EVENT_END, channelId); + } } /**