Request.java 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (c) 2014-2015 by appPlant UG. All rights reserved.
  3. *
  4. * @APPPLANT_LICENSE_HEADER_START@
  5. *
  6. * This file contains Original Code and/or Modifications of Original Code
  7. * as defined in and that are subject to the Apache License
  8. * Version 2.0 (the 'License'). You may not use this file except in
  9. * compliance with the License. Please obtain a copy of the License at
  10. * http://opensource.org/licenses/Apache-2.0/ and read it before using this
  11. * file.
  12. *
  13. * The Original Code and all software distributed under the License are
  14. * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  15. * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  16. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  18. * Please see the License for the specific language governing rights and
  19. * limitations under the License.
  20. *
  21. * @APPPLANT_LICENSE_HEADER_END@
  22. */
  23. package de.appplant.cordova.plugin.notification;
  24. import org.json.JSONObject;
  25. import java.util.Arrays;
  26. import java.util.Calendar;
  27. import java.util.Date;
  28. import java.util.List;
  29. import de.appplant.cordova.plugin.notification.trigger.DateTrigger;
  30. import de.appplant.cordova.plugin.notification.trigger.IntervalTrigger;
  31. import de.appplant.cordova.plugin.notification.trigger.MatchTrigger;
  32. import static de.appplant.cordova.plugin.notification.trigger.IntervalTrigger.Unit;
  33. /**
  34. * An object you use to specify a notification’s content and the condition
  35. * that triggers its delivery.
  36. */
  37. public final class Request {
  38. // Key name for bundled extras
  39. static final String EXTRA_OCCURRENCE = "NOTIFICATION_OCCURRENCE";
  40. // Key name for bundled extras
  41. public static final String EXTRA_LAST = "NOTIFICATION_LAST";
  42. // The options spec
  43. private final Options options;
  44. // The right trigger for the options
  45. private final DateTrigger trigger;
  46. // How often the trigger shall occur
  47. private final int count;
  48. // The trigger spec
  49. private final JSONObject spec;
  50. // The current trigger date
  51. private Date triggerDate;
  52. /**
  53. * Constructor
  54. *
  55. * @param options The options spec.
  56. */
  57. public Request(Options options) {
  58. this.options = options;
  59. this.spec = options.getTrigger();
  60. this.count = spec.optInt("count", 1);
  61. this.trigger = buildTrigger();
  62. this.triggerDate = trigger.getNextTriggerDate(getBaseDate());
  63. }
  64. /**
  65. * Gets the options spec.
  66. */
  67. public Options getOptions() {
  68. return options;
  69. }
  70. /**
  71. * The identifier for the request.
  72. *
  73. * @return The notification ID as the string
  74. */
  75. public String getIdentifier() {
  76. return options.getId().toString() + "-" + getOccurrence();
  77. }
  78. /**
  79. * The value of the internal occurrence counter.
  80. */
  81. int getOccurrence() {
  82. return trigger.getOccurrence();
  83. }
  84. /**
  85. * If there's one more trigger date to calculate.
  86. */
  87. private boolean hasNext() {
  88. return triggerDate != null && getOccurrence() < count;
  89. }
  90. /**
  91. * Moves the internal occurrence counter by one.
  92. */
  93. boolean moveNext() {
  94. if (hasNext()) {
  95. triggerDate = getNextTriggerDate();
  96. } else {
  97. triggerDate = null;
  98. }
  99. return this.triggerDate != null;
  100. }
  101. /**
  102. * Gets the current trigger date.
  103. *
  104. * @return null if there's no trigger date.
  105. */
  106. Date getTriggerDate() {
  107. Calendar now = Calendar.getInstance();
  108. if (triggerDate == null)
  109. return null;
  110. if ((now.getTimeInMillis() - triggerDate.getTime()) > 60000) {
  111. return null;
  112. }
  113. return triggerDate;
  114. }
  115. /**
  116. * Gets the next trigger date based on the current trigger date.
  117. */
  118. private Date getNextTriggerDate() {
  119. return trigger.getNextTriggerDate(triggerDate);
  120. }
  121. /**
  122. * Build the trigger specified in options.
  123. */
  124. private DateTrigger buildTrigger() {
  125. Object every = spec.opt("every");
  126. if (every instanceof JSONObject) {
  127. return new MatchTrigger(getDateMatchingComponents());
  128. }
  129. Unit unit = getUnit();
  130. int ticks = getTicks();
  131. return new IntervalTrigger(ticks, unit);
  132. }
  133. /**
  134. * Gets the unit value.
  135. */
  136. private Unit getUnit() {
  137. Object every = spec.opt("every");
  138. String unit = "SECOND";
  139. if (spec.has("unit")) {
  140. unit = spec.optString("unit", "second");
  141. } else
  142. if (every instanceof String) {
  143. unit = spec.optString("every", "second");
  144. }
  145. return Unit.valueOf(unit.toUpperCase());
  146. }
  147. /**
  148. * Gets the tick value.
  149. */
  150. private int getTicks() {
  151. Object every = spec.opt("every");
  152. int ticks = 0;
  153. if (spec.has("at")) {
  154. ticks = 0;
  155. } else
  156. if (spec.has("in")) {
  157. ticks = spec.optInt("in", 0);
  158. } else
  159. if (every instanceof String) {
  160. ticks = 1;
  161. } else
  162. if (!(every instanceof JSONObject)) {
  163. ticks = spec.optInt("every", 0);
  164. }
  165. return ticks;
  166. }
  167. /**
  168. * Gets an array of all date parts to construct a datetime instance.
  169. *
  170. * @return [min, hour, day, month, year]
  171. */
  172. private List<Integer> getDateMatchingComponents() {
  173. JSONObject every = spec.optJSONObject("every");
  174. return Arrays.asList(
  175. (Integer) every.opt("minute"),
  176. (Integer) every.opt("hour"),
  177. (Integer) every.opt("day"),
  178. (Integer) every.opt("month"),
  179. (Integer) every.opt("year")
  180. );
  181. }
  182. /**
  183. * Gets the base date from where to calculate the next trigger date.
  184. */
  185. private Date getBaseDate() {
  186. if (spec.has("at")) {
  187. return new Date(spec.optLong("at", 0) * 1000);
  188. } else {
  189. return new Date();
  190. }
  191. }
  192. }