create TodoItemUtil

This commit is contained in:
hlq07 2018-05-27 01:11:43 +08:00
parent ce19ac0261
commit 723addfba5
2 changed files with 386 additions and 0 deletions

View File

@ -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();
}
}

View File

@ -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);
}
}
}