Source Code Cross Referenced for AssignmentDetail.java in  » Project-Management » OpenProj » com » projity » pm » assignment » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Project Management » OpenProj » com.projity.pm.assignment 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:        The contents of this file are subject to the Common Public Attribution License 
0003:        Version 1.0 (the "License"); you may not use this file except in compliance with 
0004:        the License. You may obtain a copy of the License at 
0005:        http://www.projity.com/license . The License is based on the Mozilla Public 
0006:        License Version 1.1 but Sections 14 and 15 have been added to cover use of 
0007:        software over a computer network and provide for limited attribution for the 
0008:        Original Developer. In addition, Exhibit A has been modified to be consistent 
0009:        with Exhibit B.
0010:
0011:        Software distributed under the License is distributed on an "AS IS" basis, 
0012:        WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
0013:        specific language governing rights and limitations under the License. The 
0014:        Original Code is OpenProj. The Original Developer is the Initial Developer and 
0015:        is Projity, Inc. All portions of the code written by Projity are Copyright (c) 
0016:        2006, 2007. All Rights Reserved. Contributors Projity, Inc.
0017:
0018:        Alternatively, the contents of this file may be used under the terms of the 
0019:        Projity End-User License Agreeement (the Projity License), in which case the 
0020:        provisions of the Projity License are applicable instead of those above. If you 
0021:        wish to allow use of your version of this file only under the terms of the 
0022:        Projity License and not to allow others to use your version of this file under 
0023:        the CPAL, indicate your decision by deleting the provisions above and replace 
0024:        them with the notice and other provisions required by the Projity  License. If 
0025:        you do not delete the provisions above, a recipient may use your version of this 
0026:        file under either the CPAL or the Projity License.
0027:
0028:        [NOTE: The text of this license may differ slightly from the text of the notices 
0029:        in Exhibits A and B of the license at http://www.projity.com/license. You should 
0030:        use the latest text at http://www.projity.com/license for your modifications.
0031:        You may not remove this license text from the source files.]
0032:
0033:        Attribution Information: Attribution Copyright Notice: Copyright © 2006, 2007 
0034:        Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj, 
0035:        an open source solution from Projity. Attribution URL: http://www.projity.com 
0036:        Graphic Image as provided in the Covered Code as file:  openproj_logo.png with 
0037:        alternatives listed on http://www.projity.com/logo
0038:
0039:        Display of Attribution Information is required in Larger Works which are defined 
0040:        in the CPAL as a work which combines Covered Code or portions thereof with code 
0041:        not governed by the terms of the CPAL. However, in addition to the other notice 
0042:        obligations, all copies of the Covered Code in Executable and Source Code form 
0043:        distributed must, as a form of attribution of the original author, include on 
0044:        each user interface screen the "OpenProj" logo visible to all users.  The 
0045:        OpenProj logo should be located horizontally aligned with the menu bar and left 
0046:        justified on the top left of the screen adjacent to the File menu.  The logo 
0047:        must be at least 100 x 25 pixels.  When users click on the "OpenProj" logo it 
0048:        must direct them back to http://www.projity.com.  
0049:         */
0050:
0051:        package com.projity.pm.assignment;
0052:
0053:        import java.io.IOException;
0054:        import java.io.ObjectInputStream;
0055:        import java.io.ObjectOutputStream;
0056:        import java.io.Serializable;
0057:        import java.util.Collection;
0058:
0059:        import com.projity.configuration.CircularDependencyException;
0060:        import com.projity.datatype.Duration;
0061:        import com.projity.datatype.Rate;
0062:        import com.projity.datatype.TimeUnit;
0063:        import com.projity.document.Document;
0064:        import com.projity.functor.IntervalConsumer;
0065:        import com.projity.options.CalendarOption;
0066:        import com.projity.pm.assignment.contour.AbstractContour;
0067:        import com.projity.pm.assignment.contour.AbstractContourBucket;
0068:        import com.projity.pm.assignment.contour.ContourTypes;
0069:        import com.projity.pm.assignment.contour.PersonalContour;
0070:        import com.projity.pm.assignment.contour.StandardContour;
0071:        import com.projity.pm.calendar.CalendarService;
0072:        import com.projity.pm.calendar.HasCalendar;
0073:        import com.projity.pm.calendar.InvalidCalendarIntersectionException;
0074:        import com.projity.pm.calendar.WorkCalendar;
0075:        import com.projity.pm.calendar.WorkingCalendar;
0076:        import com.projity.pm.costing.CostRateTables;
0077:        import com.projity.pm.criticalpath.TaskSchedule;
0078:        import com.projity.pm.resource.Resource;
0079:        import com.projity.pm.scheduling.Delayable;
0080:        import com.projity.pm.scheduling.DelayableImpl;
0081:        import com.projity.pm.scheduling.Schedule;
0082:        import com.projity.pm.scheduling.ScheduleInterval;
0083:        import com.projity.pm.scheduling.ScheduleUtil;
0084:        import com.projity.pm.task.NormalTask;
0085:        import com.projity.pm.task.Task;
0086:        import com.projity.pm.time.MutableInterval;
0087:        import com.projity.strings.Messages;
0088:        import com.projity.util.Alert;
0089:        import com.projity.util.DateTime;
0090:
0091:        /**
0092:         * Class representing the non-scheduling part of resource assignments.  It is immutable
0093:         * @stereotype thing 
0094:         */
0095:        public final class AssignmentDetail implements  Schedule, HasCalendar,
0096:                Cloneable, Serializable, ContourTypes {// , Schedule {
0097:            static final long serialVersionUID = 867792734923243L;
0098:            transient Rate rate = new Rate(1.0D, TimeUnit.PERCENT); // units can never be 0!!!
0099:            double percentComplete = 0;
0100:            long duration = 0;
0101:            //TODO There is some stuff to figure out regarding contouring remaining work.  If you change the contour, Project applies
0102:            // the entire contour to the remaining work.  If you keep completing and change the contour again, project keeps the
0103:            // different contours active to where they were applied.  The weird thing is that if you uncomplete the task, the work still
0104:            // shows the various contours, even if the current contour is flat.  This is a bug.
0105:
0106:            private int workContourType; // these are only used for serializing the contour.  They are not "up to date" otherwise
0107:            private int costContourType;
0108:            private transient AbstractContour workContour = StandardContour.FLAT_CONTOUR;
0109:            private transient AbstractContour costContour = StandardContour.FLAT_CONTOUR;
0110:
0111:            private WorkingCalendar actualExceptionsCalendar = null; // for when user enters actual work during non-work time of calendar
0112:            private transient WorkingCalendar intersectionCalendar = null;
0113:            private transient TaskSchedule taskSchedule = null;
0114:
0115:            private transient Resource resource;
0116:            private transient Task task;
0117:            private transient Delayable delayable;
0118:            private int requestDemandType = RequestDemandType.NONE;
0119:            private int costRateIndex = CostRateTables.DEFAULT;
0120:            private long overtimeWork = 0; // allowed overtime that is evenly distributed across contour
0121:
0122:            private WorkingCalendar baselineCalendar = null; // only applies if this is a baseline
0123:
0124:            /**
0125:             * @return Returns the percentComplete.
0126:             */
0127:            public double getPercentComplete() {
0128:                return percentComplete;
0129:            }
0130:
0131:            /**
0132:             * @param percentComplete The percentComplete to set.
0133:             */
0134:            public void setPercentComplete(double percentComplete) {
0135:                this .percentComplete = percentComplete;
0136:                if (getTask() != null) // in case of called from web
0137:                    ((NormalTask) getTask()).adjustActualStartFromAssignments();
0138:            }
0139:
0140:            /**
0141:             * @return Returns the duration.
0142:             */
0143:            public long getDuration() {
0144:                return duration;
0145:            }
0146:
0147:            void recalculateDuration() {
0148:                duration = workContour.calcTotalBucketDuration(0);
0149:            }
0150:
0151:            /**
0152:             * @param taskSchedule The taskSchedule to set.
0153:             */
0154:            void setTaskSchedule(TaskSchedule taskSchedule) {
0155:                this .taskSchedule = taskSchedule;
0156:            }
0157:
0158:            /**
0159:             * Set just the units and the resource.  This is the case when replacing a resource with another,
0160:             * such as the default resource assignment being replaced with a true one
0161:             * @param units
0162:             * @param resource
0163:             */
0164:            void replaceResourceAndUnits(double units, Resource resource) {
0165:                this .resource = resource;
0166:                setUnits(units);
0167:            }
0168:
0169:            /**
0170:             * Construct an assignment.  The arguments are those that are presented in the assign resource dialog
0171:             * @param task
0172:             * @param resource
0173:             * @param units
0174:             * @param requestDemandType  -Normally empty
0175:             */
0176:            AssignmentDetail(Task task, Resource resource, double units,
0177:                    int requestDemandType, long delay) {
0178:                this .task = task;
0179:                this .resource = resource;
0180:                setUnits(units);
0181:                this .requestDemandType = requestDemandType;
0182:                this .delayable = new DelayableImpl(delay, 0);
0183:            }
0184:
0185:            private AssignmentDetail() { // used in cloning
0186:
0187:            }
0188:
0189:            /**
0190:             * Accessor for units (value of work)
0191:             * @return units
0192:             */
0193:            double getUnits() {
0194:                return rate.getValue();
0195:            }
0196:
0197:            void setUnits(double units) {
0198:                rate.setValue(units);
0199:            }
0200:
0201:            /**
0202:             * Calculate the overtime value from the overtime work field.  MSProject distributes
0203:             * overtime uniformly over the working days of the assignment.
0204:             * @return overtime value 
0205:             */
0206:            double calcOvertimeUnits() {
0207:                long workingDuration = calcWorkingDuration(); //TODO this should be stored
0208:                if (workingDuration == 0) // take care of degenerate case
0209:                    return 0.0;
0210:                return ((double) overtimeWork) / workingDuration;
0211:            }
0212:
0213:            void setOvertimeWork(long overtimeWork) {
0214:                this .overtimeWork = overtimeWork;
0215:            }
0216:
0217:            /**
0218:             * Calculate the total work by multiplying units by the calculated duration
0219:             * @return total work.
0220:             */
0221:            long calcWork() {
0222:                //hk
0223:                return (long) (getUnits() * calcWorkingDuration());
0224:            }
0225:
0226:            public String toString() {
0227:                return super .toString();
0228:                //		return "[start] " + new java.util.Date(getStart())
0229:                //		      + "\n[end] " +  new java.util.Date(getEnd())
0230:                //			  +"\n[units] " + getUnits()// in hours
0231:                //			  +"\n[work] " + getWork() / (1000*60*60); // in hours
0232:            }
0233:
0234:            /**
0235:             * @return Returns the contour.
0236:             */
0237:            AbstractContour getWorkContour() {
0238:                return workContour;
0239:            }
0240:
0241:            /**
0242:             * @param contour The contour to set.
0243:             * TODO get rid of this
0244:             */
0245:            public void debugSetWorkContour(AbstractContour contour) {
0246:                this .workContour = contour;
0247:            }
0248:
0249:            /**
0250:             * Accessor for the assignment's delay
0251:             * @return delay
0252:             */
0253:            public long getDelay() {
0254:                return delayable.getDelay();
0255:            }
0256:
0257:            void setDelay(long delay) {
0258:                if (delay > 0)
0259:                    System.out.println("delay "
0260:                            + new java.util.Date(getStart())
0261:                            + new java.util.Date(getTaskStart()));
0262:
0263:                delayable = new DelayableImpl(delay, delayable
0264:                        .getLevelingDelay());
0265:            }
0266:
0267:            public long getLevelingDelay() {
0268:                return delayable.getLevelingDelay();
0269:            }
0270:
0271:            void setLevelingDelay(long levelingDelay) {
0272:                delayable = new DelayableImpl(delayable.getDelay(),
0273:                        levelingDelay);
0274:            }
0275:
0276:            public long calcTotalDelay() {
0277:                return delayable.calcTotalDelay();
0278:            }
0279:
0280:            void setContour(Object type, Collection bucketList) {
0281:                AbstractContourBucket[] contour = new AbstractContourBucket[bucketList
0282:                        .size()];
0283:                bucketList.toArray(contour);
0284:                setContour(type, contour);
0285:
0286:            }
0287:
0288:            void setContour(Object type, AbstractContourBucket[] buckets) {
0289:                if (type == HasTimeDistributedData.WORK) {
0290:                    workContour = PersonalContour.getInstance(buckets);
0291:                } else if (type == HasTimeDistributedData.COST) {
0292:                    costContour = PersonalContour.getInstance(buckets);
0293:                }
0294:            }
0295:
0296:            /**
0297:             * @return Returns the requestDemandType.
0298:             */
0299:            public int getRequestDemandType() {
0300:                return requestDemandType;
0301:            }
0302:
0303:            void setRequestDemandType(int requestDemandType) {
0304:                this .requestDemandType = requestDemandType;
0305:
0306:            }
0307:
0308:            void setWorkContour(AbstractContour contour) {
0309:                this .workContour = contour;
0310:            }
0311:
0312:            /**
0313:             * @param duration The duration to set.
0314:             */
0315:            void adjustRemainingDuration(long newRemainingDuration) {
0316:                if (newRemainingDuration < 0)
0317:                    newRemainingDuration = 0; // just in case
0318:                if (getUnits() == 0) // take care of degenerate case
0319:                    newRemainingDuration = 0;
0320:
0321:                long actualDuration = getActualDuration();
0322:                long d = newRemainingDuration + actualDuration;
0323:                if (actualDuration > 0 && !workContour.isPersonal()) // because the remaining might not have same contour
0324:                    workContour = PersonalContour.makePersonal(workContour,
0325:                            getDuration()); //use previous duration
0326:                workContour = workContour.adjustDuration(d, actualDuration); // allow a personal contour to adjust itself
0327:                d = workContour.calcTotalBucketDuration(d); // it is possible that the contour is shorter because we have eliminated a bucket at the end which is after empty time.  The empty time must be removed too
0328:                setDuration(d);
0329:            }
0330:
0331:            /**
0332:             * @param units The units to set.
0333:             */
0334:            void adjustRemainingUnits(double newUnits) {
0335:                workContour = workContour.adjustUnits(newUnits / getUnits(),
0336:                        getActualDuration()); // allow a personal contour to adjust itself
0337:                setUnits(newUnits);
0338:            }
0339:
0340:            //this version has bugs. I have reverted to the older version below
0341:
0342:            //	void adjustRemainingWork(double multiplier) {
0343:            //		long dur;
0344:            //		boolean fixedDuration = ((NormalTask)getTask()).getSchedulingRule() == FixedDuration.getInstance();
0345:            //		if (!getResource().isLabor())
0346:            //			System.out.println("mater " + multiplier);
0347:            //		AbstractContour newContour = workContour;
0348:            //		if (fixedDuration)
0349:            //			newContour = workContour.adjustUnits(multiplier, getActualDuration());
0350:            //		else
0351:            //			newContour = workContour.contourAdjustWork(multiplier, getActualDuration());
0352:            //		if (workContour != newContour) { // adjust the work contour - the case of a personal contour
0353:            //			workContour = newContour; // if contour was changed
0354:            //			dur =workContour.calcTotalBucketDuration(getDuration()); // cannot perform simple multiplication of duration because non-work periods are NOT multiplied
0355:            //		} else {
0356:            //			dur = (long) (getActualDuration() + getRemainingDuration() * multiplier);
0357:            //		}
0358:            //		if (fixedDuration)
0359:            //			setUnits(getUnits() * multiplier);
0360:            //		else
0361:            //			setDuration(dur);
0362:            //	}
0363:
0364:            void adjustRemainingWork(double multiplier) {
0365:                long dur;
0366:
0367:                AbstractContour newContour = workContour.contourAdjustWork(
0368:                        multiplier, getActualDuration());
0369:                if (workContour != newContour) { // adjust the work contour - the case of a personal contour
0370:                    workContour = newContour; // if contour was changed
0371:                    dur = workContour.calcTotalBucketDuration(getDuration()); // cannot perform simple multiplication of duration because non-work periods are NOT multiplied
0372:                } else {
0373:                    dur = (long) (getActualDuration() + getRemainingDuration()
0374:                            * multiplier);
0375:                }
0376:                setDuration(dur);
0377:                setUnits(getUnits() / multiplier);
0378:            }
0379:
0380:            /**
0381:             * MSProject displays duration as only the working duration except in fixed duration tasks.
0382:             * @return duration with non-work periods excluded
0383:             */
0384:            long calcWorkingDuration() {
0385:                return workContour.calcWorkingBucketDuration(getDuration());
0386:            }
0387:
0388:            /**
0389:             * Allow setting of working duration. MSProject displays working duration (excludes non-work intervals) except when
0390:             * task type is fixed duration, in which case it shows duration with non-work intervals
0391:             * @param newWorkingDuration
0392:             */
0393:            void adjustWorkingDuration(long newWorkingDuration) {
0394:                adjustRemainingDuration(getDuration()
0395:                        + (newWorkingDuration - calcWorkingDuration()));
0396:            }
0397:
0398:            /**
0399:             * @return Returns the schedule.
0400:             */
0401:            TaskSchedule getTaskSchedule() {
0402:                if (taskSchedule == null)
0403:                    return getTask().getCurrentSchedule();
0404:                return taskSchedule;
0405:            }
0406:
0407:            TaskSchedule getTaskScheduleOfAssignment() {
0408:                return taskSchedule;
0409:            }
0410:
0411:            void convertToBaselineAssignment(boolean useDefaultCalendar) {
0412:                try {
0413:                    if (useDefaultCalendar)
0414:                        baselineCalendar = CalendarService.getInstance()
0415:                                .getDefaultInstance();
0416:                    else
0417:                        baselineCalendar = (WorkingCalendar) getEffectiveWorkCalendar()
0418:                                .clone();
0419:                } catch (CloneNotSupportedException e) {
0420:                    // TODO Auto-generated catch block
0421:                    e.printStackTrace();
0422:                }
0423:            }
0424:
0425:            boolean isBaseline() {
0426:                return baselineCalendar != null;
0427:            }
0428:
0429:            public WorkCalendar getEffectiveWorkCalendar() {
0430:                if (actualExceptionsCalendar != null)
0431:                    return actualExceptionsCalendar;
0432:                if (baselineCalendar != null)
0433:                    return baselineCalendar;
0434:                Resource resource = getResource();
0435:                Task task = getTask();
0436:                if (((NormalTask) task).isIgnoreResourceCalendar()
0437:                        || isInvalidIntersectionCalendar()
0438:                        || resource.getEffectiveWorkCalendar() == null)
0439:                    return task.getEffectiveWorkCalendar();
0440:                // if no task calendar, or calendar is invalid due to empty intersection of task and resource calendars
0441:                if (task.getWorkCalendar() == null)
0442:                    return resource.getEffectiveWorkCalendar();
0443:
0444:                if (intersectionCalendar == null) {
0445:                    try {
0446:                        intersectionCalendar = ((WorkingCalendar) task
0447:                                .getEffectiveWorkCalendar())
0448:                                .intersectWith((WorkingCalendar) resource
0449:                                        .getEffectiveWorkCalendar());
0450:                    } catch (InvalidCalendarIntersectionException e) {
0451:                        intersectionCalendar = WorkingCalendar.INVALID_INTERSECTION_CALENDAR;
0452:                        Alert.error(Messages
0453:                                .getString("Message.invalidIntersection"));
0454:                        return task.getEffectiveWorkCalendar();
0455:                    }
0456:                }
0457:                return intersectionCalendar;
0458:                // need to use intersection work calendar
0459:            }
0460:
0461:            public boolean isInvalidIntersectionCalendar() {
0462:                return intersectionCalendar == WorkingCalendar.INVALID_INTERSECTION_CALENDAR;
0463:            }
0464:
0465:            /**
0466:             * @return Returns the task.
0467:             */
0468:            Task getTask() {
0469:                return task;
0470:            }
0471:
0472:            /**
0473:             * The assignment start is calculated like this:
0474:             * Get the task start. 
0475:             * If the assignment is not started, use the task's dependency date if it's later than the start
0476:             * Add in any delay
0477:             */
0478:            public long getStart() {
0479:                long delay = this .calcTotalDelay();
0480:                TaskSchedule ts = getTaskSchedule();
0481:                long s = ts.getStart();
0482:                if (percentComplete == 0) { // if no completion, use task dependency date if needed
0483:                    long d = ts.getDependencyDate();
0484:                    if (d > s && !task.startsBeforeProject())
0485:                        s = d;
0486:                }
0487:                if (delay > 0)
0488:                    s = getEffectiveWorkCalendar().add(s, delay, false); // use later time
0489:                //TODO check if above should use task calendar or assignment calendar
0490:                return s;
0491:            }
0492:
0493:            /**
0494:             * Sets the assignment start. Since the assigment start is an offset (usually 0) from task start, setting a later start means
0495:             * setting a delay for the assignment.  Also, any levelling delay is cleared
0496:             */
0497:            public void setStart(long start) {
0498:                if (start > getTaskStart()) {
0499:                    long delay = getEffectiveWorkCalendar().compare(start,
0500:                            getTaskStart(), false);
0501:                    setLevelingDelay(0);
0502:                    setDelay(delay);
0503:                }
0504:            }
0505:
0506:            long getSplitDuration() {
0507:                long dependencyStart = getDependencyStart();
0508:                if (dependencyStart == 0
0509:                        || getDependencyStart() == getTaskStart())
0510:                    return 0;
0511:
0512:                long remainingStart = Math.max(getTaskStart(), getStop());
0513:                return Math.max(0, getEffectiveWorkCalendar().compare(
0514:                        getDependencyStart(), remainingStart, false));
0515:            }
0516:
0517:            //		// if need to split
0518:            //		if (actualDuration >0 && actualDuration != durationMillis) {
0519:            //			long start = getStart();
0520:            //			long split = getTaskSchedule().getResume();
0521:            //			if (split > start) {
0522:            //				long splitDuration = task.getEffectiveWorkCalendar().compare(split,start,false); //TODO move this elsewhere
0523:            //				finish = getEffectiveWorkCalendar().add(finish,splitDuration,true);
0524:            //		}
0525:            //		}
0526:            //		return finish;
0527:
0528:            long getFinish() {
0529:                return getEnd();
0530:
0531:                //		// if need to split
0532:                //		if (actualDuration >0 && actualDuration != durationMillis) {
0533:                //			long start = getStart();
0534:                //			long split = getTaskSchedule().getResume();
0535:                //			if (split > start) {
0536:                //				long splitDuration = task.getEffectiveWorkCalendar().compare(split,start,false); //TODO move this elsewhere
0537:                //				finish = getEffectiveWorkCalendar().add(finish,splitDuration,true);
0538:                //		}
0539:                //		}
0540:                //		return finish;
0541:            }
0542:
0543:            /**
0544:             * @return Returns the resource.
0545:             */
0546:            Resource getResource() {
0547:                return resource;
0548:            }
0549:
0550:            AbstractContourBucket[] getContour(Object type) {
0551:                return ((type == HasTimeDistributedData.COST) ? costContour
0552:                        : workContour).getContourBuckets();
0553:            }
0554:
0555:            /**
0556:             * @return Returns the costContour.
0557:             */
0558:            AbstractContour getCostContour() {
0559:                return costContour;
0560:            }
0561:
0562:            /**
0563:             * @return Returns the costRateIndex.
0564:             */
0565:            int getCostRateIndex() {
0566:                return costRateIndex;
0567:            }
0568:
0569:            void setCostRateIndex(int costRateIndex) {
0570:                this .costRateIndex = costRateIndex;
0571:            }
0572:
0573:            Assignment getBaselineAssignment() {
0574:                if (task == null) // case when just loading assignment in timesheet
0575:                    return null;
0576:                return task.getBaselineAssignment(resource);
0577:            }
0578:
0579:            Assignment getBaselineAssignment(Object baseline,
0580:                    boolean createIfDoestExist) {
0581:                if (task == null) // case when just loading assignment in timesheet
0582:                    return null;
0583:                return task.getBaselineAssignment(resource, baseline,
0584:                        createIfDoestExist);
0585:            }
0586:
0587:            long effectiveBaselineStart() {
0588:                Assignment baselineAssignment = getBaselineAssignment();
0589:                if (baselineAssignment == null)
0590:                    return getStart();
0591:                return baselineAssignment.getStart();
0592:            }
0593:
0594:            long effectiveBaselineStart(Object baseline) {
0595:                Assignment baselineAssignment = getBaselineAssignment(baseline,
0596:                        false);
0597:                if (baselineAssignment == null)
0598:                    return getStart();
0599:                return baselineAssignment.getStart();
0600:            }
0601:
0602:            long effectiveBaselineFinish(Object baseline) {
0603:                Assignment baselineAssignment = getBaselineAssignment(baseline,
0604:                        false);
0605:                if (baselineAssignment == null)
0606:                    return getFinish();
0607:                return baselineAssignment.getFinish();
0608:            }
0609:
0610:            //	private void adjustActualDurationAndContour(long newActualDuration, long stop, long splitDuration) {
0611:            //		long oldActualDuration = actualDuration;
0612:            //		newActualDuration = Duration.millis(newActualDuration);
0613:            //		if (newActualDuration == oldActualDuration) // if no change do nothing
0614:            //			return;
0615:            //		actualDuration = newActualDuration; // need to set in now since it mayb be used below inside bucketsBetweenDurations
0616:            //		
0617:            //		if (newActualDuration == 0) { // if setting to 0 actuals
0618:            //			return;
0619:            //		}
0620:            //		
0621:            //		if (oldActualDuration > newActualDuration) {// trim off end
0622:            //			actualWorkContour = actualWorkContour.adjustDuration(newActualDuration); // simple, just truncate it.
0623:            //		} else {
0624:            //System.out.println("Stop "+ new Date(stop) + " duration" + DurationFormat.format(stopResumeDuration));			
0625:            //			ArrayList list;
0626:            //			if (actualWorkContour != null) // see if there are actuals
0627:            //				list = actualWorkContour.toArrayList(); // copy current actual contour to an array list
0628:            //			else // in case there are no actuals yet
0629:            //				list = new ArrayList();
0630:            //			if (actualDuration > durationMillis) { // if made longer than planned duration, adjust planned duration
0631:            //				durationMillis = actualDuration;
0632:            //				workContour = workContour.adjustDuration(durationMillis);
0633:            //			}
0634:            //			list.addAll(workContour.bucketsBetweenDurations(oldActualDuration, newActualDuration, durationMillis)); // add from work contour
0635:            //			actualWorkContour = PersonalContour.getInstance(list); // set new contour that combines the two above
0636:            //			//insert gap for stop/resume
0637:            //System.out.println("contour before\n" + actualWorkContour.toString(newActualDuration));
0638:            //			if (stopResumeDuration > 0) {
0639:            //				actualWorkContour = ((PersonalContour)actualWorkContour).insertBucket(stop,PersonalContourBucket.getInstance(stopResumeDuration,0.0));
0640:            //				System.out.println("contour after\n" + actualWorkContour.toString(newActualDuration));
0641:            //			}
0642:            ////			System.out.println("new actual contour" + actualWorkContour.toString(newActualDuration));
0643:            //		}
0644:            //	}
0645:
0646:            /** returns the amount of effort that the resource as available to work on the assignment 
0647:             * 
0648:             * @return
0649:             */
0650:            long getResourceAvailability() {
0651:                WorkCalendar cal = resource.getEffectiveWorkCalendar();
0652:                if (cal == null)
0653:                    cal = task.getOwningProject().getEffectiveWorkCalendar();
0654:                //TODO implement time-scaled availability
0655:                return (long) resource.getMaximumUnits()
0656:                        * cal.compare(getFinish(), getStart(), false);
0657:            }
0658:
0659:            void shift(long start, long end, long shiftDuration) {
0660:                PersonalContour newContour = PersonalContour.makePersonal(
0661:                        workContour, getDuration());
0662:                newContour = newContour.shift(start, end, shiftDuration);
0663:                workContour = newContour;
0664:                if (workContour.isPersonal())
0665:                    duration = workContour.calcTotalBucketDuration(duration);
0666:                checkForNegativeDuration();
0667:            }
0668:
0669:            // in rare circumstances duration would go negative. prevent this
0670:            private void checkForNegativeDuration() {
0671:                if (duration < 0) {
0672:                    if (getDelay() > 0) // clear out any delay
0673:                        setDelay(0);
0674:                    duration = 0;
0675:                }
0676:
0677:            }
0678:
0679:            void extend(long end, long extendDuration) {
0680:                workContour = workContour.extend(end, extendDuration);
0681:                if (workContour.isPersonal())
0682:                    duration = workContour.calcTotalBucketDuration(duration);
0683:                else
0684:                    duration += extendDuration;
0685:                checkForNegativeDuration();
0686:            }
0687:
0688:            /**
0689:             * @param startOffset
0690:             * @param extendDuration
0691:             */
0692:            public void extendBefore(long startOffset, long extendDuration) {
0693:                workContour = workContour.extendBefore(startOffset,
0694:                        extendDuration);
0695:                if (workContour.isPersonal())
0696:                    duration = workContour.calcTotalBucketDuration(duration);
0697:                else
0698:                    duration -= extendDuration;
0699:                checkForNegativeDuration();
0700:
0701:            }
0702:
0703:            /* (non-Javadoc)
0704:             * @see com.projity.pm.scheduling.Schedule#split(java.lang.Object, long, long)
0705:             */
0706:            public void split(Object eventSource, long from, long to) {
0707:                System.out
0708:                        .println("split should not be called for AssignmentDetail");
0709:            }
0710:
0711:            public void removeEmptyBucketAtDuration(long atDuration) {
0712:                if (workContour.isPersonal()) {
0713:                    workContour = ((PersonalContour) workContour)
0714:                            .removeEmptyBucketAtDuration(atDuration);
0715:                }
0716:            }
0717:
0718:            MutableInterval getRangeThatIntervalCanBeMoved(long start, long end) {
0719:                return workContour.getRangeThatIntervalCanBeMoved(start, end);
0720:            }
0721:
0722:            /* (non-Javadoc)
0723:             * @see com.projity.pm.calendar.HasCalendar#setWorkCalendar(com.projity.pm.calendar.WorkCalendar)
0724:             */
0725:            public void setWorkCalendar(WorkCalendar workCalendar) {
0726:            }
0727:
0728:            /* (non-Javadoc)
0729:             * @see com.projity.pm.calendar.HasCalendar#getWorkCalendar()
0730:             */
0731:            public WorkCalendar getWorkCalendar() {
0732:                return getEffectiveWorkCalendar();
0733:            }
0734:
0735:            /**
0736:             * Use the start dependency in the task schedule
0737:             */
0738:            public long getDependencyStart() {
0739:                return getTaskSchedule().getRemainingDependencyDate();
0740:            }
0741:
0742:            long getTaskStart() {
0743:                return getTaskSchedule().getStart();
0744:            }
0745:
0746:            public void setDuration(long duration) {
0747:                long stop = getStop(); // need to preserve completion
0748:                if (Duration.millis(duration) < 0)
0749:                    duration = 0; // just in case
0750:                this .duration = duration;
0751:                setStop(stop);
0752:            }
0753:
0754:            public long getActualFinish() {
0755:                if (getPercentComplete() < 1.0)
0756:                    return 0;
0757:                return getEnd();
0758:                //    	return getEffectiveWorkCalendar().add(getStop(),getRemainingDuration(),false);
0759:            }
0760:
0761:            /**
0762:             * Sets the actual finish.  This entails setting the end, the actual start (in case it's not set yet), the duration
0763:             * and the actual duration.
0764:             */
0765:            public void setActualFinish(long actualFinish) {
0766:                setEnd(actualFinish);
0767:                setPercentComplete(1.0D);
0768:            }
0769:
0770:            public long getEnd() {
0771:                WorkCalendar cal = getEffectiveWorkCalendar();
0772:                long finish = cal.add(getStart(), getDuration(), true);
0773:                if (getPercentComplete() > 0.0 && getPercentComplete() < 1.0) {
0774:                    long dependencyStart = getDependencyStart();
0775:                    if (dependencyStart > getTaskStart()) {
0776:                        long splitDuration = cal.compare(dependencyStart,
0777:                                getTaskStart(), false);
0778:                        finish = cal.add(finish, splitDuration, true);
0779:                    }
0780:                }
0781:                return finish;
0782:            }
0783:
0784:            public void setEnd(long end) {
0785:                long remaining = getRemainingDuration();
0786:                long oldEnd = getEnd();
0787:                if (oldEnd == end)
0788:                    return;
0789:                long stop = getStop();
0790:                if (stop > end)
0791:                    end = stop;
0792:                long durationDifference = getEffectiveWorkCalendar().compare(
0793:                        end, oldEnd, false);
0794:                //		if (stop != 0 && end > stop) {
0795:                //			durationDifference -= getSplitDuration();
0796:                //			System.out.println("split duration is " + DurationFormat.format(getSplitDuration()));
0797:                //		}
0798:                //System.out.println("duration difference " + DurationFormat.format(durationDifference));
0799:                //System.out.println("old end " + new Date(oldEnd) + " end " + new Date(end));
0800:                long newRemaining = remaining + durationDifference;
0801:                if (newRemaining < 0) // test to avoid negative duration
0802:                    newRemaining = 0L;
0803:                adjustRemainingDuration(newRemaining);
0804:
0805:                //		long splitDuration = 0; //getSplitDuration();
0806:                //		durationActive += durationDifference + splitDuration;
0807:                //		durationSpan += durationDifference + splitDuration;
0808:
0809:                setStop(stop);
0810:                //		long splitDuration = getSplitDuration();
0811:                //		
0812:                //		if (splitDuration >= 0) {
0813:                //			durationSpan = durationActive + splitDuration;
0814:                //		}
0815:
0816:            }
0817:
0818:            public long getActualStart() {
0819:                if (percentComplete == 0)
0820:                    return 0;
0821:                return getStart();
0822:            }
0823:
0824:            public void setActualStart(long actualStart) {
0825:                setStart(actualStart);
0826:                if (percentComplete == 0)
0827:                    setPercentComplete(INSTANT_COMPLETION);
0828:            }
0829:
0830:            /**
0831:             * @return Returns the actualDuration.
0832:             */
0833:            public long getActualDuration() {
0834:                return DateTime.closestDate(getDuration()
0835:                        * getPercentComplete());
0836:            }
0837:
0838:            /**
0839:             * @param actualDuration The actualDuration to set. Will fix actual start if needed
0840:             */
0841:            public void setActualDuration(long actualDuration) {
0842:                if (getDuration() > 0)
0843:                    setPercentComplete(((double) actualDuration)
0844:                            / getDuration());
0845:            }
0846:
0847:            public void clearDuration() {
0848:                setDuration(0);
0849:            }
0850:
0851:            /* (non-Javadoc)
0852:             * @see com.projity.pm.scheduling.Schedule#moveInterval(java.lang.Object, long, long, com.projity.pm.scheduling.ScheduleInterval)
0853:             */
0854:            public void moveInterval(Object eventSource, long start, long end,
0855:                    ScheduleInterval oldInterval, boolean isChild) {
0856:                throw new RuntimeException(
0857:                        "cannot call moveInterval for an AssignmentDetail");
0858:            }
0859:
0860:            public void moveRemainingToDate(long date) {
0861:                throw new RuntimeException(
0862:                        "cannot call moveRemainingToDate for an AssignmentDetail");
0863:            }
0864:
0865:            /* (non-Javadoc)
0866:             * @see com.projity.pm.scheduling.Schedule#consumeIntervals(com.projity.functor.IntervalConsumer)
0867:             */
0868:            public void consumeIntervals(IntervalConsumer consumer) {
0869:                throw new RuntimeException(
0870:                        "cannot call consumeIntervals for an AssignmentDetail");
0871:            }
0872:
0873:            public long getElapsedDuration() {
0874:                return Math.round(getEffectiveWorkCalendar().compare(getEnd(),
0875:                        getStart(), true)
0876:                        * CalendarOption.getInstance()
0877:                                .getFractionOfDayThatIsWorking());
0878:            }
0879:
0880:            public long getRemainingDuration() {
0881:                return DateTime
0882:                        .closestDate((getDuration() * (1.0D - percentComplete)));
0883:            }
0884:
0885:            public void setRemainingDuration(long remainingDuration) {
0886:                //		if (getDuration() > 0) {
0887:                //			double actual = (percentComplete * getDuration());
0888:                //			long total = (long) (actual + remainingDuration);
0889:                //			setDuration(total);
0890:                //			if (actual != 0.0D)
0891:                //				setPercentComplete(actual / total);
0892:                //			
0893:                //		}
0894:                setPercentComplete(1.0D - ((double) remainingDuration)
0895:                        / getDuration());
0896:            }
0897:
0898:            /**
0899:             *  returns calculated completed date.  If there is no advancement, the date is start date
0900:             * @return
0901:             */
0902:            public long getStop() {
0903:                long stop = 0;
0904:                if (percentComplete > 0.0
0905:                        && percentComplete != INSTANT_COMPLETION) {
0906:                    stop = getEffectiveWorkCalendar().add(getStart(),
0907:                            getActualDuration(), true); // use earlier date
0908:                }
0909:                return stop;
0910:            }
0911:
0912:            public void setDependencyStart(long dependencyStart) {
0913:                throw new RuntimeException(
0914:                        "cannot call setDependencyStart for an AssignmentDetail");
0915:            }
0916:
0917:            /**
0918:             * Remove any filler periods in the contour after a certain date. This is used in the special case
0919:             * of uncompleting a task.  There might be filler periods in the contour due to a task dependency
0920:             * that pushed out remaining work that was subsequently completed.  When uncompleting, the remaining
0921:             * work needs to have this filler period removed, otherwise there will be an extra delay.
0922:             * @param stop Stop date
0923:             */
0924:            void removeFillerAfter(long stop) {
0925:                long stopDuration = getEffectiveWorkCalendar().compare(stop,
0926:                        getStart(), false);
0927:                workContour = workContour.removeFillerAfter(stopDuration);
0928:            }
0929:
0930:            public void setStop(long stop) {
0931:                if (stop < getStart()) // if before start ignore
0932:                    return;
0933:                if (percentComplete == 1.0 && stop >= getActualFinish()) // adjust to be no later than actual finish
0934:                    return;
0935:
0936:                //		System.out.println("setting stop to  " + new java.util.Date(stop));
0937:
0938:                if (stop <= getStart()) { // if getting rid of completion
0939:                    setPercentComplete(0);
0940:                } else {
0941:                    long actualDuration = getEffectiveWorkCalendar().compare(
0942:                            stop, getStart(), false);
0943:                    //			if (getDependencyStart() >= getStop() && getDependencyStart() < stop) {// if setting stop incorporates split due to dependency
0944:                    //				actualDuration -= getSplitDuration();
0945:                    //			}
0946:                    //	duration = getWorkContour().calcTotalBucketDuration(0);
0947:
0948:                    long d = getDuration();
0949:                    if (d != 0)
0950:                        setPercentComplete(((double) actualDuration) / d);
0951:                }
0952:            }
0953:
0954:            /* (non-Javadoc)
0955:             * @see com.projity.pm.scheduling.Schedule#getResume()
0956:             */
0957:            public long getResume() {
0958:                long resume = 0;
0959:
0960:                if (percentComplete > 0.0)
0961:                    resume = getEffectiveWorkCalendar().add(getStart(),
0962:                            getActualDuration(), false); // use later date
0963:                resume = Math.max(resume, getDependencyStart());
0964:                if (workContour.isPersonal()) {
0965:
0966:                }
0967:
0968:                return resume;
0969:            }
0970:
0971:            /* (non-Javadoc)
0972:             * @see com.projity.pm.scheduling.Schedule#setResume(long)
0973:             */
0974:            public void setResume(long resume) {
0975:                long oldResume = getResume();
0976:                long shift = getEffectiveWorkCalendar().compare(resume,
0977:                        oldResume, false);
0978:                if (shift == 0)
0979:                    return;
0980:
0981:                if (resume > oldResume) {
0982:
0983:                }
0984:                //
0985:                //		setStop(stop);
0986:
0987:            }
0988:
0989:            long extractDelay() {
0990:                return workContour.extractDelay();
0991:            }
0992:
0993:            private static short DEFAULT_VERSION = 1;
0994:            private short version = DEFAULT_VERSION;
0995:
0996:            private void writeObject(ObjectOutputStream s) throws IOException {
0997:                workContourType = workContour.getType();
0998:                costContourType = costContour.getType();
0999:                s.defaultWriteObject();
1000:                rate.serialize(s);
1001:                //delayable
1002:                s.writeLong(delayable.getDelay());
1003:                s.writeLong(delayable.getLevelingDelay());
1004:                //personnal contours
1005:                if (workContourType == CONTOURED)
1006:                    s.writeObject(workContour.getContourBuckets());
1007:                if (costContourType == CONTOURED)
1008:                    s.writeObject(costContour.getContourBuckets());
1009:
1010:                if (version >= 1) {
1011:                    s.writeBoolean(taskSchedule == null);
1012:                    if (taskSchedule != null)
1013:                        taskSchedule.serialize(s);
1014:                }
1015:            }
1016:
1017:            private void readObject(ObjectInputStream s) throws IOException,
1018:                    ClassNotFoundException {
1019:                s.defaultReadObject();
1020:                rate = Rate.deserialize(s);
1021:                //delayable
1022:                delayable = new DelayableImpl(s.readLong(), s.readLong());
1023:                //personnal contours
1024:                if (workContourType == CONTOURED) {
1025:                    //	    	try{
1026:                    workContour = PersonalContour
1027:                            .getInstance((AbstractContourBucket[]) s
1028:                                    .readObject());
1029:                    //	    	}catch(Exception e){
1030:                    //	    		workContour = StandardContour.getStandardContour(workContourType);
1031:                    //	    	}
1032:                } else
1033:                    workContour = StandardContour
1034:                            .getStandardContour(workContourType);
1035:                if (costContourType == CONTOURED) {
1036:                    //	    	try{
1037:                    costContour = PersonalContour
1038:                            .getInstance((AbstractContourBucket[]) s
1039:                                    .readObject());
1040:                    //	    	}catch(Exception e){
1041:                    //	    		costContour = StandardContour.getStandardContour(costContourType);
1042:                    //	    	}
1043:                } else
1044:                    costContour = StandardContour
1045:                            .getStandardContour(costContourType);
1046:
1047:                if (version >= 1) {
1048:                    boolean nullSchedule = s.readBoolean();
1049:                    if (!nullSchedule) {
1050:                        taskSchedule = TaskSchedule.deserialize(s);
1051:                        taskSchedule.setTask(task);
1052:                    }
1053:                }
1054:                version = DEFAULT_VERSION;
1055:
1056:            }
1057:
1058:            public Object clone() {
1059:                //		try {
1060:                /*
1061:                private transient Rate rate = new Rate(1.0D); // units can never be 0!!!
1062:                double percentComplete = 0;
1063:                long duration = 0;
1064:
1065:                //	private Schedule schedule = new ScheduleImpl(this);
1066:                
1067:                //			private long durationMillis; // This includes non-working duration (if personal contour).  See also calcWorkingDuration()
1068:                //			long actualDuration = 0;
1069:                
1070:                //TODO There is some stuff to figure out regarding contouring remaining work.  If you change the contour, Project applies
1071:                // the entire contour to the remaining work.  If you keep completing and change the contour again, project keeps the
1072:                // different contours active to where they were applied.  The weird thing is that if you uncomplete the task, the work still
1073:                // shows the various contours, even if the current contour is flat.  This is a bug.
1074:                
1075:                
1076:                private int workContourType; // these are only used for serializing the contour.  They are not "up to date" otherwise
1077:                private int costContourType;
1078:                private transient AbstractContour workContour = StandardContour.FLAT_CONTOUR;
1079:                private transient AbstractContour costContour = StandardContour.FLAT_CONTOUR;
1080:
1081:                private transient WorkCalendar actualExceptionsCalendar; // for when user enters actual work during non-work time of calendar
1082:                private transient WorkingCalendar intersectionCalendar = null;
1083:                private transient TaskSchedule taskSchedule = null;
1084:
1085:                private transient Resource resource;
1086:                private transient Task task;
1087:                private transient Delayable delayable;
1088:                private int requestDemandType = RequestDemandType.NONE;
1089:                private int costRateIndex = CostRateTables.DEFAULT;
1090:                private long overtimeWork = 0; // allowed overtime that is evenly distributed across contour
1091:                
1092:                private WorkingCalendar baselineCalendar = null; // only applies if this is a baseline
1093:                 */
1094:                AssignmentDetail a = new AssignmentDetail();
1095:                a.rate = (Rate) rate.clone();
1096:                a.percentComplete = percentComplete;
1097:                a.duration = duration;
1098:                a.workContour = (AbstractContour) workContour.clone();
1099:                a.costContour = costContour; //(AbstractContour)costContour.clone();
1100:                a.actualExceptionsCalendar = actualExceptionsCalendar; //(WorkCalendar) actualExceptionsCalendar.clone();
1101:                a.intersectionCalendar = intersectionCalendar; // (WorkingCalendar) intersectionCalendar.clone();
1102:                a.taskSchedule = taskSchedule; // copy not clone
1103:                a.resource = resource;
1104:                a.task = task;
1105:                a.delayable = (Delayable) ((DelayableImpl) delayable).clone();
1106:                a.requestDemandType = requestDemandType;
1107:                a.costRateIndex = costRateIndex;
1108:                a.overtimeWork = overtimeWork;
1109:                a.baselineCalendar = baselineCalendar;
1110:                return a;
1111:                //		}
1112:                //		catch (CloneNotSupportedException e) {
1113:                //			throw new InternalError();
1114:                //		}
1115:            }
1116:
1117:            public long getOvertimeWork() {
1118:                return overtimeWork;
1119:            }
1120:
1121:            public void setResource(Resource resource) {
1122:                this .resource = resource;
1123:            }
1124:
1125:            public void setTask(Task task) {
1126:                this .task = task;
1127:            }
1128:
1129:            boolean hasDuration() {
1130:                return duration != 0;
1131:            }
1132:
1133:            public final boolean isTemporal() {
1134:                return rate.getTimeUnit() != TimeUnit.NON_TEMPORAL;
1135:            }
1136:
1137:            /**
1138:             * @param timeUnit
1139:             */
1140:            void setRateUnit(int timeUnit) {
1141:                rate.setTimeUnit(timeUnit);
1142:            }
1143:
1144:            public final Rate getRate() {
1145:                return rate;
1146:            }
1147:
1148:            public final void setRate(Rate rate) {
1149:                this .rate = rate;
1150:            }
1151:
1152:            public void invalidateAssignmentCalendar() {
1153:                if (intersectionCalendar != null)
1154:                    intersectionCalendar = null;
1155:                if (actualExceptionsCalendar != null)
1156:                    actualExceptionsCalendar.invalidate();
1157:            }
1158:
1159:            /* (non-Javadoc)
1160:             * @see com.projity.pm.calendar.HasCalendar#invalidateCalendar()
1161:             */
1162:            public Document invalidateCalendar() {
1163:                return task.getOwningProject();
1164:
1165:            }
1166:
1167:            public boolean isJustModified() {
1168:                Task task = getTask();
1169:                if (task == null)
1170:                    return false;
1171:                else
1172:                    return task.isJustModified();
1173:            }
1174:
1175:            public void addCalendarTime(long start, long end) {
1176:                if (actualExceptionsCalendar == null) {
1177:                    WorkCalendar base = getEffectiveWorkCalendar();
1178:                    actualExceptionsCalendar = CalendarService.getInstance()
1179:                            .getStandardBasedInstance();
1180:                    try {
1181:                        actualExceptionsCalendar.setBaseCalendar(base);
1182:                    } catch (CircularDependencyException e) {
1183:                        // TODO Auto-generated catch block
1184:                        e.printStackTrace();
1185:                    }
1186:                }
1187:                actualExceptionsCalendar.addCalendarTime(start, end);
1188:            }
1189:
1190:            public void setComplete(boolean complete) {
1191:                ScheduleUtil.setComplete(this , complete);
1192:            }
1193:
1194:            public boolean isComplete() {
1195:                return getPercentComplete() == 1.0D;
1196:            }
1197:
1198:            public final long getEarliestStop() {
1199:                return getStop();
1200:            }
1201:
1202:            public final long getCompletedThrough() {
1203:                return getStop();
1204:            }
1205:
1206:            public void setCompletedThrough(long completedThrough) {
1207:                setStop(completedThrough);
1208:            }
1209:
1210:            public Object backupDetail() {
1211:                return clone();
1212:            }
1213:
1214:            public void restoreDetail(Object source, Object detail,
1215:                    boolean isChild) {
1216:            }
1217:
1218:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.