Source Code Cross Referenced for TaskSchedule.java in  » Project-Management » OpenProj » com » projity » pm » criticalpath » 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.criticalpath 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:        The contents of this file are subject to the Common Public Attribution License 
003:        Version 1.0 (the "License"); you may not use this file except in compliance with 
004:        the License. You may obtain a copy of the License at 
005:        http://www.projity.com/license . The License is based on the Mozilla Public 
006:        License Version 1.1 but Sections 14 and 15 have been added to cover use of 
007:        software over a computer network and provide for limited attribution for the 
008:        Original Developer. In addition, Exhibit A has been modified to be consistent 
009:        with Exhibit B.
010:
011:        Software distributed under the License is distributed on an "AS IS" basis, 
012:        WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
013:        specific language governing rights and limitations under the License. The 
014:        Original Code is OpenProj. The Original Developer is the Initial Developer and 
015:        is Projity, Inc. All portions of the code written by Projity are Copyright (c) 
016:        2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018:        Alternatively, the contents of this file may be used under the terms of the 
019:        Projity End-User License Agreeement (the Projity License), in which case the 
020:        provisions of the Projity License are applicable instead of those above. If you 
021:        wish to allow use of your version of this file only under the terms of the 
022:        Projity License and not to allow others to use your version of this file under 
023:        the CPAL, indicate your decision by deleting the provisions above and replace 
024:        them with the notice and other provisions required by the Projity  License. If 
025:        you do not delete the provisions above, a recipient may use your version of this 
026:        file under either the CPAL or the Projity License.
027:
028:        [NOTE: The text of this license may differ slightly from the text of the notices 
029:        in Exhibits A and B of the license at http://www.projity.com/license. You should 
030:        use the latest text at http://www.projity.com/license for your modifications.
031:        You may not remove this license text from the source files.]
032:
033:        Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007 
034:        Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj, 
035:        an open source solution from Projity. Attribution URL: http://www.projity.com 
036:        Graphic Image as provided in the Covered Code as file:  openproj_logo.png with 
037:        alternatives listed on http://www.projity.com/logo
038:
039:        Display of Attribution Information is required in Larger Works which are defined 
040:        in the CPAL as a work which combines Covered Code or portions thereof with code 
041:        not governed by the terms of the CPAL. However, in addition to the other notice 
042:        obligations, all copies of the Covered Code in Executable and Source Code form 
043:        distributed must, as a form of attribution of the original author, include on 
044:        each user interface screen the "OpenProj" logo visible to all users.  The 
045:        OpenProj logo should be located horizontally aligned with the menu bar and left 
046:        justified on the top left of the screen adjacent to the File menu.  The logo 
047:        must be at least 100 x 25 pixels.  When users click on the "OpenProj" logo it 
048:        must direct them back to http://www.projity.com.  
049:         */
050:        package com.projity.pm.criticalpath;
051:
052:        import java.io.IOException;
053:        import java.io.ObjectInputStream;
054:        import java.io.ObjectOutputStream;
055:        import java.util.Collection;
056:        import java.util.Date;
057:        import java.util.Iterator;
058:
059:        import com.projity.datatype.Duration;
060:        import com.projity.grouping.core.Node;
061:        import com.projity.pm.dependency.Dependency;
062:        import com.projity.pm.task.NormalTask;
063:        import com.projity.pm.task.SubProj;
064:        import com.projity.pm.task.Task;
065:
066:        public final class TaskSchedule implements  Cloneable {
067:            public static final int CURRENT = 0;
068:            public static final int EARLY = -1;
069:            public static final int LATE = 1;
070:
071:            //Persisted fields
072:            private double percentComplete = 0D;
073:
074:            // these are calculated, but are persisted anyway for reporting
075:            private long rawDuration;
076:            private long start;
077:            private long finish;
078:
079:            // Calculated fields that are transient
080:            //TODO don't bother serializing these.  When I make them transient, the program hangs
081:            private Task task;
082:            private int type;
083:            private boolean forward = true;
084:            private long dependencyDate = Dependency.NEEDS_CALCULATION;
085:            private long remainingDependencyDate = 0;
086:
087:            public TaskSchedule() {
088:
089:            }
090:
091:            public TaskSchedule(Task task, int type) {
092:                init(task, type);
093:                start = 0;
094:                finish = 0;
095:            }
096:
097:            public void init(Task task, int type) {
098:                this .task = task;
099:                this .type = type;
100:                if (type == EARLY)
101:                    forward = true;
102:                else if (type == LATE)
103:                    forward = false;
104:                dependencyDate = Dependency.NEEDS_CALCULATION;
105:                invalidate();
106:            }
107:
108:            public void initSerialized(Task task, int type) {
109:                this .task = task;
110:                this .type = type;
111:                if (type == EARLY)
112:                    forward = true;
113:                else if (type == LATE)
114:                    forward = false;
115:            }
116:
117:            public void setTask(Task task) {
118:                this .task = task;
119:            }
120:
121:            public void serialize(ObjectOutputStream s) throws IOException {
122:                s.writeDouble(percentComplete);
123:                s.writeLong(rawDuration);
124:                s.writeLong(start);
125:                s.writeLong(finish);
126:            }
127:
128:            //call init to complete initialization
129:            public static TaskSchedule deserialize(ObjectInputStream s)
130:                    throws IOException, ClassNotFoundException {
131:                TaskSchedule t = new TaskSchedule();
132:                t.setPercentComplete(s.readDouble());
133:                t.setRawDuration(s.readLong());
134:                t.setStart(s.readLong());
135:                t.setFinish(s.readLong());
136:                return t;
137:            }
138:
139:            public Object clone() {
140:                try {
141:                    return super .clone();
142:                } catch (CloneNotSupportedException e) {
143:                    throw new InternalError();
144:                }
145:            }
146:
147:            public Object cloneWithTask(Task task) {
148:                TaskSchedule ts = (TaskSchedule) clone();
149:                ts.setTask(task);
150:                ts.invalidate();
151:                return ts;
152:            }
153:
154:            //
155:            //	void copyDatesFrom(TaskSchedule from) {
156:            //		start = from.start;
157:            //		finish = from.finish;
158:            //		if (task.isWbsParent())
159:            //			rawDuration = from.rawDuration;
160:            //		dependencyDate = from.dependencyDate;
161:            //		remainingDependencyDate = from.remainingDependencyDate;
162:            //	}
163:
164:            public long getBegin() {
165:                return forward ? start : -finish;
166:            }
167:
168:            public long getEnd() {
169:                return forward ? finish : -start;
170:            }
171:
172:            public long getWindowBegin() {
173:                return forward ? task.getWindowEarlyStart() : -task
174:                        .getWindowLateFinish();
175:            }
176:
177:            public long getWindowEnd() {
178:                return forward ? task.getWindowEarlyFinish() : -task
179:                        .getWindowLateStart();
180:            }
181:
182:            public void setBegin(long begin) {
183:                if (forward)
184:                    start = begin;
185:                else
186:                    finish = -begin;
187:            }
188:
189:            public void setEnd(long end) {
190:                if (forward)
191:                    finish = end;
192:                else
193:                    start = -end;
194:            }
195:
196:            public long getBeginDependency() {
197:                if (dependencyDate == Dependency.NEEDS_CALCULATION)
198:                    dependencyDate = calcDependencyDate();
199:
200:                return dependencyDate;
201:            }
202:
203:            public final void invalidate() {
204:                start = 0;
205:                finish = 0;
206:                dependencyDate = Dependency.NEEDS_CALCULATION;
207:            }
208:
209:            public void copyDatesAfterClone(TaskSchedule from) {
210:                start = from.start;
211:                finish = from.finish;
212:                dependencyDate = from.dependencyDate;
213:            }
214:
215:            final void invalidateDependencyDate() {
216:                dependencyDate = Dependency.NEEDS_CALCULATION;
217:            }
218:
219:            /**
220:             * @return Returns the percentComplete.
221:             */
222:            public final double getPercentComplete() {
223:                return percentComplete;
224:            }
225:
226:            /**
227:             * @param percentComplete The percentComplete to set.
228:             */
229:            public final void setPercentComplete(double percentComplete) {
230:                this .percentComplete = percentComplete;
231:            }
232:
233:            /**
234:             * @return Returns the rawDuration.
235:             */
236:            public final long getRawDuration() {
237:                return rawDuration;
238:            }
239:
240:            /**
241:             * @param rawDuration The rawDuration to set.
242:             */
243:            public final void setRawDuration(long rawDuration) {
244:                this .rawDuration = rawDuration;
245:
246:            }
247:
248:            private final boolean isLate() {
249:                return type == LATE;
250:            }
251:
252:            public final long getDependencyDate() {
253:                return dependencyDate;
254:            }
255:
256:            public final void setDependencyDate(long dependencyDate) {
257:                this .dependencyDate = dependencyDate;
258:            }
259:
260:            public final long getFinish() {
261:                return finish;
262:            }
263:
264:            public final void setFinish(long finish) {
265:                this .finish = finish;
266:            }
267:
268:            public final long getStart() {
269:                return start;
270:            }
271:
272:            public final void setStart(long start) {
273:                this .start = start;
274:            }
275:
276:            public TaskSchedule getOppositeSchedule() {
277:                return task.getSchedule(forward ? LATE : EARLY);
278:            }
279:
280:            /**
281:             * @return Returns the forward.
282:             */
283:            public final boolean isForward() {
284:                return forward;
285:            }
286:
287:            public void setForward(boolean forward) {
288:                if (this .forward != forward) {
289:                    this .forward = forward;
290:                    long s = start;
291:                    start = -finish;
292:                    finish = -s;
293:                    dependencyDate = -dependencyDate;
294:                    remainingDependencyDate = -remainingDependencyDate;
295:
296:                }
297:            }
298:
299:            /**
300:             * @param begin
301:             */
302:            public final void setRemainingDependencyDate(
303:                    long remainingDependencyDate) {
304:                this .remainingDependencyDate = remainingDependencyDate;
305:            }
306:
307:            /**
308:             * @return Returns the remainingDependencyDate.
309:             */
310:            public final long getRemainingDependencyDate() {
311:                return remainingDependencyDate;
312:            }
313:
314:            /**
315:             * Calculate a task's dates and see if the critical path changes.  This means either: The task is currently critical, or the task becomes critical.
316:             * This function is useful in seeing whether a backward pass is necessary.  The backward pass is only necessary when the CP is modified.
317:             * @param honorRequiredDates
318:             * @param boundary
319:             * @return
320:             */
321:            final boolean affectsCriticalPath(CalculationContext context) {
322:                if (task.isOrWasCritical())
323:                    return true;
324:
325:                calcStartAndFinish(context); // for parents, it will examine all children
326:                long newEnd = getEnd();
327:                long oppositeEnd = -getOppositeSchedule().getBegin();
328:
329:                //		System.out.println("Affects" + (oppositeEnd < newEnd) + " opposite " + new Date(oppositeEnd) + " new" + new Date(newEnd));
330:                return (oppositeEnd < newEnd);
331:            }
332:
333:            final void calcDates(CalculationContext context) {
334:                long oldBegin = getBegin();
335:                long oldEnd = getEnd();
336:                long newBegin = 0L;
337:                long newEnd = 0L;
338:                final long needsCalculation = Dependency.NEEDS_CALCULATION;
339:                boolean unopenedSubproject = task.isSubproject()
340:                        && !((SubProj) task).isValidAndOpen();
341:                boolean external = task.isExternal();
342:                if (!external && !unopenedSubproject) {
343:                    if (context.taskReferenceType == PredecessorTaskList.TaskReference.PARENT_END) {
344:                        assignDatesFromChildren();
345:                    } else {
346:                        calcStartAndFinish(context); // for parents, it will examine all children
347:                    }
348:                    newBegin = getBegin();
349:                    newEnd = getEnd();
350:                    boolean reverseScheduled = task.isReverseScheduled();
351:
352:                    // if not just calculating early dates, check if reverse scheduled
353:                    if (!context.earlyOnly && reverseScheduled) {
354:                        TaskSchedule oppositeSchedule = getOppositeSchedule();
355:                        newBegin = -oppositeSchedule.getEnd();
356:                        newEnd = -oppositeSchedule.getBegin();
357:                    }
358:
359:                    if (context.assign && !unopenedSubproject) {
360:                        TaskSchedule currentSchedule = task
361:                                .getCurrentSchedule();
362:                        if (newBegin < 0) {
363:                            currentSchedule.setStart(-newEnd);
364:                            currentSchedule.setFinish(-newBegin);
365:                            currentSchedule
366:                                    .setRemainingDependencyDate(-remainingDependencyDate);
367:                        } else {
368:                            currentSchedule.setStart(newBegin);
369:                            currentSchedule.setFinish(newEnd);
370:                            currentSchedule
371:                                    .setRemainingDependencyDate(remainingDependencyDate);
372:
373:                        }
374:                        currentSchedule.setDependencyDate(dependencyDate);
375:                        // for parents, set current schedule's duration
376:                        if (context.taskReferenceType == PredecessorTaskList.TaskReference.PARENT_END) {
377:                            //TODO this only needs to be done if advancement changed on a task
378:                            currentSchedule.updateDurationFromDates(); // calculate duration based on parent start/end
379:                            ((NormalTask) (currentSchedule.task))
380:                                    .assignActualDatesFromChildren();
381:                        }
382:                        //			System.out.println(task.getName() + " Set current " + new Date(currentSchedule.getStart()) + " " + new Date(currentSchedule.getFinish()));
383:
384:                    }
385:                } else if (external) { // external
386:                    TaskSchedule currentSchedule = task.getCurrentSchedule();
387:                    newBegin = currentSchedule.getBegin();
388:                    newEnd = currentSchedule.getEnd();
389:                    oldBegin = 0;
390:
391:                }
392:
393:                if (oldBegin == newBegin && oldEnd == newEnd) {
394:                    //			System.out.println("no change");
395:                    if (!unopenedSubproject)
396:                        return;
397:                }
398:
399:                if (unopenedSubproject) { // need to put back old dates because we want the reverse pass to work right
400:                    newBegin = oldBegin;
401:                    newEnd = oldEnd;
402:                }
403:                Collection list = task.getDependencyList(!forward);
404:                Task parent = task.getWbsParentTask();
405:                TaskSchedule parentSchedule = null;
406:                long parentEnd = 0;
407:                if (parent != null) {
408:                    parentSchedule = parent.getSchedule(type);
409:                    parentEnd = parentSchedule.getEnd();
410:                }
411:
412:                if (context.taskReferenceType == PredecessorTaskList.TaskReference.PARENT_BEGIN) {
413:                    if (oldBegin != newBegin) { // if parent start (finish) changed, then all of its children need to me marked
414:
415:                        flagChildren();
416:                        setDependencyDate(newBegin); //This fixes a problem in incorrect propagation of constraints to children hk 16/8/05
417:
418:                        //				 make sure that in second pass over this, the schedule will change so it will be marked in backward pass.  However, we don't want to lose
419:                        //				information - specificially whether this task affects its parent's task.  In case it does, it is marked with a special value (Dependency.NEEDS_CALCULATION)
420:                        //				This is a bit of a hack, but it's for optimization purposes.				
421:
422:                        if (parentEnd == oldEnd)
423:                            setEnd(needsCalculation);
424:                        else
425:                            setEnd(0);
426:                    }
427:                    return;
428:                }
429:
430:                Dependency dependency;
431:
432:                if (list.isEmpty()) {
433:                    if (!task.isExternal() && task != context.sentinel) { // When the task is the sentinel, do nothing, otherwise find dependency and update it
434:                        dependency = (Dependency) context.sentinel
435:                                .getDependencyList(forward).find(forward, task); // find sentinel's dependency concerning this task
436:
437:                        //debug
438:                        if (dependency == null) {
439:                            dependency = (Dependency) context.sentinel
440:                                    .getDependencyList(forward).find(forward,
441:                                            task); // find sentinel's dependency concerning this task
442:                        }
443:                        if (dependency != null) { // tasks in a subproject won't have a sentinel dependency
444:                            dependency.calcDependencyDate(forward, newBegin,
445:                                    newEnd, false); // calculate it to store off value
446:                            context.sentinel
447:                                    .setCalculationStateCount(context.stateCount); // need to process successor(predecessor) later on in pass
448:                            context.sentinel.getSchedule(type)
449:                                    .setDependencyDate(needsCalculation); //sentinel needs dependencies calculated - I assume more than one
450:                        }
451:                    }
452:                } else {
453:                    //			Go Thru Successors (Predecessors) and calculate a dependency date for them and mark them for further treatment.  There is an optimization here:
454:                    //			If the successor(pred) task only has one predecessor(succ), then just set its dependency date instead of calculating it.  This avoids reprocessing
455:                    //			the predecessor(successor) list of that task later on.  Since in most cases, a task has only one predecessor, this saves time.
456:                    for (Iterator d = list.iterator(); d.hasNext();) {
457:                        Task dependencyTask;
458:                        TaskSchedule dependencyTaskSchedule;
459:
460:                        dependency = (Dependency) d.next();
461:                        if (dependency.isDisabled())
462:                            continue;
463:                        dependencyTask = (Task) dependency.getTask(!forward); // get the successor(pred) task
464:                        dependencyTaskSchedule = dependencyTask
465:                                .getSchedule(type);
466:                        // if this task is the only predecessor(successor) for the successor(predecessor) task, avoid long calculation and just calculate the date, otherwise
467:                        // flag the task for later calculation
468:                        long dependencyCount = dependencyTask
469:                                .getDependencyList(forward).size();
470:
471:                        long dep = newBegin; // by default (if no preds for example)
472:                        if (dependencyCount > 0) {
473:                            boolean useSooner = !dependencyTask.isWbsParent()
474:                                    && dependencyTask.hasDuration();
475:                            dep = dependency.calcDependencyDate(forward,
476:                                    newBegin, newEnd, useSooner); // calculate it and store off value
477:                            if (dependencyCount > 1) // can't just set date directly because more than one
478:                                dep = needsCalculation; // it will need to be calculated later
479:                        }
480:                        dependencyTaskSchedule.setDependencyDate(dep);
481:                        dependencyTask
482:                                .setCalculationStateCount(context.stateCount); // need to process successor(predecessor) later on in pass
483:                    }
484:                }
485:
486:                // mark parent also if it is affected and isn't marked already
487:                if (parent != null
488:                        && parent.getCalculationStateCount() != context.stateCount) {
489:                    long parentBegin = parentSchedule.getBegin();
490:                    if (oldEnd == 0 || oldEnd == Dependency.NEEDS_CALCULATION) // in case a parent itself modifies its parent or this task has been invalidated (if it is the task modified)
491:                        parent.setCalculationStateCount(context.stateCount); // mark its parent
492:                    else if ((oldEnd != newEnd && (newEnd > parentEnd || oldEnd == parentEnd)) // if this task previously determined the parent end date, the parent will need to be recalculated
493:                            || (oldBegin != newBegin && (newBegin < parentBegin || oldBegin == parentBegin))) { // if this task previously determined parent start date
494:                        parent.setCalculationStateCount(context.stateCount); // mark parent
495:                    }
496:                }
497:                if (context.pass == 1) // only mark during first pass.
498:                    task.setCalculationStateCount(context.stateCount + 1); // signal that backward pass needs to be done on this
499:            }
500:
501:            private void flagChildren() {
502:                int stateCount = task.getCalculationStateCount();
503:                Collection children = task.getWbsChildrenNodes();
504:                if (children == null)
505:                    return;
506:                Object current;
507:                Iterator i = children.iterator();
508:                while (i.hasNext()) {
509:                    current = ((Node) i.next()).getImpl();
510:                    if (!(current instanceof  Task))
511:                        continue;
512:                    ((Task) current).setCalculationStateCount(stateCount); // mark parent
513:                }
514:
515:            }
516:
517:            private void updateDurationFromDates() {
518:                setRawDuration(task.getEffectiveWorkCalendar().compare(
519:                        getFinish(), getStart(), false));
520:
521:            }
522:
523:            public void assignDatesFromChildren() {
524:                Collection children = task.getWbsChildrenNodes();
525:                if (children == null)
526:                    return;
527:                long begin = Long.MAX_VALUE;
528:                long end = Long.MIN_VALUE;
529:
530:                Iterator i = children.iterator();
531:                NormalTask child;
532:                Object current;
533:                TaskSchedule childSchedule;
534:                boolean estimated = false;
535:                while (i.hasNext()) {
536:                    current = ((Node) i.next()).getImpl();
537:                    if (!(current instanceof  NormalTask))
538:                        continue;
539:
540:                    child = (NormalTask) current;
541:                    estimated |= child.isEstimated();
542:                    childSchedule = child.getSchedule(type);
543:                    long childBegin = childSchedule.getBegin();
544:                    if (childBegin != 0)
545:                        begin = Math.min(begin, childBegin);
546:                    long childEnd = childSchedule.getEnd();
547:                    if (childEnd != 0)
548:                        end = Math.max(end, childEnd);
549:                }
550:
551:                if (begin != Long.MAX_VALUE && begin != 0) // in case of invalid subproject having no children
552:                    setBegin(begin);
553:                else
554:                    return;
555:                if (end != Long.MIN_VALUE && end != 0)
556:                    setEnd(end);
557:                else
558:                    return;//		System.out.println("begin is " + new Date(begin) + " end " + new Date(end));
559:                long duration = task.getEffectiveWorkCalendar().compare(end,
560:                        begin, false);
561:                duration = Duration.setAsEstimated(duration, estimated);
562:                ((NormalTask) task).setEstimated(estimated);
563:                setRawDuration(duration);
564:                //		System.out.println("parent " + task + "  begin " + new Date(start) + " " +start+ " end " + new Date(finish) + " " + finish);
565:                //		if (begin == 0)
566:                //			System.out.println("bad date 0");//assignDatesFromChildren();
567:            }
568:
569:            /**
570:             * Calculate the date which predecessors(successors) push this task to start by looping thru all of its predecesors(succ) and choosing the max value
571:             * @return max date
572:             */
573:            long calcDependencyDate() {
574:                long result = 0;
575:                Dependency dependency;
576:                long current;
577:                Collection list = task.getDependencyList(forward);
578:                for (Iterator i = list.iterator(); i.hasNext();) {
579:                    dependency = (Dependency) i.next();
580:                    if (dependency.isDisabled())
581:                        continue;
582:                    current = dependency.getDate(forward);
583:                    if (result == 0)
584:                        result = current;
585:                    else
586:                        result = Math.max(result, current);
587:                }
588:                setDependencyDate(result);
589:                return result;
590:            }
591:
592:            /**
593:             * During the forward pass, begin is early dates, during backward pass, it is late dates.
594:             * When reverse scheduling, the backward pass is executed first, then the forward.
595:             * The late schedule uses a trick: dates are returned as negative values.  This lets me to use the same min/max code.  Also
596:             * the calendar code knows to reverse durations when the date is negative.
597:             * @param boundary 
598:             * @param honorRequiredDates
599:             * @param early
600:             * @return
601:             */
602:            private void calcStartAndFinish(CalculationContext context) {
603:                if ("test".equals(task.getName()))
604:                    System.out.println("test");
605:
606:                long begin = getBeginDependency();
607:
608:                Task parent = task.getWbsParentTask();
609:
610:                //boolean useSooner = (forward != task.hasDuration()); // shortcut: if forward and is milestone, use sooner, otherwise later.  And conversely, if reverse and isn't milestone, use sooner, othewise later
611:                boolean useSooner = !task.hasDuration();
612:
613:                if (parent != null) {
614:                    TaskSchedule parentSchedule = parent.getSchedule(type);
615:                    long parentDependency = parentSchedule.getBeginDependency();
616:                    long parentWindow = parentSchedule.getWindowBegin();
617:                    if (parentDependency == 0
618:                            || (parentWindow != 0 && parentWindow > parentDependency))
619:                        parentDependency = parentWindow;
620:                    // in case where parent determines start time, make sure that this
621:                    // task starts either at day end if milesetone, or at next working
622:                    // day otherwise if parent is at day end
623:                    if (parentDependency != 0
624:                            && (begin == 0 || parentDependency > begin)) {
625:                        begin = task.getEffectiveWorkCalendar().add(
626:                                parentDependency, 0, useSooner);
627:                    }
628:                }
629:                if (task.isInSubproject())
630:                    begin = Math.max(begin, context.forward ? task
631:                            .getOwningProject().getStartConstraint() : -task
632:                            .getOwningProject().getEnd());
633:
634:                // Soft constraints
635:                long windowBegin = getWindowBegin();
636:
637:                // Make sure the task starts after its early start window date. This
638:                // is a soft constraint during forward pass.
639:
640:                // For SNET
641:                if (windowBegin != 0) {
642:                    if (begin == 0)
643:                        begin = windowBegin;
644:                    else if (windowBegin < begin) {
645:                        if (task.startsBeforeProject()) // case of task starting before project start but has SNET constraint
646:                            begin = windowBegin;
647:                    } else
648:                        begin = windowBegin;
649:                }
650:
651:                // For FNET
652:                long windowEnd = getWindowEnd();
653:                if (windowEnd != 0) {
654:                    if (begin == 0)
655:                        begin = Long.MIN_VALUE;
656:                    begin = Math.max(begin, task.calcOffsetFrom(windowEnd,
657:                            windowEnd, false, false, useSooner));
658:                    //			System.out.println("Applying FNET " + task + " " + d(windowEnd) + " begin is now " + d(begin));
659:                }
660:
661:                // Hard constraints
662:                if (context.honorRequiredDates) {
663:                    // If honoring required dates, check the hard constraint that the
664:                    // task is finished by its late finish date.
665:                    // Note that currently late finish has priority over early start.
666:                    long oppositeEnd = -getOppositeSchedule().getWindowBegin(); // For FNLT
667:                    if (oppositeEnd != 0) {
668:                        if (begin == 0)
669:                            begin = Long.MAX_VALUE;
670:                        begin = Math.min(begin, task.calcOffsetFrom(
671:                                oppositeEnd, dependencyDate, false, false,
672:                                useSooner));
673:                        //				System.out.println("Applying FNLT " + task + " " + d(oppositeEnd) + " begin is now " + d(begin));
674:                    }
675:                    // For SNLT
676:                    long oppositeBegin = -getOppositeSchedule().getWindowEnd();
677:                    if (oppositeBegin != 0) {
678:                        if (begin == 0)
679:                            begin = Long.MAX_VALUE;
680:                        begin = Math.min(begin, oppositeBegin);
681:                        //				System.out.println("Applying SNLT " + task + " " + d(oppositeBegin) + " begin is now " + d(begin));
682:                    }
683:                }
684:
685:                if (begin == 0) {
686:                    if (!task.isWbsParent()) // if no constraints at all
687:                        begin = context.boundary;
688:                }
689:                if (task.isSubproject()) {// subprojects can't start before their project start
690:                    SubProj subProj = (SubProj) task;
691:                    if (!subProj.isValidAndOpen())
692:                        return;
693:                    if (task.getPredecessorList().size() == 0
694:                            && task.getConstraintDate() == 0)
695:                        return;
696:                    begin = Math.max(begin, context.forward ? subProj
697:                            .getSubproject().getStartConstraint() : -subProj
698:                            .getSubproject().getEnd());
699:                }
700:
701:                long levelingDelay = task.getLevelingDelay();
702:
703:                if (Duration.millis(levelingDelay) != 0)
704:                    begin = task.getEffectiveWorkCalendar().add(begin,
705:                            levelingDelay, useSooner);
706:
707:                long remainingBegin = begin;
708:
709:                if (forward == context.forward)
710:                    setRemainingDependencyDate(remainingBegin); // the date which predecessors push the task to start at.  Actuals can override this
711:
712:                if (context.forward) {
713:                    long actualStart = task.getActualStart();
714:                    if (actualStart != 0)
715:                        begin = actualStart;
716:                }
717:                setBegin(begin);
718:                long end = ((Task) task).calcOffsetFrom(begin, remainingBegin,
719:                        true, true, true);
720:                setEnd(end);
721:            }
722:
723:            public void dump() {
724:                System.out.println("Task " + task + " schedule " + type
725:                        + " start " + new Date(start) + " finish "
726:                        + new Date(finish));
727:            }
728:
729:            /** 
730:             * Function used for tracing dates when debugging
731:             * @param l date either postive or negative
732:             * @return a date using the absolute value of the input
733:             */
734:            public static Date d(long l) {
735:                return new Date(Math.abs(l));
736:            }
737:
738:            /**
739:             * Structure used to store variables related to the pass
740:             */
741:            static class CalculationContext {
742:                int stateCount;
743:                boolean forward;
744:                boolean honorRequiredDates;
745:                Task sentinel;
746:                int taskReferenceType;
747:                long boundary;
748:                boolean earlyOnly;
749:                boolean assign;
750:                int scheduleType;
751:                int pass;
752:            }
753:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.