create TodoItemUtil
This commit is contained in:
parent
ce19ac0261
commit
723addfba5
|
@ -0,0 +1,356 @@
|
|||
package org.cutem.cutecalendar.model;
|
||||
|
||||
import org.cutem.cutecalendar.util.GenericPair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.cutem.cutecalendar.model.TodoItem.*;
|
||||
|
||||
public class TodoItemUtil {
|
||||
|
||||
private static final int[] PARENT_CHILDREN_CONFLICT = {CONFERENCE, COURSE, DATE, INTERVIEW};
|
||||
|
||||
private static final int[] INTERSECTED_CONFLICT = {CONFERENCE, COURSE, DATE, INTERVIEW, TRIP};
|
||||
|
||||
private static boolean arrayContains(@NotNull int[] arr, int o) {
|
||||
for (int e : arr) {
|
||||
if (o == e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<GenericPair<Calendar, Calendar>> calculateRepeatArray(@NotNull TodoItem item) {
|
||||
ArrayList<GenericPair<Calendar, Calendar>> arrayList = new ArrayList<>();
|
||||
String repeatWeeks = item.getStringProperty("repeatWeeks");
|
||||
int repeat = repeatWeeks == null ? 1 : Integer.parseInt(repeatWeeks);
|
||||
Calendar c1 = item.getBgn();
|
||||
Calendar c2 = item.getEnd();
|
||||
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
arrayList.add(GenericPair.makePair(c1, c2));
|
||||
c1.add(Calendar.DAY_OF_MONTH, 7);
|
||||
c2.add(Calendar.DAY_OF_MONTH, 7);
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public static boolean isIntersected(
|
||||
@NotNull Calendar c1, @NotNull Calendar c2,
|
||||
@NotNull Calendar p1, @NotNull Calendar p2) {
|
||||
return !p1.after(c2) && !p2.before(c1);
|
||||
}
|
||||
|
||||
public static boolean isIntersected(
|
||||
@NotNull Collection<GenericPair<Calendar, Calendar>> ints1,
|
||||
@NotNull Collection<GenericPair<Calendar, Calendar>> ints2) {
|
||||
for (GenericPair<Calendar, Calendar> p1 : ints1) {
|
||||
for (GenericPair<Calendar, Calendar> p2 : ints2) {
|
||||
Calendar c1 = p1.getFirst();
|
||||
Calendar c2 = p1.getSecond();
|
||||
Calendar c3 = p2.getFirst();
|
||||
Calendar c4 = p2.getSecond();
|
||||
if (isIntersected(c1, c2, c3, c4)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isIntersectedWithAnniversary(
|
||||
@NotNull TodoItem anniversary,
|
||||
@NotNull Collection<GenericPair<Calendar, Calendar>> ints) {
|
||||
|
||||
for (GenericPair<Calendar, Calendar> p : ints) {
|
||||
Calendar p1 = p.getFirst();
|
||||
Calendar p2 = p.getSecond();
|
||||
|
||||
Calendar c1 = anniversary.getBgn();
|
||||
Calendar c2 = anniversary.getEnd();
|
||||
int originYear = c1.get(Calendar.YEAR);
|
||||
int newYear = p1.get(Calendar.YEAR);
|
||||
|
||||
c1.set(Calendar.YEAR, newYear);
|
||||
c2.set(Calendar.YEAR, newYear);
|
||||
|
||||
if (originYear <= newYear && isIntersected(c1, c2, p1, p2)) {
|
||||
return true;
|
||||
} else {
|
||||
c1.add(Calendar.YEAR, 1);
|
||||
c2.add(Calendar.YEAR, 1);
|
||||
++newYear;
|
||||
|
||||
if (originYear <= newYear && isIntersected(c1, c2, p1, p2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if intersected; false otherwise.
|
||||
*
|
||||
* @param anniversary a TodoItem assumed to be {@code ANNIVERSARY} type
|
||||
* @param item any TodoItem instance (include "anniversary", "course", ...)
|
||||
* @return true if intersected; false otherwise
|
||||
*/
|
||||
public static boolean isIntersectedWithAnniversary(@NotNull TodoItem anniversary, @NotNull TodoItem item) {
|
||||
if (item.getType() == ANNIVERSARY && anniversary.getBgn().after(item.getBgn())) {
|
||||
TodoItem t = anniversary;
|
||||
anniversary = item;
|
||||
item = t;
|
||||
}
|
||||
|
||||
List<GenericPair<Calendar, Calendar>> list = calculateRepeatArray(item);
|
||||
return isIntersectedWithAnniversary(anniversary, list);
|
||||
}
|
||||
|
||||
public static boolean isIntersectedDuring(@NotNull TodoItem item, @NotNull Calendar from, @NotNull Calendar to) {
|
||||
ArrayList<GenericPair<Calendar, Calendar>> l2 = new ArrayList<>();
|
||||
l2.add(GenericPair.makePair(from, to));
|
||||
|
||||
if (item.getType() == ANNIVERSARY) {
|
||||
return isIntersectedWithAnniversary(item, l2);
|
||||
} else {
|
||||
List<GenericPair<Calendar, Calendar>> l1 = calculateRepeatArray(item);
|
||||
return isIntersected(l1, l2);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isIntersected(@NotNull TodoItem i1, @NotNull TodoItem i2) {
|
||||
if (i1.getType() == ANNIVERSARY) {
|
||||
return isIntersectedWithAnniversary(i1, i2);
|
||||
} else if (i2.getType() == ANNIVERSARY) {
|
||||
return isIntersectedWithAnniversary(i2, i1);
|
||||
} else {
|
||||
return isIntersected(calculateRepeatArray(i1), calculateRepeatArray(i2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isIntersectedConflict(@NotNull TodoItem i1, @NotNull TodoItem i2) {
|
||||
int t1 = i1.getType();
|
||||
int t2 = i2.getType();
|
||||
return isIntersected(i1, i2)
|
||||
&& arrayContains(INTERSECTED_CONFLICT, t1)
|
||||
&& arrayContains(INTERSECTED_CONFLICT, t2);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isIn(
|
||||
@NotNull Calendar out1, @NotNull Calendar out2,
|
||||
@NotNull Calendar in1, @NotNull Calendar in2) {
|
||||
// out1 <= in1 && in2 <= out2
|
||||
return !in1.before(out1) && !in2.after(out2);
|
||||
}
|
||||
|
||||
public static boolean isIn(
|
||||
@NotNull Collection<GenericPair<Calendar, Calendar>> l1,
|
||||
@NotNull Collection<GenericPair<Calendar, Calendar>> l2) {
|
||||
for (GenericPair<Calendar, Calendar> p1 : l1) {
|
||||
for (GenericPair<Calendar, Calendar> p2 : l2) {
|
||||
Calendar c1 = p1.getFirst();
|
||||
Calendar c2 = p1.getSecond();
|
||||
Calendar c3 = p2.getFirst();
|
||||
Calendar c4 = p2.getSecond();
|
||||
if (!isIn(c1, c2, c3, c4)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isInAnniversary(
|
||||
@NotNull TodoItem anniversary,
|
||||
@NotNull Collection<GenericPair<Calendar, Calendar>> ints) {
|
||||
|
||||
for (GenericPair<Calendar, Calendar> p : ints) {
|
||||
Calendar p1 = p.getFirst();
|
||||
Calendar p2 = p.getSecond();
|
||||
|
||||
Calendar c1 = anniversary.getBgn();
|
||||
Calendar c2 = anniversary.getEnd();
|
||||
|
||||
int originYear = c1.get(Calendar.YEAR);
|
||||
int newYear = p1.get(Calendar.YEAR);
|
||||
if (originYear > newYear) {
|
||||
return false;
|
||||
}
|
||||
|
||||
c1.set(Calendar.YEAR, newYear);
|
||||
c2.set(Calendar.YEAR, newYear);
|
||||
if (!isIn(c1, c2, p1, p2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isInAnniversary(
|
||||
@NotNull TodoItem anniversary,
|
||||
@NotNull TodoItem item) {
|
||||
if (item.getType() == ANNIVERSARY && anniversary.getBgn().after(item.getBgn())) {
|
||||
TodoItem t = anniversary;
|
||||
anniversary = item;
|
||||
item = t;
|
||||
}
|
||||
|
||||
List<GenericPair<Calendar, Calendar>> list = calculateRepeatArray(item);
|
||||
return isInAnniversary(anniversary, list);
|
||||
}
|
||||
|
||||
public static boolean isIn(@NotNull TodoItem item, @NotNull Calendar from, @NotNull Calendar to) {
|
||||
ArrayList<GenericPair<Calendar, Calendar>> l2 = new ArrayList<>();
|
||||
l2.add(GenericPair.makePair(from, to));
|
||||
|
||||
if (item.getType() == ANNIVERSARY) {
|
||||
return isInAnniversary(item, l2);
|
||||
} else {
|
||||
List<GenericPair<Calendar, Calendar>> l1 = calculateRepeatArray(item);
|
||||
return isIntersected(l1, l2);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isIn(@NotNull TodoItem i1, @NotNull TodoItem i2) {
|
||||
if (i1.getType() == ANNIVERSARY) {
|
||||
return isInAnniversary(i1, i2);
|
||||
} else if (i2.getType() == ANNIVERSARY) {
|
||||
return isInAnniversary(i2, i1);
|
||||
} else {
|
||||
return isIn(calculateRepeatArray(i1), calculateRepeatArray(i2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isParentChildConflict(@NotNull TodoItem parent, @NotNull TodoItem child) {
|
||||
int pType = parent.getType();
|
||||
int cType = child.getType();
|
||||
|
||||
return pType != cType && arrayContains(PARENT_CHILDREN_CONFLICT, pType)
|
||||
&& arrayContains(PARENT_CHILDREN_CONFLICT, cType);
|
||||
}
|
||||
|
||||
public static boolean canBecomeSubTodoItem(@NotNull TodoItem parent, @NotNull TodoItem newItem) {
|
||||
return isIn(parent, newItem) && !isParentChildConflict(parent, newItem);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isParentTodoItem(@NotNull TodoItem item) {
|
||||
return item.getStringProperty(CHILDREN_IDS) != null;
|
||||
}
|
||||
|
||||
public static boolean isChildTodoItem(@NotNull TodoItem item) {
|
||||
return item.getStringProperty(PARENT_ID) != null;
|
||||
}
|
||||
|
||||
public static List<Long> getAllChildrenIds(@NotNull TodoItem item) {
|
||||
String ids = item.getStringProperty(CHILDREN_IDS);
|
||||
String[] idsSlice = ids.split("[;,]");
|
||||
ArrayList<Long> result = new ArrayList<>(idsSlice.length);
|
||||
|
||||
for (int i = 0; i < ids.length(); i++) {
|
||||
long id = Long.parseLong(idsSlice[i]);
|
||||
result.set(i, id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long getParentId(@NotNull TodoItem item) {
|
||||
String id = item.getStringProperty(PARENT_ID);
|
||||
return Long.parseLong(id);
|
||||
}
|
||||
|
||||
public static String idsToString(@NotNull Collection<Long> ids) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
boolean first = true;
|
||||
for (long i : ids) {
|
||||
if (!first) {
|
||||
builder.append(';');
|
||||
}
|
||||
builder.append(Long.toString(i));
|
||||
first = false;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static TodoItem[] bind(@NotNull TodoItem parent, @NotNull TodoItem child) {
|
||||
if (!isParentTodoItem(parent)) {
|
||||
throw new IllegalArgumentException("parent is not a parent todo-item");
|
||||
}
|
||||
if (!isChildTodoItem(child)) {
|
||||
throw new IllegalArgumentException("child is not a child todo-item");
|
||||
}
|
||||
|
||||
TodoItemFactory fParent = new TodoItemFactory().copy(parent);
|
||||
TodoItemFactory fChild = new TodoItemFactory().copy(child);
|
||||
|
||||
List<Long> ids = getAllChildrenIds(parent);
|
||||
ids.add(child.getId());
|
||||
String idsString = idsToString(ids);
|
||||
|
||||
TodoItem newP = fParent
|
||||
.stringProperties(CHILDREN_IDS, idsString)
|
||||
.stringProperties(COMPOSITE, "parent")
|
||||
.buildId(parent.getId());
|
||||
|
||||
String pIdString = Long.toString(parent.getId());
|
||||
|
||||
TodoItem newC = fChild
|
||||
.stringProperties(PARENT_ID, pIdString)
|
||||
.stringProperties(COMPOSITE, "child")
|
||||
.buildId(child.getId());
|
||||
|
||||
return new TodoItem[]{newP, newC};
|
||||
}
|
||||
|
||||
public static TodoItem[] unbind(@NotNull TodoItem parent, @NotNull TodoItem child) {
|
||||
if (!isParentTodoItem(parent)) {
|
||||
throw new IllegalArgumentException("parent is not a parent todo-item");
|
||||
}
|
||||
if (!isChildTodoItem(child)) {
|
||||
throw new IllegalArgumentException("child is not a child todo-item");
|
||||
}
|
||||
|
||||
TodoItemFactory fParent = new TodoItemFactory().copy(parent);
|
||||
TodoItemFactory fChild = new TodoItemFactory().copy(child);
|
||||
|
||||
List<Long> ids = getAllChildrenIds(parent);
|
||||
ids.remove(child.getId());
|
||||
String idsString = idsToString(ids);
|
||||
|
||||
TodoItem newP = fParent
|
||||
.stringProperties(CHILDREN_IDS, idsString)
|
||||
.stringProperties(COMPOSITE, "parent")
|
||||
.buildId(parent.getId());
|
||||
|
||||
TodoItem newC = fChild
|
||||
.stringProperties(PARENT_ID, null)
|
||||
.stringProperties(COMPOSITE, "parent")
|
||||
.buildId(child.getId());
|
||||
|
||||
return new TodoItem[]{newP, newC};
|
||||
}
|
||||
|
||||
|
||||
public static TodoItem finishSingleTodoItem(@NotNull TodoItem item) {
|
||||
TodoItemFactory factory = new TodoItemFactory();
|
||||
return factory.copy(item).stringProperties(FINISH, "finish").buildId(item.getId());
|
||||
}
|
||||
|
||||
public static TodoItem finishTimelessItem(@NotNull String title) {
|
||||
TodoItemFactory factory = new TodoItemFactory();
|
||||
return factory.wholeDay(Calendar.getInstance()).title(title).build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.cutem.cutecalendar.model;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class TodoItemUtilTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.out.println(c.getTime());
|
||||
c.add(Calendar.DAY_OF_MONTH, 7);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue