📄 appointmentimpl.java
字号:
} else {
blocks.add( currentPos,currentPos + blockLength,this, isException);
}
}
}
currentPos += repeating.getIntervalLength( currentPos) ;
}
return false;
}
public boolean overlaps(Date start,Date end) {
return overlaps( start, end , true );
}
public boolean overlaps(Date start,Date end, boolean excludeExceptions) {
if (start == null && end == null)
return true;
if (start == null)
start = this.start;
if (end == null)
{
// there must be an overlapp because there can't be infinity exceptions
if (getMaxEnd() == null)
return true;
end = getMaxEnd();
}
if (getMaxEnd() != null && getMaxEnd().before(start))
return false;
if (this.start.after(end))
return false;
boolean overlaps = processBlocks( start.getTime(), end.getTime(), null, excludeExceptions );
return overlaps;
}
public boolean overlaps(long start,long end, boolean excludeExceptions) {
if (getMaxEnd() != null && getMaxEnd().getTime()<start)
return false;
if (this.start.getTime() > end)
return false;
boolean overlaps = processBlocks( start, end, null, excludeExceptions );
return overlaps;
}
private static Date getOverlappingEnd(Repeating r1,Repeating r2) {
Date maxEnd = null;
if (r1.getEnd() != null)
maxEnd = r1.getEnd();
if (r2.getEnd() != null)
if (maxEnd != null && r2.getEnd().before(maxEnd))
maxEnd = r2.getEnd();
return maxEnd;
}
public boolean overlaps(Appointment a2) {
if ( a2 == this)
return true;
Date start2 =a2.getStart();
Date end2 =a2.getEnd();
long s1 = this.start.getTime();
long s2 = start2.getTime();
long e1 = this.end.getTime();
long e2 = a2.getEnd().getTime();
RepeatingImpl r1 = this.repeating;
RepeatingImpl r2 = (RepeatingImpl)a2.getRepeating();
DD=DE?BUG: print("Testing overlap of");
DD=DE?BUG: print(" A1: " + toString());
DD=DE?BUG: print(" A2: " + a2.toString());
if (r1 == null && r2 == null) {
if (e2<=s1 || e1<=s2)
return false;
return true;
}
if (r1 == null) {
return a2.overlaps(this.start,this.end);
}
if (r2 == null) {
return overlaps(start2,end2);
}
// So both appointments have a repeating
// If r2 has no exceptions we can check if a1 overlaps the first appointment of a2
if (overlaps(start2,end2) && !r2.isException(start2.getTime())) {
DD=DE?BUG: print("Primitive overlap for " + getReservation() + " with " + a2.getReservation());
return true;
}
// Check if appointments could overlap because of the end-dates of an repeating
Date end = getOverlappingEnd(r1,r2);
if (end != null && (end.getTime()<=s1 || end.getTime()<=s2))
return false;
// We cant compare the fixed interval length here so we have to compare the blocks
if ( !r1.isFixedIntervalLength())
{
return overlapsHard( (AppointmentImpl)a2);
}
if ( !r2.isFixedIntervalLength())
{
return ((AppointmentImpl)a2).overlapsHard( this);
}
// O.K. we found 2 Candidates for the hard way
long l1 = r1.getFixedIntervalLength();
long l2 = r2.getFixedIntervalLength();
// The greatest common divider of the two intervals
long gcd = gcd(l1,l2);
long startx1 = Math.max(0,(s2-e1))/l1;
long startx2 = Math.max(0,(s1-e2))/l2;
DD=DE?BUG: print("l? = intervalsize for A?, x? = stepcount for A? ");
long max_x1 = l2/gcd + startx1;
if (end!= null && (end.getTime()-s1)/l1 + startx1 < max_x1)
max_x1 = (end.getTime()-s1)/l1 + startx1;
long max_x2 = l1/gcd + startx2;
if (end!= null && (end.getTime()-s2)/l2 + startx2 < max_x2)
max_x2 = (end.getTime()-s2)/l2 + startx2;
long x1 =startx1;
long x2 =startx2;
DD=DE?BUG: print(
"l1: " + n(l1)
+ " l2: " + n(l2)
+ " gcd: " + n(gcd)
+ " start_x1: " + startx1
+ " start_x2: " + startx2
+ " max_x1: " + max_x1
+ " max_x2: " + max_x2
);
boolean overlaps = false;
long current1 = x1 *l1;
long current2 = x2 *l2;
long maxEnd1 = max_x1*l1;
long maxEnd2 = max_x2*l2;
while (current1<=maxEnd1 && current2<=maxEnd2) {
// DD=DE?BUG: print("x1: " + x1 + " x2:" + x2);
DD=DE?BUG: print(" A1: " + f(s1 + current1, e1 + current1));
DD=DE?BUG: print(" A2: " + f(s2 + current2, e2 + current2));
if ((s1 + current1) < (e2 + current2) &&
(e1 + current1) > (s2 + current2)) {
if (!isException(s1 + current1,s2 + current2,r2)) {
overlaps = true;
break;
}
}
if ((s1 + current1) < (s2 + current2))
current1+=l1;
else
current2+=l2;
}
if (overlaps)
DD=DE?BUG: print("Appointments overlap");
else
DD=DE?BUG: print("Appointments don't overlap");
return overlaps;
}
private boolean overlapsHard( AppointmentImpl a2 )
{
RepeatingImpl r2 = (RepeatingImpl)a2.getRepeating();
AppointmentBlockArray array = new AppointmentBlockArray();
Date maxEnd =r2.getEnd();
if ( maxEnd == null)
{
// overlaps will be checked two 250 weeks (5 years) from now on
maxEnd = new Date(a2.getStart().getTime() + DateTools.MILLISECONDS_PER_WEEK * 250);
}
createBlocks( getStart(), maxEnd, array);
for ( int i=0;i<array.size();i++)
{
long start = array.getStartAt( i);
long end = array.getEndAt( i);
if (a2.overlaps( start, end, true))
{
return true;
}
}
return false;
}
/** the greatest common divider of a and b (Euklids Algorithm) */
public static long gcd(long a,long b){
return (b == 0) ? a : gcd(b, a%b);
}
/* Prueft im Abstand von "gap" millisekunden das Intervall von start bis ende
auf Ausnahmen. Gibt es fuer einen Punkt keine Ausnahme wird false zurueckgeliefert.
*/
private boolean isException(long s1,long s2,RepeatingImpl r2) {
RepeatingImpl r1 = repeating;
Date end= getOverlappingEnd(r1,r2);
if (end == null)
return false;
if ((!r1.hasExceptions() && !r2.hasExceptions()))
return false;
long l1 = r1.getFixedIntervalLength();
long l2 = r2.getFixedIntervalLength();
long gap = (l1 * l2) / gcd(l1,l2);
Date[] exceptions1 = r1.getExceptions();
Date[] exceptions2 = r2.getExceptions();
DD=DE?BUG: print(" Testing Exceptions for overlapp " + f(s1) + " with " + f(s2) + " gap " + n(gap));
int i1 = 0;
int i2 = 0;
long x = 0;
if (exceptions1.length>i1)
DD=DE?BUG: print("Exception a1: " + fe(exceptions1[i1].getTime()));
if (exceptions2.length>i2)
DD=DE?BUG: print("Exception a2: " + fe(exceptions2[i2].getTime()));
while (s1 + x * gap < end.getTime()) {
DD=DE?BUG: print("Looking for exception for gap " + x + " s1: " + fe(s1+x*gap) + " s2: " + fe(s2+x*gap));
while ((i1<exceptions1.length)
&& (exceptions1[i1].getTime() + DateTools.MILLISECONDS_PER_DAY <= s1 + x*gap))
{
i1 ++;
if (exceptions1.length>i1) {
DD=DE?BUG: print("Exception a1: " + fe(exceptions1[i1].getTime()));
}
}
while ((exceptions2.length>i2)
&& (exceptions2[i2].getTime() + DateTools.MILLISECONDS_PER_DAY <= s2 + x*gap)) {
i2 ++;
if (exceptions2.length>i2) {
DD=DE?BUG: print("Exception a2: " + fe(exceptions2[i2].getTime()));
}
}
if ((exceptions1.length==i1)
|| (s1 + x*gap >= exceptions1[i1].getTime() + DateTools.MILLISECONDS_PER_DAY)) {
DD=DE?BUG: print("Exception from a1 doesnt match ");
if ((exceptions2.length==i2)
|| (s2 + x*gap >= exceptions2[i2].getTime() + DateTools.MILLISECONDS_PER_DAY)) {
DD=DE?BUG: print("Exception from a2 doesnt match. !");
return false;
} else {
DD=DE?BUG: print("Exception from a2 matches!");
}
} else {
DD=DE?BUG: print("Exception from a1 matches!");
}
DD=DE?BUG: print("Exception found for gap " + x);
x ++;
}
DD=DE?BUG: print("Exceptions found for every gap. No overlapping. ");
return true;
}
private static String print(String string) {
if (string != null)
System.out.println(string);
return string;
}
/* cuts the milliseconds and seconds. Usefull for debugging output.*/
private long n(long n) {
return n / (1000 * 60);
}
/* Formats milliseconds as date. Usefull for debugging output.*/
static String f(long n) {
SimpleDateFormat format = new SimpleDateFormat("E yyyy-MM-dd HH:mm");
format.setTimeZone(DateTools.getTimeZone());
return format.format(new Date(n));
}
/* Formats milliseconds as date without time. Usefull for debugging output.*/
static String fe(long n) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
format.setTimeZone(DateTools.getTimeZone());
return format.format(new Date(n));
}
/* Formats 2 dates in milliseconds as appointment. Usefull for debugging output.*/
static String f(long s,long e) {
Date start = new Date(s);
Date end = new Date(e);
SimpleDateFormat formatLong = new SimpleDateFormat("E yyyy-MM-dd HH:mm");
formatLong.setTimeZone(DateTools.getTimeZone());
SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
formatTime.setTimeZone(DateTools.getTimeZone());
if (DateTools.isSameDay(s,e)) {
return formatLong.format(start) + "-" + formatTime.format(end);
} else {
return formatLong.format(start) + "-" + formatLong.format(end);
}
}
static private void copy(AppointmentImpl source,AppointmentImpl dest) {
dest.isWholeDaysSet = source.isWholeDaysSet;
dest.start = source.start;
dest.end = source.end;
dest.repeating = (RepeatingImpl) ((source.repeating != null) ?
source.repeating.clone()
: null);
if (dest.repeating != null)
dest.repeating.setAppointment(dest);
}
public void copy(Object obj) {
super.copy((AppointmentImpl)obj);
copy((AppointmentImpl) obj,this);
}
public Object deepClone() {
AppointmentImpl clone = new AppointmentImpl();
super.deepClone(clone);
copy(this,clone);
return clone;
}
public Object clone() {
AppointmentImpl clone = new AppointmentImpl();
super.clone(clone);
copy(this,clone);
return clone;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -