⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appointmentimpl.java

📁 Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*--------------------------------------------------------------------------*
 | Copyright (C) 2006 Christopher Kohlhaas                                  |
 |                                                                          |
 | This program is free software; you can redistribute it and/or modify     |
 | it under the terms of the GNU General Public License as published by the |
 | Free Software Foundation. A copy of the license has been included with   |
 | these distribution in the COPYING file, if not go to www.fsf.org .       |
 |                                                                          |
 | As a special exception, you are granted the permissions to link this     |
 | program with every library, which license fulfills the Open Source       |
 | Definition as published by the Open Source Initiative (OSI).             |
 *--------------------------------------------------------------------------*/
package org.rapla.entities.domain.internal;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.rapla.components.util.Assert;
import org.rapla.components.util.DateTools;
import org.rapla.components.util.Tools;
import org.rapla.entities.RaplaType;
import org.rapla.entities.domain.Appointment;
import org.rapla.entities.domain.AppointmentBlockArray;
import org.rapla.entities.domain.Repeating;
import org.rapla.entities.domain.Reservation;
import org.rapla.entities.storage.Mementable;
import org.rapla.entities.storage.internal.SimpleEntity;

public class AppointmentImpl extends SimpleEntity implements Appointment, Mementable,java.io.Serializable
{
    // Don't forget to increase the serialVersionUID when you change the fields
    private static final long serialVersionUID = 1;
    
    private Date start;
    private Date end;
    private RepeatingImpl repeating;
    private boolean isWholeDaysSet = false;
    /** set DE (DebugDisabled) to false for debuging output. You must change in code
        because this flag is final for efficience reasons.*/
    public final static boolean DE = true;
    public final static String BUG = null;
    public static String DD = null;

    final public RaplaType getRaplaType() {return TYPE;}
    
    private AppointmentImpl() {
    }

    public AppointmentImpl(Date start,Date end) {
        this.start = start;
        this.end = end;
    }

    void setParent(Reservation parent) {
        getReferenceHandler().put("parent",parent);
        if (parent != null)
            setOwner(parent.getOwner());
    }

    public void removeParent()
    {
        getReferenceHandler().removeId("parent");
        setOwner( null );
    }

    
    public Date getStart() { return start;}
    public Date getEnd() { return end;}

    public void setReadOnly(boolean enable) {
        super.setReadOnly( enable );
        if ( repeating != null )
            repeating.setReadOnly( enable );
    }

    public void move(Date newStart) {
        long diff = this.end.getTime() - this.start.getTime();
        move(newStart, new Date(newStart.getTime() + diff));
    }

    public void move(Date start,Date end) {
        checkWritable();
        this.start = start;
        this.end = end;
    }

    public String toString() {
        if (start != null && end != null)
            return f(start.getTime(),end.getTime()) +
                ((repeating != null) ? (" [" + repeating.toString()) + "]": "");
        else
            return start + "-" + end;
    }

    public Reservation getReservation() {
        return (Reservation)getReferenceHandler().get("parent");
    }

    public boolean isWholeDaysSet() {
        return isWholeDaysSet;
    }

    public void setWholeDays(boolean enable) {
        checkWritable();
        if (enable) {
            if (start.getTime() != DateTools.cutDate(start.getTime()))
                this.start = DateTools.cutDate(this.start);
            if (start.getTime() != DateTools.cutDate(end.getTime()))
                this.end = DateTools.fillDate(this.end);
        }
        isWholeDaysSet  = enable;
    }

    public int compareTo(Object obj) {
        if (!(obj instanceof Appointment))
            throw new ClassCastException ("Appointment Expected");
        Appointment a2 = (Appointment) obj;
        Date start2 = a2.getStart();
        Date end2 = a2.getEnd();
        if (start.before( start2))
            return -1;
        if (start.after( start2))
            return 1;
        if (getEnd().before( end2))
            return -1;
        if (getEnd().after( end2))
            return 1;
        return 0;
    }

    transient Date maxDate;

    /** returns the largest date that covers the appointment
        and null if the appointments repeats forever.
    */
    public Date getMaxEnd() {
        long end = (this.end!= null) ? this.end.getTime():0;
        if  (repeating != null)
            if (repeating.getEnd() != null)
                end = Math.max(end
                               ,repeating.getEnd().getTime());
            else
                end = 0;
        if (end == 0)
            return null;

        // cache max date object
        if (maxDate == null || maxDate.getTime() != end)
            maxDate = new Date(end);
        return maxDate;
    }

    public Repeating getRepeating() {
        return repeating;
    }

    public void setRepeatingEnabled(boolean enableRepeating) {
        checkWritable();
        if (this.repeating == null) {
            if (enableRepeating) {
                this.repeating = new RepeatingImpl(Repeating.WEEKLY,this);
            }
        } else {
            if (!enableRepeating) {
                this.repeating = null;
            }
        }
    }

    public boolean isRepeatingEnabled() {
        return repeating != null;
    }

    public Date getFirstDifference( Appointment a2, Date maxDate ) {
        AppointmentBlockArray blocks1 = new AppointmentBlockArray();
        createBlocks( start, maxDate, blocks1);
        AppointmentBlockArray blocks2 = new AppointmentBlockArray();
        a2.createBlocks(a2.getStart(), maxDate, blocks2);
        //        System.out.println("block sizes " + blocks1.size() + ", " + blocks2.size() );
        for ( int i = 0; i < blocks1.size(); i++ ) {
            long a1Start = blocks1.getStartAt( i );
            long a1End = blocks1.getEndAt( i );
            if ( i >= blocks2.size() ) {
                return new Date( a1Start );
            }
            long a2Start = blocks2.getStartAt( i );
            long a2End = blocks2.getEndAt( i );
            //System.out.println("a1Start " + a1Start + " a1End " + a1End);
            //System.out.println("a2Start " + a2Start + " a2End " + a2End);
            if ( a1Start != a2Start )
                return new Date( Math.min ( a1Start, a2Start ) );

            if ( a1End != a2End )
                return new Date( Math.min ( a1End, a2End ) );
        }
        if ( blocks2.size() > blocks1.size() ) {
            return new Date( blocks2.getStartAt( blocks1.size() ) );
        }
        return null;
    }

    public Date getLastDifference( Appointment a2, Date maxDate ) {
        AppointmentBlockArray blocks1 = new AppointmentBlockArray();
        createBlocks( start, maxDate, blocks1);
        AppointmentBlockArray blocks2 = new AppointmentBlockArray();
        a2.createBlocks(a2.getStart(), maxDate, blocks2);
        if ( blocks2.size() > blocks1.size() ) {
            return new Date( blocks2.getEndAt( blocks1.size() ) );
        }
        if ( blocks1.size() > blocks2.size() ) {
            return new Date( blocks1.getEndAt( blocks2.size() ) );
        }
        for ( int i = blocks1.size() - 1 ; i >= 0; i-- ) {
            long a1Start = blocks1.getStartAt( i );
            long a1End = blocks1.getEndAt( i );
            long a2Start = blocks2.getStartAt( i );
            long a2End = blocks2.getEndAt( i );
            if ( a1End != a2End )
                return new Date( Math.max ( a1End, a2End ) );

            if ( a1Start != a2Start )
                return new Date( Math.max ( a1Start, a2Start ) );
        }
        return null;
    }

    public boolean matches(Appointment a2) {
        if (!Tools.equalsOrBothNull(this.start, a2.getStart()))
            return false;
        
        if (!Tools.equalsOrBothNull(this.end, a2.getEnd()))
            return false;
        
        Repeating r1 = this.repeating;
        Repeating r2 = a2.getRepeating();

        // No repeatings. The two appointments match
        if (r1 == null && r2 == null) {
            return true;
        } else if (r1 == null || r2 == null) {
            // one repeating is null the other not so the appointments don't match
            return false;
        }

        if (!r1.getType().equals(r2.getType()))
            return false;

        if (r1.getInterval() != r2.getInterval())
            return false;

        if (!Tools.equalsOrBothNull(r1.getEnd(), r2.getEnd()))
            return false;

        // The repeatings match regulary, so we must test the exceptions
        Date[] e1 = r1.getExceptions();
        Date[] e2 = r2.getExceptions();
        if (e1.length != e2.length) {
            //System.out.println("Exception-length don't match");
            return false;
        }

        for (int i=0;i<e1.length;i++)
            if (!e1[i].equals(e2[i])) {
                //System.out.println("Exception " + e1[i] + " doesn't match " + e2[i]);
                return false;
            }

        // Even the repeatings match, so  we can return true
        return true;
    }

    public void createBlocks(Date start,Date end,AppointmentBlockArray blocks) {
        createBlocks(start,end, blocks, true);
    }
    
    
    public void createBlocks(Date start,Date end,AppointmentBlockArray blocks, boolean excludeExceptions) {
        Assert.notNull(blocks);
        Assert.notNull(start,"You must set a startDate");
        Assert.notNull(end, "You must set an endDate");
        processBlocks(start.getTime(), end.getTime(), blocks, excludeExceptions);
    }
    /* returns true if there is at least one block in an array. If the passed blocks array is not null it will contain all blocks
     * that overlap the start,end period after a call.*/
    private boolean processBlocks(long start,long end,AppointmentBlockArray blocks, boolean excludeExceptions) {
        boolean checkOnly = (blocks == null);
        long c1 = start;
        long c2 = end;
        long s = this.start.getTime();
        long e = this.end.getTime();
        // if there is no repeating
        if (repeating==null) {
            if (s <c2 && e>c1) {
                if ( !checkOnly )
                    blocks.add(s,e,this, false);
                return true;
            } 
            return false;
        }

        DD=DE?BUG: print("s = appointmentstart, e = appointmentend, c1 = intervalstart c2 = intervalend");
        DD=DE?BUG: print("s:" + n(s) + " e:" + n(e) + " c2:" + n(c2) + " c1:" + n(c1));
        if (s <c2 && e>c1  && (!repeating.isException(s) || !excludeExceptions)) {
            if (checkOnly) {
                return true;
            } else {
                blocks.add(s,e,this, repeating.isException(s));
            }
        }
        
        long l = repeating.getIntervalLength( s  );
        //System.out.println( "l in days " + l / DateTools.MILLISECONDS_PER_DAY );
        Assert.isTrue(l>0);
        long timeFromStart = l ;
        if ( repeating.isFixedIntervalLength())
        {
            timeFromStart = Math.max(l,((c1-e) / l)* l);
        }
        int maxNumber = repeating.getNumber();
        long maxEnding = Long.MAX_VALUE;
        if ( maxNumber >= 0)
        {
            maxEnding = repeating.getEnd().getTime();
        }
        DD=DE?BUG: print("l = repeatingInterval (in minutes), x = stepcount");
        DD=DE?BUG: print("Maxend " + f( maxEnding));
        long currentPos = s + timeFromStart;
        DD=DE?BUG: print( " currentPos:" + n(currentPos) + " c2-s:" + n(c2-s) + " c1-e:" + n(c1-e));
        long blockLength = Math.max(0, e - s);
        while (currentPos <= c2 && (maxNumber<0 || currentPos<=maxEnding)) {
            DD=DE?BUG: print(" current pos:" + f(currentPos));
            if (( currentPos + blockLength > c1)  && ( currentPos < c2)) {
                boolean isException =repeating.isException( currentPos ); 
                if ((!isException || !excludeExceptions)) {
                    if ( checkOnly ) {
                        return true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -