Source Code Cross Referenced for Task.java in  » Project-Management » OpenProj » com » projity » pm » task » 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.task 
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:        package com.projity.pm.task;
0051:
0052:        import java.util.Collection;
0053:        import java.util.Date;
0054:        import java.util.HashSet;
0055:        import java.util.Iterator;
0056:        import java.util.LinkedList;
0057:        import java.util.List;
0058:
0059:        import javax.swing.SwingUtilities;
0060:
0061:        import org.apache.commons.collections.Closure;
0062:        import org.apache.commons.collections.CollectionUtils;
0063:        import org.apache.commons.collections.Predicate;
0064:        import org.apache.commons.collections.functors.TruePredicate;
0065:
0066:        import com.projity.association.AssociationFormatParameters;
0067:        import com.projity.association.AssociationList;
0068:        import com.projity.association.AssociationListFormat;
0069:        import com.projity.configuration.CircularDependencyException;
0070:        import com.projity.configuration.Configuration;
0071:        import com.projity.configuration.Settings;
0072:        import com.projity.datatype.Duration;
0073:        import com.projity.document.Document;
0074:        import com.projity.document.ObjectEvent;
0075:        import com.projity.field.CustomFields;
0076:        import com.projity.field.CustomFieldsImpl;
0077:        import com.projity.field.Field;
0078:        import com.projity.field.FieldContext;
0079:        import com.projity.field.FieldParseException;
0080:        import com.projity.functor.CollectionVisitor;
0081:        import com.projity.functor.ObjectVisitor;
0082:        import com.projity.grouping.core.Node;
0083:        import com.projity.grouping.core.NodeList;
0084:        import com.projity.grouping.core.OutlineCollection;
0085:        import com.projity.grouping.core.hierarchy.BelongsToHierarchy;
0086:        import com.projity.grouping.core.model.NodeModel;
0087:        import com.projity.grouping.core.summaries.DivisionSummaryVisitor;
0088:        import com.projity.grouping.core.summaries.LeafWalker;
0089:        import com.projity.options.CalculationOption;
0090:        import com.projity.options.CalendarOption;
0091:        import com.projity.pm.assignment.Assignment;
0092:        import com.projity.pm.assignment.HasTimeDistributedData;
0093:        import com.projity.pm.assignment.timesheet.UpdatesFromTimesheet;
0094:        import com.projity.pm.calendar.HasCalendar;
0095:        import com.projity.pm.calendar.WorkCalendar;
0096:        import com.projity.pm.costing.EarnedValueMethodType;
0097:        import com.projity.pm.costing.ExpenseType;
0098:        import com.projity.pm.costing.HasExpenseType;
0099:        import com.projity.pm.criticalpath.PredecessorTaskList;
0100:        import com.projity.pm.criticalpath.ScheduleWindow;
0101:        import com.projity.pm.criticalpath.TaskSchedule;
0102:        import com.projity.pm.dependency.Dependency;
0103:        import com.projity.pm.dependency.DependencyFormat;
0104:        import com.projity.pm.dependency.DependencyService;
0105:        import com.projity.pm.dependency.DependencyType;
0106:        import com.projity.pm.dependency.HasDependencies;
0107:        import com.projity.pm.dependency.HasDependenciesImpl;
0108:        import com.projity.pm.key.HasKey;
0109:        import com.projity.pm.key.HasKeyImpl;
0110:        import com.projity.pm.resource.Resource;
0111:        import com.projity.pm.scheduling.CanBeLeveled;
0112:        import com.projity.pm.scheduling.ConstraintType;
0113:        import com.projity.pm.scheduling.Schedule;
0114:        import com.projity.pm.scheduling.ScheduleUtil;
0115:        import com.projity.pm.snapshot.Snapshottable;
0116:        import com.projity.pm.snapshot.SnapshottableImpl;
0117:        import com.projity.server.access.ErrorLogger;
0118:        import com.projity.server.data.DataObject;
0119:        import com.projity.strings.Messages;
0120:        import com.projity.util.Alert;
0121:        import com.projity.util.DateTime;
0122:        import com.projity.util.Environment;
0123:
0124:        /**
0125:         * @stereotype thing 
0126:         */
0127:        public abstract class Task implements  HasKey, HasNotes, HasCalendar,
0128:                HasDependencies, Schedule, ScheduleWindow, Snapshottable,
0129:                HasTimeDistributedData, HasPriority, CustomFields,
0130:                BelongsToDocument, BelongsToHierarchy, DataObject,
0131:                CanBeLeveled, UpdatesFromTimesheet, HasExpenseType {
0132:            static final long serialVersionUID = 786665335611L;
0133:            /**
0134:             * @link aggregation
0135:             * @supplierCardinality 0..* 
0136:             */
0137:            /*# com.projity.pm.assignment.Assignment lnkAssignment; */
0138:            transient Project project;
0139:            transient Project owningProject;
0140:            transient TaskSchedule currentSchedule = null;
0141:
0142:            protected transient int debugDependencyOrder = -1;
0143:            protected transient TaskSchedule earlySchedule;
0144:            protected transient TaskSchedule lateSchedule;
0145:            protected transient Snapshottable snapshots;
0146:            protected transient HasDependencies dependencies;
0147:            protected String notes = "";
0148:            protected String wbs = "";
0149:            protected boolean markTaskAsMilestone = false;
0150:            protected transient CustomFieldsImpl customFields = new CustomFieldsImpl();
0151:            protected transient HasKeyImpl hasKey;
0152:            protected transient boolean external = false;
0153:            protected transient long projectId = 0;
0154:            double physicalPercentComplete = 0.0;
0155:
0156:            protected long windowEarlyStart = 0;
0157:            protected long windowEarlyFinish = 0;
0158:            protected long windowLateStart = 0;
0159:            protected long windowLateFinish = 0;
0160:
0161:            protected long actualStart = 0;
0162:
0163:            protected long levelingDelay = 0L;
0164:            protected transient int calculationStateCount = 0;
0165:            protected transient boolean markerStatus = false;
0166:            protected int earnedValueMethod = EarnedValueMethodType.PERCENT_COMPLETE;
0167:            protected static Field startFieldInstance = null;
0168:
0169:            protected int constraintType = ConstraintType.ASAP;
0170:            protected long deadline = 0;
0171:            protected int expenseType = ExpenseType.NONE;
0172:            protected transient boolean inSubproject = false;
0173:            protected transient long lastSavedStart = 0L;
0174:            protected transient long lastSavedFinish = 0L;
0175:            protected transient boolean dirty;
0176:
0177:            public static Field getStartField() {
0178:                if (startFieldInstance == null)
0179:                    startFieldInstance = Configuration
0180:                            .getFieldFromId("Field.start");
0181:                return startFieldInstance;
0182:            }
0183:
0184:            /**
0185:             * @return Returns the taskSchedule.
0186:             */
0187:            public TaskSchedule getCurrentSchedule() {
0188:                return currentSchedule;
0189:            }
0190:
0191:            private static Field endFieldInstance = null;
0192:
0193:            public static Field getEndField() {
0194:                if (endFieldInstance == null)
0195:                    endFieldInstance = Configuration
0196:                            .getFieldFromId("Field.finish");
0197:                return endFieldInstance;
0198:            }
0199:
0200:            public Task() {
0201:                this (true);
0202:            }
0203:
0204:            public Task(boolean local) {
0205:                hasKey = new HasKeyImpl(local, this );
0206:                currentSchedule = new TaskSchedule();
0207:                initializeTransientTaskObjects();
0208:            }
0209:
0210:            public boolean isReadOnly() {
0211:                return isExternal()
0212:                        || isSubproject()
0213:                        || (getOwningProject() != null && getOwningProject()
0214:                                .isReadOnly());
0215:            }
0216:
0217:            protected void initializeTransientTaskObjects() {
0218:                currentSchedule.initSerialized(this , TaskSchedule.CURRENT);
0219:                earlySchedule = new TaskSchedule(this , TaskSchedule.EARLY);
0220:                lateSchedule = new TaskSchedule(this , TaskSchedule.LATE);
0221:                snapshots = new SnapshottableImpl(Settings.numBaselines());
0222:                dependencies = new HasDependenciesImpl(this );
0223:
0224:                createSnapshot(CURRENT);
0225:                ((TaskSnapshot) getCurrentSnapshot())
0226:                        .setCurrentSchedule(currentSchedule); // put the current schedule in the snapshot
0227:                setLastSavedStart(currentSchedule.getStart());
0228:                setLastSavedFinish(currentSchedule.getFinish());
0229:            }
0230:
0231:            protected void initializeTransientTaskObjectsAfterDeserialization() {
0232:                earlySchedule = new TaskSchedule(this , TaskSchedule.EARLY);
0233:                lateSchedule = new TaskSchedule(this , TaskSchedule.LATE);
0234:                dependencies = new HasDependenciesImpl(this );
0235:
0236:                currentSchedule = ((TaskSnapshot) getCurrentSnapshot())
0237:                        .getCurrentSchedule();
0238:                currentSchedule.initSerialized(this , TaskSchedule.CURRENT);
0239:
0240:                setLastSavedStart(currentSchedule.getStart());
0241:                setLastSavedFinish(currentSchedule.getFinish());
0242:            }
0243:
0244:            public TaskSnapshot getBaselineSnapshot() {
0245:                return (TaskSnapshot) getSnapshot(CalculationOption
0246:                        .getInstance().getEarnedValueBaselineId());
0247:            }
0248:
0249:            private TaskSnapshot createSnapshot(Object snapshotId) {
0250:                TaskSnapshot newOne = new TaskSnapshot();
0251:                setSnapshot(snapshotId, newOne);
0252:                return newOne;
0253:            }
0254:
0255:            /*
0256:             * (non-Javadoc)
0257:             * 
0258:             * @see com.projity.pm.scheduling.Schedule#getHasCalendar()
0259:             */
0260:            public HasCalendar getHasCalendar() {
0261:                return this ;
0262:            }
0263:
0264:            public Assignment getBaselineAssignment(Resource resource) {
0265:                TaskSnapshot baseline = getBaselineSnapshot();
0266:                if (baseline == null)
0267:                    return null;
0268:                return getBaselineSnapshot().findAssignment(resource);
0269:            }
0270:
0271:            public Assignment getBaselineAssignment(Resource resource,
0272:                    Object snapshot, boolean createIfDoesntExist) {
0273:                TaskSnapshot baselineSnapshot = (TaskSnapshot) getSnapshot(snapshot);
0274:                if (baselineSnapshot == null) {
0275:                    if (createIfDoesntExist)
0276:                        baselineSnapshot = createSnapshot(snapshot);
0277:                    else
0278:                        return null;
0279:                }
0280:                Assignment assignment = baselineSnapshot
0281:                        .findAssignment(resource);
0282:
0283:                if (assignment == null && createIfDoesntExist) {
0284:                    assignment = Assignment.getInstance(this , resource, 1.0, 0);
0285:                    baselineSnapshot.addAssignment(assignment);
0286:                    TaskSchedule baselineSchedule = new TaskSchedule(this ,
0287:                            TaskSchedule.CURRENT);
0288:                    //baselineSnapshot.set
0289:                    baselineSnapshot.setCurrentSchedule(baselineSchedule);
0290:                    assignment.setTaskSchedule(baselineSchedule);
0291:                    assignment.convertToBaselineAssignment(true);
0292:                }
0293:
0294:                return assignment;
0295:            }
0296:
0297:            /**
0298:             * @return Returns the project.
0299:             */
0300:            public Project getProject() {
0301:                return project;
0302:            }
0303:
0304:            public Document getDocument() {
0305:                return getProject();
0306:            }
0307:
0308:            public WorkCalendar getProjectCalendar() {
0309:                return project.getWorkCalendar();
0310:            }
0311:
0312:            public void connectToProject() {
0313:                project.connectTask(this );
0314:            }
0315:
0316:            protected boolean isInitialized() {
0317:                return getProject() != null && getProject().isInitialized();
0318:            }
0319:
0320:            /**
0321:             * @param project The project to set.
0322:             */
0323:            public void setProject(Project project) {
0324:                this .project = project;
0325:            }
0326:
0327:            public static Closure forProject(Closure visitor) {
0328:                return new ObjectVisitor(visitor) {
0329:                    protected final Object getObject(Object caller) {
0330:                        return ((Task) caller).getProject();
0331:                    }
0332:                };
0333:            }
0334:
0335:            //	Don't know if need this or not.  In any case, need to work out hierarchy treatment.
0336:            //	public NodeHierarchy getNodeHierarchy() {
0337:            //		//TODO use correct view ?
0338:            //		return Document.getTestInstance().getContextManager().getGlobalContext().getTaskContext(View.UNNAMED).getModel().getHierarchy();
0339:            //	}
0340:            //	
0341:            //	
0342:            public static Closure forParent(Closure visitor) {
0343:                return new ObjectVisitor(visitor) {
0344:                    protected final Object getObject(Object caller) {
0345:                        return ((Task) caller).getProject().getTaskOutline()
0346:                                .getHierarchy().getParent((Node) caller);
0347:                    }
0348:                };
0349:            }
0350:
0351:            public static Closure forAllChildren(Closure visitor,
0352:                    Predicate filter) {
0353:                return new CollectionVisitor(visitor, filter) {
0354:                    protected Collection getCollection(Object caller) {
0355:                        return ((Task) caller).getProject().getTaskOutline()
0356:                                .getHierarchy().getChildren((Node) caller);
0357:                    }
0358:                };
0359:            }
0360:
0361:            public static Closure forAllChildren(Closure visitor) {
0362:                return forAllChildren(visitor, TruePredicate.INSTANCE);
0363:            }
0364:
0365:            /**
0366:             * @return Returns the notes.
0367:             */
0368:            public String getNotes() {
0369:                return notes;
0370:            }
0371:
0372:            /**
0373:             * @param notes The notes to set.
0374:             */
0375:            public void setNotes(String notes) {
0376:                this .notes = notes;
0377:
0378:            }
0379:
0380:            public double getCustomCost(int i) {
0381:                return customFields.getCustomCost(i);
0382:            }
0383:
0384:            public long getCustomDate(int i) {
0385:                return customFields.getCustomDate(i);
0386:            }
0387:
0388:            public long getCustomDuration(int i) {
0389:                return customFields.getCustomDuration(i);
0390:            }
0391:
0392:            public long getCustomFinish(int i) {
0393:                return customFields.getCustomFinish(i);
0394:            }
0395:
0396:            public boolean getCustomFlag(int i) {
0397:                return customFields.getCustomFlag(i);
0398:            }
0399:
0400:            public double getCustomNumber(int i) {
0401:                return customFields.getCustomNumber(i);
0402:            }
0403:
0404:            public long getCustomStart(int i) {
0405:                return customFields.getCustomStart(i);
0406:            }
0407:
0408:            public String getCustomText(int i) {
0409:                return customFields.getCustomText(i);
0410:            }
0411:
0412:            public void setCustomCost(int i, double cost) {
0413:                customFields.setCustomCost(i, cost);
0414:            }
0415:
0416:            public void setCustomDate(int i, long date) {
0417:                customFields.setCustomDate(i, date);
0418:            }
0419:
0420:            public void setCustomDuration(int i, long duration) {
0421:                customFields.setCustomDuration(i, duration);
0422:            }
0423:
0424:            public void setCustomFinish(int i, long finish) {
0425:                customFields.setCustomFinish(i, finish);
0426:            }
0427:
0428:            public void setCustomFlag(int i, boolean flag) {
0429:                customFields.setCustomFlag(i, flag);
0430:            }
0431:
0432:            public void setCustomNumber(int i, double number) {
0433:                customFields.setCustomNumber(i, number);
0434:            }
0435:
0436:            public void setCustomStart(int i, long start) {
0437:                customFields.setCustomStart(i, start);
0438:            }
0439:
0440:            public void setCustomText(int i, String text) {
0441:                customFields.setCustomText(i, text);
0442:            }
0443:
0444:            /************************************************************************************************
0445:             * Task Schedule and methods
0446:             *************************************************************************************************/
0447:
0448:            /**
0449:             * @return start from task schedule
0450:             */
0451:            public long getStart() {
0452:                return currentSchedule.getStart();
0453:            }
0454:
0455:            /**
0456:             * Set the dependency start, not the task schedule start.  Only the CP can do that
0457:             */
0458:            public void setStart(long start, FieldContext fieldContext) {
0459:                if (getActualStart() != 0) // you can't change the start date of an in progress task
0460:                    return;
0461:                start = CalendarOption.getInstance().makeValidStart(start,
0462:                        false);
0463:                if (start != getStart()) {
0464:                    long projectStart = getProject().getStart();
0465:                    if (projectStart > start) {
0466:                        if (!Alert
0467:                                .okCancel(Messages
0468:                                        .getString("Message.allowTaskStartBeforeProjectStart")))
0469:                            return;
0470:                        setScheduleConstraint(ConstraintType.SNLT, start);
0471:
0472:                    } else {
0473:                        setScheduleConstraint(ConstraintType.SNET, start);
0474:                    }
0475:                }
0476:            }
0477:
0478:            public void setStart(long start) {
0479:                setStart(start, null);
0480:            }
0481:
0482:            /**
0483:             * @return
0484:             */
0485:            public long getEnd() {
0486:                return currentSchedule.getFinish();
0487:            }
0488:
0489:            /**
0490:             * @param end
0491:             */
0492:            public void setEnd(long end) {
0493:                setEnd(end, null);
0494:            }
0495:
0496:            public void setEnd(long end, FieldContext fieldContext) {
0497:                if (end != getEnd()) { // only set if it changes
0498:                    getCurrentSchedule().setEnd(end);
0499:                }
0500:            }
0501:
0502:            /**
0503:             * @return Returns the dependencyStart.
0504:             */
0505:            public long getDependencyStart() {
0506:                return currentSchedule.getRemainingDependencyDate();
0507:            }
0508:
0509:            /**
0510:             * @param dependencyStart The dependencyStart to set.
0511:             */
0512:            public void setDependencyStart(long dependencyStart) {
0513:                currentSchedule.setRemainingDependencyDate(dependencyStart);
0514:            }
0515:
0516:            /**
0517:             * Sets the duration without controls that setDuration performs
0518:             * 
0519:             * @param duration
0520:             */
0521:            public abstract void setRawDuration(long duration);
0522:
0523:            public long getRawDuration() {
0524:                return currentSchedule.getRawDuration();
0525:            }
0526:
0527:            public void clearDuration() {
0528:                setRawDuration(0);
0529:            }
0530:
0531:            /**
0532:             * @return
0533:             */
0534:            public WorkCalendar getEffectiveWorkCalendar() {
0535:                return null; // TODO figure out if this belong shere
0536:            }
0537:
0538:            public boolean isMilestone() {
0539:                return false;
0540:            }
0541:
0542:            public boolean isSubproject() {
0543:                return false;
0544:            }
0545:
0546:            transient Collection wbsChildrenNodes = null;
0547:            transient Task wbsParentTask = null;
0548:            transient Resource delegatedTo = null;
0549:
0550:            /**
0551:             * @return Returns the wbsChildrenNodes.
0552:             */
0553:            public Collection getWbsChildrenNodes() {
0554:                return wbsChildrenNodes;
0555:            }
0556:
0557:            /**
0558:             * @param wbsChildrenNodes The wbsChildrenNodes to set.
0559:             */
0560:            public void setWbsChildrenNodes(Collection wbsChildrenNodes) {
0561:                //System.out.println(this + " setWbsChildrenNodes " + wbsChildrenNodes);		
0562:                this .wbsChildrenNodes = wbsChildrenNodes;
0563:            }
0564:
0565:            public List getWbsChildrenTasks() {
0566:                List children = (List) getWbsChildrenNodes();
0567:                return NodeList.nodeListToImplList(children);
0568:            }
0569:
0570:            /**
0571:             * @return Returns the wbsParent.
0572:             */
0573:            public Task getWbsParentTask() {
0574:                return wbsParentTask;
0575:            }
0576:
0577:            /**
0578:             * @param wbsParent The wbsParent to set.
0579:             */
0580:            public void setWbsParent(Task wbsParentTask) {
0581:                this .wbsParentTask = wbsParentTask;
0582:            }
0583:
0584:            /**
0585:             * See if a this task is a child, grandchild... of another
0586:             * @param potentialParentTask - task to see if parent
0587:             * @return true if the task descends from potentialParentTask
0588:             */
0589:            public boolean wbsDescendentOf(Task potentialParentTask) {
0590:                if (this  == potentialParentTask)
0591:                    return true;
0592:                Task parentTask = getWbsParentTask();
0593:                if (parentTask == null)
0594:                    return false;
0595:                return parentTask.wbsDescendentOf(potentialParentTask);
0596:
0597:            }
0598:
0599:            public boolean isParent() {
0600:                return isWbsParent();
0601:            }
0602:
0603:            /* (non-Javadoc)
0604:             * @see com.projity.pm.task.TaskSpecificFields#isParent()
0605:             */
0606:            public boolean isWbsParent() {
0607:                if (wbsChildrenNodes == null || wbsChildrenNodes.size() == 0) {//a task has at least one assignment
0608:                //			System.out.println(this + " is not a wbs parent " + wbsChildrenNodes);
0609:                    return false;
0610:                }
0611:
0612:                Iterator i = wbsChildrenNodes.iterator();
0613:                Object current;
0614:                while (i.hasNext()) {
0615:                    current = ((Node) i.next()).getImpl();
0616:                    if (current instanceof  Task) {
0617:                        return true;
0618:                    }
0619:                }
0620:                return false;
0621:            }
0622:
0623:            public String getWbsParentName() {
0624:                if (wbsParentTask == null)
0625:                    return "";
0626:                return wbsParentTask.getName();
0627:            }
0628:
0629:            //arranges a task in predecessor/parent order in a colleciton
0630:            public void arrangeTask(Collection addTo, boolean markerStatus,
0631:                    int depth) {
0632:                if (this .markerStatus == markerStatus) { // if task has been added, don't treat it again
0633:                    return;
0634:                }
0635:
0636:                if (Environment.isImporting() && depth >= 1000) // in case circular link in imported project - TODO this is not a perfect solution
0637:                    throw new RuntimeException(
0638:                            CircularDependencyException.RUNTIME_EXCEPTION_TEXT);
0639:                // Arrange my parent
0640:                Task parent = getWbsParentTask();
0641:                //		System.out.println("arrange " + this + " id " + getId() + "    parent is " + parent );
0642:                if (parent != null) {
0643:                    parent.arrangeTask(addTo, markerStatus, depth + 1);
0644:                }
0645:
0646:                // Arrange my predecessors
0647:                Iterator i = getPredecessorList().iterator();
0648:                Task predecessor;
0649:                Dependency dep;
0650:
0651:                while (i.hasNext()) {
0652:                    dep = (Dependency) i.next();
0653:                    if (dep.isDisabled())
0654:                        continue;
0655:                    predecessor = (Task) dep.getPredecessor();
0656:                    predecessor.arrangeTask(addTo, markerStatus, depth + 1);
0657:                    predecessor.arrangeChildren(addTo, markerStatus, depth);
0658:                }
0659:
0660:                // Process current task
0661:                PredecessorTaskList.TaskReference taskReference = new PredecessorTaskList.TaskReference(
0662:                        this );
0663:                addTo.add(taskReference);
0664:                this .markerStatus = markerStatus; // mark the task as added so it won't be treated again
0665:
0666:                // Arrange my children
0667:                if (isWbsParent()) {
0668:                    taskReference.setParentBegin();
0669:                    arrangeChildren(addTo, markerStatus, depth);
0670:                    taskReference = new PredecessorTaskList.TaskReference(this );
0671:                    taskReference.setParentEnd();
0672:                    addTo.add(taskReference);
0673:                }
0674:            }
0675:
0676:            private void arrangeChildren(Collection addTo,
0677:                    boolean markerStatus, int depth) {
0678:
0679:                //note that it is possible that this is called for non parents
0680:
0681:                Collection children = getWbsChildrenNodes(); // I depend on my predecessors children
0682:                if (children != null) {
0683:                    Iterator p = children.iterator();
0684:                    Object current;
0685:                    Task child;
0686:                    while (p.hasNext()) {
0687:                        current = ((Node) p.next()).getImpl();
0688:                        if (!(current instanceof  Task))
0689:                            continue;
0690:
0691:                        child = (Task) current;
0692:                        child.arrangeTask(addTo, markerStatus, depth + 1);
0693:                    }
0694:                }
0695:            }
0696:
0697:            /**
0698:             * This rather complex function determines whether one task depends on another.  Because of the rules for parent tasks,
0699:             * the algorithm is rather complicated.  Basically:
0700:             * - A (parent) task depends on its childrens predecessors, as these are potentially equivalent 
0701:             * - A task depends on its parents predecessors - in the case of a link to its parent task, the links applies to this task too
0702:             * - A task depends on its parent, of course
0703:             * - A task depends on its predecessors (obviously)
0704:             * - A task depends on its predecessors children
0705:             * 
0706:             * @param other Task to compare to
0707:             * @param set - A set used to prevent treating same task twice
0708:             * @return true if linking to other would cause a circular link
0709:             */
0710:            private boolean dependsOn(Task other, HashSet set) {
0711:                // To avoid infinite loops which can occur under certain circumstances, use a set to prevent looking up twice
0712:                if (set.contains(this ))
0713:                    return false;
0714:                set.add(this );
0715:
0716:                // Here is the primary exit point.  We have arrived back at the other node, so it is circular
0717:                if (this  == other)
0718:                    return true;
0719:
0720:                Task predecessor;
0721:                Dependency dep;
0722:
0723:                Collection children;
0724:                Iterator i;
0725:
0726:                // I depend on my children's predecessors
0727:                children = getWbsChildrenNodes();
0728:                Task child;
0729:                Object current;
0730:                if (children != null) {
0731:                    i = children.iterator();
0732:                    while (i.hasNext()) {
0733:                        current = ((Node) i.next()).getImpl();
0734:                        if (!(current instanceof  Task))
0735:                            continue;
0736:                        child = (Task) current;
0737:                        Iterator j = child.getPredecessorList().iterator();
0738:                        while (j.hasNext()) {
0739:                            dep = (Dependency) j.next();
0740:                            if (dep.isDisabled())
0741:                                continue;
0742:                            predecessor = (Task) dep.getPredecessor();
0743:                            if (predecessor.wbsDescendentOf(this )) // skip if already belongs to parent thru an ancestry relation
0744:                                continue;
0745:                            if (predecessor.dependsOn(other, set))
0746:                                return true;
0747:                        }
0748:                    }
0749:                }
0750:
0751:                // I depend on my parent's predecessors
0752:                Task parent = getWbsParentTask();
0753:                if (parent != null) {
0754:
0755:                    // I dependon my parent
0756:                    if (parent.dependsOn(other, set))
0757:                        return true;
0758:
0759:                    i = parent.getPredecessorList().iterator();
0760:                    while (i.hasNext()) {
0761:                        dep = (Dependency) i.next();
0762:                        if (dep.isDisabled())
0763:                            continue;
0764:                        predecessor = (Task) dep.getPredecessor();
0765:                        if (predecessor.dependsOn(other, set)) {
0766:                            return true;
0767:                        }
0768:                    }
0769:                }
0770:
0771:                // I depend on my predecessors and their children	
0772:                i = getPredecessorList().iterator();
0773:                while (i.hasNext()) {
0774:                    dep = (Dependency) i.next();
0775:                    if (dep.isDisabled())
0776:                        continue;
0777:                    predecessor = (Task) dep.getPredecessor(); // I depend on my predecessors
0778:                    if (predecessor.dependsOn(other, set))
0779:                        return true;
0780:
0781:                    // see if my children depend on other
0782:                    children = predecessor.getWbsChildrenNodes(); // I depend on my predecessors children
0783:                    if (children != null) {
0784:                        i = children.iterator();
0785:                        while (i.hasNext()) {
0786:                            current = ((Node) i.next()).getImpl();
0787:                            if (!(current instanceof  Task))
0788:                                continue;
0789:
0790:                            child = (Task) current;
0791:                            if (child.dependsOn(other, set))
0792:                                return true;
0793:                        }
0794:                    }
0795:
0796:                }
0797:
0798:                return false;
0799:            }
0800:
0801:            public boolean dependsOn(HasDependencies other) {
0802:                HashSet set = new HashSet();
0803:                return dependsOn((Task) other, set);
0804:            }
0805:
0806:            /**
0807:             * @return
0808:             */
0809:            public Date getCreated() {
0810:                return hasKey.getCreated();
0811:            }
0812:
0813:            /**
0814:             * @return
0815:             */
0816:            public long getId() {
0817:                return hasKey.getId();
0818:            }
0819:
0820:            /**
0821:             * @param id
0822:             */
0823:            public void setId(long id) {
0824:                hasKey.setId(id);
0825:            }
0826:
0827:            /**
0828:             * @param created
0829:             */
0830:            public void setCreated(Date created) {
0831:                hasKey.setCreated(created);
0832:            }
0833:
0834:            public String getPredecessors() {
0835:                return AssociationListFormat.getInstance(
0836:                        DependencyFormat
0837:                                .getInstance(AssociationFormatParameters
0838:                                        .getInstance(this , true, Configuration
0839:                                                .getFieldFromId("Field.id"),
0840:                                                false, true))).format(
0841:                        getPredecessorList());
0842:            }
0843:
0844:            public String getSuccessors() {
0845:                return AssociationListFormat.getInstance(
0846:                        DependencyFormat
0847:                                .getInstance(AssociationFormatParameters
0848:                                        .getInstance(this , false, Configuration
0849:                                                .getFieldFromId("Field.id"),
0850:                                                false, true))).format(
0851:                        getSuccessorList());
0852:            }
0853:
0854:            public String getUniqueIdPredecessors() {
0855:                return AssociationListFormat
0856:                        .getInstance(
0857:                                DependencyFormat
0858:                                        .getInstance(AssociationFormatParameters
0859:                                                .getInstance(
0860:                                                        this ,
0861:                                                        true,
0862:                                                        Configuration
0863:                                                                .getFieldFromId("Field.uniqueId"),
0864:                                                        false, true))).format(
0865:                                getPredecessorList());
0866:            }
0867:
0868:            public String getUniqueIdSuccessors() {
0869:                return AssociationListFormat
0870:                        .getInstance(
0871:                                DependencyFormat
0872:                                        .getInstance(AssociationFormatParameters
0873:                                                .getInstance(
0874:                                                        this ,
0875:                                                        false,
0876:                                                        Configuration
0877:                                                                .getFieldFromId("Field.uniqueId"),
0878:                                                        false, true))).format(
0879:                                getSuccessorList());
0880:            }
0881:
0882:            public String getWbsPredecessors() {
0883:                return AssociationListFormat.getInstance(
0884:                        DependencyFormat
0885:                                .getInstance(AssociationFormatParameters
0886:                                        .getInstance(this , true, Configuration
0887:                                                .getFieldFromId("Field.wbs"),
0888:                                                true, true))).format(
0889:                        getPredecessorList());
0890:            }
0891:
0892:            public String getWbsSuccessors() {
0893:                return AssociationListFormat.getInstance(
0894:                        DependencyFormat
0895:                                .getInstance(AssociationFormatParameters
0896:                                        .getInstance(this , false, Configuration
0897:                                                .getFieldFromId("Field.wbs"),
0898:                                                true, true))).format(
0899:                        getSuccessorList());
0900:            }
0901:
0902:            public void setPredecessors(String predecessors)
0903:                    throws FieldParseException {
0904:                getPredecessorList().setAssociations(
0905:                        predecessors,
0906:                        DependencyFormat
0907:                                .getInstance(AssociationFormatParameters
0908:                                        .getInstance(this , true, Configuration
0909:                                                .getFieldFromId("Field.id"),
0910:                                                false, true)));
0911:            }
0912:
0913:            public void setSuccessors(String successors)
0914:                    throws FieldParseException {
0915:                getSuccessorList().setAssociations(
0916:                        successors,
0917:                        DependencyFormat
0918:                                .getInstance(AssociationFormatParameters
0919:                                        .getInstance(this , false, Configuration
0920:                                                .getFieldFromId("Field.id"),
0921:                                                false, true)));
0922:            }
0923:
0924:            public void setUniqueIdPredecessors(String predecessors)
0925:                    throws FieldParseException {
0926:                getPredecessorList()
0927:                        .setAssociations(
0928:                                predecessors,
0929:                                DependencyFormat
0930:                                        .getInstance(AssociationFormatParameters
0931:                                                .getInstance(
0932:                                                        this ,
0933:                                                        true,
0934:                                                        Configuration
0935:                                                                .getFieldFromId("Field.uniqueId"),
0936:                                                        false, true)));
0937:            }
0938:
0939:            public void setUniqueIdSuccessors(String successors)
0940:                    throws FieldParseException {
0941:                getSuccessorList()
0942:                        .setAssociations(
0943:                                successors,
0944:                                DependencyFormat
0945:                                        .getInstance(AssociationFormatParameters
0946:                                                .getInstance(
0947:                                                        this ,
0948:                                                        false,
0949:                                                        Configuration
0950:                                                                .getFieldFromId("Field.uniqueId"),
0951:                                                        false, true)));
0952:            }
0953:
0954:            /**
0955:             * @return Returns the wbs.
0956:             */
0957:            public String getWbs() {
0958:                return wbs;
0959:            }
0960:
0961:            /**
0962:             * @param wbs The wbs to set.
0963:             */
0964:            public void setWbs(String wbs) {
0965:                this .wbs = wbs;
0966:            }
0967:
0968:            /**
0969:             * @return
0970:             */
0971:            public long getUniqueId() {
0972:                return hasKey.getUniqueId();
0973:            }
0974:
0975:            /**
0976:             * @param id
0977:             */
0978:            public void setUniqueId(long id) {
0979:                hasKey.setUniqueId(id);
0980:            }
0981:
0982:            /**
0983:             * @return
0984:             */
0985:            public String getName() {
0986:                return hasKey.getName();
0987:            }
0988:
0989:            /**
0990:             * @param name
0991:             */
0992:            public void setName(String name) {
0993:                hasKey.setName(name);
0994:            }
0995:
0996:            public String toString() {
0997:                if (getName() == null)
0998:                    return "<null name>";
0999:                return getName();
1000:            }
1001:
1002:            public String getName(FieldContext context) {
1003:                return hasKey.getName(context);
1004:            }
1005:
1006:            public boolean isNormal() {
1007:                return false;
1008:            }
1009:
1010:            public boolean isCritical() {
1011:                return false;
1012:            }
1013:
1014:            /** if task is currently critical or will become critical after CP */
1015:            public boolean isOrWasCritical() {
1016:                if (isCritical())
1017:                    return true;
1018:                if (currentSchedule.isForward())
1019:                    return getEnd() >= getLateFinish();
1020:                else
1021:                    // reverse schedule
1022:                    return getStart() <= getEarlyStart();
1023:            }
1024:
1025:            public boolean isSummary() {
1026:                return isWbsParent(); //TODO need to somehow hook into view and see if parent in view's node model.  yuck!
1027:            }
1028:
1029:            public boolean isAssignment() {
1030:                return false;
1031:            }
1032:
1033:            /**
1034:             * @return Returns the physicalPercentComplete.
1035:             */
1036:            public double getPhysicalPercentComplete() {
1037:                return physicalPercentComplete;
1038:            }
1039:
1040:            /**
1041:             * @param physicalPercentComplete The physicalPercentComplete to set.
1042:             */
1043:            public void setPhysicalPercentComplete(
1044:                    double physicalPercentComplete) {
1045:                this .physicalPercentComplete = physicalPercentComplete;
1046:            }
1047:
1048:            public void markTaskAsNeedingRecalculation() {
1049:                int nextStateCount = project.getCalculationStateCount() + 1;
1050:                setCalculationStateCount(nextStateCount);
1051:            }
1052:
1053:            /**
1054:             * Flags all tasks which depend on this one for scheduling as dirty
1055:             * @param doSelf TODO
1056:             *
1057:             */
1058:            void markAllDependentTasksAsNeedingRecalculation(boolean doSelf) {
1059:                if (doSelf)
1060:                    markTaskAsNeedingRecalculation();
1061:
1062:                Iterator succ = getSuccessorList().iterator();
1063:                if (!succ.hasNext()) {
1064:                    getProject().getSchedulingAlgorithm().markBoundsAsDirty();
1065:                    //TODO what about reverse schedulded?
1066:                } else {
1067:                    Task successor;
1068:                    // mark successors as dirty
1069:                    while (succ.hasNext()) {
1070:                        successor = (Task) ((Dependency) succ.next())
1071:                                .getSuccessor();
1072:                        successor.markTaskAsNeedingRecalculation();
1073:                    }
1074:                }
1075:                // mark parent as dirty
1076:                Task parent = getWbsParentTask();
1077:                while (parent != null) {
1078:                    parent.markTaskAsNeedingRecalculation();
1079:                    parent = parent.getWbsParentTask();
1080:                }
1081:
1082:                // mark children as dirty
1083:                Collection children = getWbsChildrenNodes();
1084:                if (children != null) {
1085:                    Iterator i = children.iterator();
1086:                    Object child;
1087:                    while (i.hasNext()) {
1088:                        child = ((Node) i.next()).getImpl();
1089:                        if (!(child instanceof  Task))
1090:                            continue;
1091:                        ((Task) child).markTaskAsNeedingRecalculation();
1092:                    }
1093:                }
1094:            }
1095:
1096:            void cleanUp(Object eventSource, boolean deep, boolean undo,
1097:                    boolean cleanDependencies) {
1098:                //if (!cleanDependencies) return; //TODO was for undo of paste of linked tasks, but doesn't work
1099:                markAllDependentTasksAsNeedingRecalculation(false);
1100:
1101:                // remove sentinel dependencies if any
1102:                project.removeStartSentinelDependency(this );
1103:                project.removeEndSentinelDependency(this );
1104:
1105:                // remove all links to or from
1106:                LinkedList toRemove = new LinkedList(); //fix
1107:                DependencyService.getInstance().remove(getPredecessorList(),
1108:                        toRemove);
1109:                for (Iterator j = toRemove.iterator(); j.hasNext();) {
1110:                    DependencyService.getInstance().remove(
1111:                            (Dependency) j.next(), eventSource, undo); //fix
1112:                }
1113:                toRemove.clear();
1114:                DependencyService.getInstance().remove(getSuccessorList(),
1115:                        toRemove);
1116:                for (Iterator j = toRemove.iterator(); j.hasNext();) {
1117:                    DependencyService.getInstance().remove(
1118:                            (Dependency) j.next(), eventSource, undo); //fix
1119:                }
1120:
1121:            }
1122:
1123:            public void recalculate(Object eventSource) {
1124:                ((Project) getDocument()).updateScheduling(eventSource, this ,
1125:                        ObjectEvent.UPDATE, getEndField());
1126:                //getDocument().getObjectEventManager().fireUpdateEvent(eventSource,this,getEndField());
1127:            }
1128:
1129:            public void recalculateLater(final Object eventSource) {
1130:                markTaskAsNeedingRecalculation(); // task needs to be recalculated
1131:
1132:                SwingUtilities.invokeLater(new Runnable() {
1133:                    public void run() {
1134:                        recalculate(eventSource);
1135:                    }
1136:                });
1137:            }
1138:
1139:            /**
1140:             * @return
1141:             */
1142:            public long getActualStart() {
1143:                return actualStart;
1144:                //		if (currentSchedule.getPercentComplete() == 0.0D && getPercentComplete() == 0)
1145:                //			return 0;
1146:                //		return getStart();
1147:            }
1148:
1149:            public abstract void setActualStart(long actualStart);
1150:
1151:            public long getActualFinish() {
1152:                if (getPercentComplete() == 1.0)
1153:                    return getEnd();
1154:                return 0;
1155:            }
1156:
1157:            /**
1158:             * @param actualFinish
1159:             */
1160:            public void setActualFinish(long actualFinish) {
1161:                long old = getActualFinish();
1162:                if (actualFinish == old)
1163:                    return;
1164:                setEnd(actualFinish);
1165:                setPercentComplete(1.0);
1166:            }
1167:
1168:            /**
1169:             * Percent complete is calculated based on assignments
1170:             */
1171:            public double getPercentComplete() {
1172:                boolean parent = isWbsParent();
1173:                DivisionSummaryVisitor divisionClosure = ScheduleUtil
1174:                        .percentCompleteClosureInstance(parent);
1175:                Project proj = (Project) (getMasterDocument() == null ? getProject()
1176:                        : getMasterDocument());
1177:                NodeModel nodeModel = proj.getTaskOutline();
1178:                if (isWbsParent()) {
1179:                    try {
1180:                        LeafWalker.recursivelyTreatBranch(nodeModel, this ,
1181:                                divisionClosure);
1182:                    } catch (NullPointerException n) {
1183:                        ErrorLogger.logOnce("getPercentComplete",
1184:                                "getPercentComplete() Task: " + this 
1185:                                        + " Project " + project, n);
1186:                        return 0; // better this than crashing
1187:                    }
1188:                } else {
1189:                    CollectionUtils.forAllDo(((NormalTask) this )
1190:                            .getAssignments(), divisionClosure);
1191:                }
1192:                return divisionClosure.getValue();
1193:            }
1194:
1195:            public boolean inProgress() {
1196:                double percentComplete = getPercentComplete();
1197:                return (percentComplete > 0.0D && percentComplete < 1.0D);
1198:            }
1199:
1200:            public boolean isComplete() {
1201:                return getPercentComplete() >= 1.0D;
1202:            }
1203:
1204:            public boolean isUnstarted() {
1205:                return getPercentComplete() == 0.0D;
1206:            }
1207:
1208:            public long getDurationMillis() {
1209:                return Duration.millis(getDuration());
1210:            }
1211:
1212:            /**
1213:             * @return
1214:             */
1215:            //&&&&&	
1216:            //	public long getActualDuration() {
1217:            //		long stop = getStop();
1218:            //		if (stop == 0)
1219:            //			return 0;
1220:            //		return getEffectiveWorkCalendar().compare(stop,getStart(),false);
1221:            //	}
1222:            /**
1223:             * Actual duration is % complete * duration for all tasks including parents
1224:             */
1225:            public long getActualDuration() {
1226:                long duration = getDuration();
1227:                long result = Math.round(getPercentComplete()
1228:                        * Duration.millis(duration));
1229:                return Duration.useTimeUnitOfInNone(result, duration);
1230:            }
1231:
1232:            /**
1233:             * @param actualDuration
1234:             */
1235:            public void setActualDuration(long actualDuration) {
1236:                actualDuration = DateTime.closestDate(Duration
1237:                        .millis(actualDuration));
1238:
1239:                if (actualDuration == Duration.millis(getActualDuration()))
1240:                    return;
1241:                long stop = getEffectiveWorkCalendar().add(getStart(),
1242:                        actualDuration, true);
1243:                setStop(stop);
1244:            }
1245:
1246:            /**
1247:             * @return
1248:             */
1249:            public long getRemainingDuration() {
1250:                long actualDuration = getActualDuration();
1251:                long result = getDurationMillis()
1252:                        - Duration.millis(actualDuration);
1253:                return Duration.useTimeUnitOfInNone(result, actualDuration);
1254:            }
1255:
1256:            /**
1257:             * @param remainingDuration
1258:             */
1259:            public void setRemainingDuration(long remainingDuration) {
1260:                remainingDuration = DateTime.closestDate(Duration
1261:                        .millis(remainingDuration));
1262:                setActualDuration(getDurationMillis() - remainingDuration);
1263:            }
1264:
1265:            public Object clone() {
1266:                try {
1267:                    Task task = (Task) super .clone();
1268:                    _cloneTo(task);
1269:                    //				Handle wbs outside
1270:                    return task;
1271:                } catch (CloneNotSupportedException e) {
1272:                    throw new InternalError();
1273:                }
1274:            }
1275:
1276:            public void cleanClone() {
1277:                owningProject = null;
1278:                project = null;
1279:            }
1280:
1281:            private void _cloneTo(Task task) {
1282:                task.hasKey = new HasKeyImpl(isLocal(), task);
1283:                task.setName(new String(getName()));
1284:                task.setRawDuration(getRawDuration());
1285:
1286:                task.earlySchedule = (TaskSchedule) earlySchedule
1287:                        .cloneWithTask(task);
1288:                task.lateSchedule = (TaskSchedule) lateSchedule
1289:                        .cloneWithTask(task);
1290:                task.customFields = (CustomFieldsImpl) customFields.clone();
1291:                task.snapshots = (Snapshottable) ((SnapshottableImpl) snapshots)
1292:                        .cloneWithTask(task);
1293:                task.currentSchedule = ((TaskSnapshot) task
1294:                        .getCurrentSnapshot()).getCurrentSchedule();
1295:                task.notes = new String(notes);
1296:                task.wbs = new String(wbs);
1297:                task.wbsChildrenNodes = null;
1298:                task.wbsParentTask = null;
1299:
1300:                task.dependencies = new HasDependenciesImpl(task);
1301:
1302:                task.currentSchedule.copyDatesAfterClone(currentSchedule);
1303:            }
1304:
1305:            public void cloneTo(Task task) {
1306:                task.project = project;
1307:                task.owningProject = owningProject;
1308:
1309:                task.debugDependencyOrder = debugDependencyOrder;
1310:                task.markTaskAsMilestone = markTaskAsMilestone;
1311:                task.external = external;
1312:                task.projectId = projectId;
1313:                task.physicalPercentComplete = physicalPercentComplete;
1314:
1315:                task.windowEarlyStart = windowEarlyStart;
1316:                task.windowEarlyFinish = windowEarlyFinish;
1317:                task.windowLateStart = windowLateStart;
1318:                task.windowLateFinish = windowLateFinish;
1319:
1320:                task.actualStart = actualStart;
1321:
1322:                task.levelingDelay = levelingDelay;
1323:                task.calculationStateCount = calculationStateCount;
1324:                task.markerStatus = markerStatus;
1325:                task.earnedValueMethod = earnedValueMethod;
1326:                task.startFieldInstance = startFieldInstance;
1327:
1328:                task.constraintType = constraintType;
1329:                task.deadline = deadline;
1330:                task.expenseType = expenseType;
1331:                task.inSubproject = inSubproject;
1332:                task.lastSavedStart = lastSavedStart;
1333:                task.lastSavedFinish = lastSavedFinish;
1334:                task.dirty = dirty;
1335:
1336:                task.delegatedTo = delegatedTo;
1337:
1338:                _cloneTo(task);
1339:            }
1340:
1341:            /**
1342:             * @return Returns the splitDuration.
1343:             */
1344:            public long getSplitDuration() {
1345:                long r = getResume();
1346:                if (r == 0)
1347:                    return 0;
1348:                return getEffectiveWorkCalendar().compare(r, getStop(), false);
1349:            }
1350:
1351:            /******************************************************************************
1352:             * Getters and setters
1353:             ****************************************************************************/
1354:
1355:            /**
1356:             * @return Returns the constraintType.
1357:             */
1358:            public int getConstraintType() {
1359:                return constraintType;
1360:            }
1361:
1362:            /**
1363:             * @param constraintType The constraintType to set.
1364:             */
1365:            public void setConstraintType(int constraintType)
1366:                    throws FieldParseException {
1367:                int newConstraintType = makeValidConstraintType(constraintType); // limit to valid options
1368:                if (newConstraintType != constraintType)
1369:                    throw new FieldParseException(Messages
1370:                            .getString("Message.parentConstraintType"));
1371:                setRawConstraintType(constraintType);
1372:                long d = getConstraintDate(); // save off old date, it will be reused
1373:                if (!isDatelessConstraintType() && d == 0) // if the constraint requires a date and there is none, set a date to today
1374:                    setConstraintDate(getEffectiveWorkCalendar()
1375:                            .adjustInsideCalendar(DateTime.midnightToday(),
1376:                                    false));
1377:
1378:            }
1379:
1380:            public void setRawConstraintType(int constraintType) {
1381:                long d = getConstraintDate(); // save off old date, it will be reused
1382:                clearDateConstraints(); // get rid of all constraints
1383:                setScheduleConstraint(constraintType, d); // set new constraint with old date
1384:
1385:            }
1386:
1387:            /**
1388:             * @return Returns the windowEarlyStart.
1389:             */
1390:            public long getWindowEarlyStart() {
1391:                return windowEarlyStart;
1392:            }
1393:
1394:            /**
1395:             * @param windowEarlyStart The windowEarlyStart to set.
1396:             */
1397:            public void setWindowEarlyStart(long windowEarlyStart) {
1398:                this .windowEarlyStart = windowEarlyStart;
1399:            }
1400:
1401:            /**
1402:             * @return Returns the windowEarlyFinish.
1403:             */
1404:            public long getWindowEarlyFinish() {
1405:                return windowEarlyFinish;
1406:            }
1407:
1408:            /**
1409:             * @param windowEarlyFinish The windowEarlyFinish to set.
1410:             */
1411:            public void setWindowEarlyFinish(long windowEarlyFinish) {
1412:                this .windowEarlyFinish = windowEarlyFinish;
1413:            }
1414:
1415:            /**
1416:             * @return Returns the windowLateFinish.
1417:             */
1418:            public long getWindowLateFinish() {
1419:                return windowLateFinish;
1420:            }
1421:
1422:            /**
1423:             * @param windowLateFinish The windowLateFinish to set.
1424:             */
1425:            public void setWindowLateFinish(long windowLateFinish) {
1426:                this .windowLateFinish = windowLateFinish;
1427:            }
1428:
1429:            /**
1430:             * @return Returns the windowLateStart.
1431:             */
1432:            public long getWindowLateStart() {
1433:                return windowLateStart;
1434:            }
1435:
1436:            /**
1437:             * @param windowLateStart The windowLateStart to set.
1438:             */
1439:            public void setWindowLateStart(long windowLateStart) {
1440:                this .windowLateStart = windowLateStart;
1441:            }
1442:
1443:            /**
1444:             * @param mustStart The date the task must start on.
1445:             */
1446:            public void setMustStartOn(long mustStart) {
1447:                setWindowEarlyStart(mustStart);
1448:                setWindowLateStart(mustStart);
1449:            }
1450:
1451:            /**
1452:             * @param mustStart The date the task must finish on.
1453:             */
1454:            public void setMustFinishOn(long mustFinish) {
1455:                setWindowEarlyFinish(mustFinish);
1456:                setWindowLateFinish(mustFinish);
1457:            }
1458:
1459:            /**
1460:             * Set constraint FNET
1461:             * @param date
1462:             */
1463:            public void setFinishNoEarlierThan(long date) {
1464:                setWindowEarlyFinish(date);
1465:            }
1466:
1467:            /**
1468:             * Set constraint FNLT 
1469:             * @param date
1470:             */
1471:            public void setFinishNoLaterThan(long date) {
1472:                setWindowLateFinish(date);
1473:                setWindowEarlyFinish(0);
1474:            }
1475:
1476:            /**
1477:             * Set constraint SNET
1478:             * @param date
1479:             */
1480:            public void setStartNoEarlierThan(long date) {
1481:                setWindowEarlyStart(date);
1482:                setWindowLateStart(0);
1483:            }
1484:
1485:            /**
1486:             * Set constraint SNLT 
1487:             * @param date
1488:             */
1489:            public void setStartNoLaterThan(long date) {
1490:                setWindowLateStart(date);
1491:                setWindowEarlyStart(0);
1492:            }
1493:
1494:            /**
1495:             * @return Returns the earlyFinish.
1496:             */
1497:            public long getEarlyFinish() {
1498:                return earlySchedule.getFinish();
1499:            }
1500:
1501:            /**
1502:             * @return Returns the earlyStart.
1503:             */
1504:            public long getEarlyStart() {
1505:                return earlySchedule.getStart();
1506:            }
1507:
1508:            /**
1509:             * @return Returns the lateFinish.
1510:             */
1511:            public long getLateFinish() {
1512:                return lateSchedule.getFinish();
1513:            }
1514:
1515:            /**
1516:             * @return Returns the lateStart.
1517:             */
1518:            public long getLateStart() {
1519:                return lateSchedule.getStart();
1520:            }
1521:
1522:            /**
1523:             * Is this task reverse scheduled:  Is it ALAP in forward scheduling or ASAP in reverse?
1524:             * @return
1525:             */
1526:            public final boolean isReverseScheduled() {
1527:                if (project.isForward())
1528:                    return constraintType == ConstraintType.ALAP;
1529:                else
1530:                    return constraintType == ConstraintType.ASAP;
1531:            }
1532:
1533:            protected final boolean isDatelessConstraintType() {
1534:                return constraintType == ConstraintType.ALAP
1535:                        || constraintType == ConstraintType.ASAP;
1536:
1537:            }
1538:
1539:            /*********************************************************************************
1540:             * Constraints
1541:             ***********************************************************************************/
1542:            private void clearDateConstraints() {
1543:                setWindowEarlyStart(0);
1544:                setWindowLateStart(0);
1545:                setWindowEarlyFinish(0);
1546:                setWindowLateFinish(0);
1547:            }
1548:
1549:            //	public Object[] fieldOptionsScheduleConstraint() {
1550:            //		if (isWbsParent()) {
1551:            //			Configuration.getFieldFromId("Field.scheduleConstraint");
1552:            //			
1553:            //			
1554:            //		} else {
1555:            //			return null; // use default
1556:            //		}
1557:            //			
1558:            //	}
1559:
1560:            public void setScheduleConstraint(int constraintType, long date) {
1561:                this .constraintType = constraintType;
1562:                if (constraintType == ConstraintType.FNET) {
1563:                    setFinishNoEarlierThan(date);
1564:                } else if (constraintType == ConstraintType.FNLT) {
1565:                    setFinishNoLaterThan(date);
1566:                } else if (constraintType == ConstraintType.SNET) {
1567:                    setStartNoEarlierThan(date);
1568:                } else if (constraintType == ConstraintType.SNLT) {
1569:                    setStartNoLaterThan(date);
1570:                } else if (constraintType == ConstraintType.MSO) {
1571:                    setMustStartOn(date);
1572:                } else if (constraintType == ConstraintType.MFO) {
1573:                    setMustFinishOn(date);
1574:                } else {
1575:                    clearDateConstraints();
1576:                }
1577:
1578:            }
1579:
1580:            public void setScheduleConstraintAndUpdate(int constraintType,
1581:                    long date) {
1582:                setScheduleConstraint(constraintType, date);
1583:                getDocument().getObjectEventManager().fireUpdateEvent(this ,
1584:                        this ,
1585:                        Configuration.getFieldFromId("Field.constraintType"));
1586:            }
1587:
1588:            public void setConstraintDate(long date) {
1589:                if (date == 0) {
1590:                    clearDateConstraints();
1591:                    constraintType = getProject().getDefaultConstraintType();
1592:                } else {
1593:                    date = getEffectiveWorkCalendar().adjustInsideCalendar(
1594:                            date, false); // make date valid
1595:
1596:                }
1597:                setScheduleConstraint(constraintType, date);
1598:
1599:            }
1600:
1601:            public long getConstraintDate() {
1602:                if (constraintType == ConstraintType.FNET) {
1603:                    return getWindowEarlyFinish();
1604:                } else if (constraintType == ConstraintType.FNLT) {
1605:                    return getWindowLateFinish();
1606:                } else if (constraintType == ConstraintType.SNET) {
1607:                    return getWindowEarlyStart();
1608:                } else if (constraintType == ConstraintType.SNLT) {
1609:                    return getWindowLateStart();
1610:                } else if (constraintType == ConstraintType.MSO) {
1611:                    return getWindowEarlyStart();
1612:                } else if (constraintType == ConstraintType.MFO) {
1613:                    return getWindowEarlyFinish();
1614:                } else {
1615:                    return 0;
1616:                }
1617:            }
1618:
1619:            public boolean isReadOnlyConstraintDate(FieldContext fieldContext) {
1620:                return getConstraintType() == ConstraintType.ALAP
1621:                        || getConstraintType() == ConstraintType.ASAP;
1622:            }
1623:
1624:            /**************************************************************************
1625:             * Critical path methods for slack
1626:             ***************************************************************************/
1627:            public final long getTotalSlack() {
1628:                return getEffectiveWorkCalendar().compare(getLateFinish(),
1629:                        getEarlyFinish(), false);
1630:            }
1631:
1632:            /** The amount of excess time an activity has between its Early Start and Late Start dates. */
1633:            public final long getStartSlack() {
1634:                return getEffectiveWorkCalendar().compare(getLateStart(),
1635:                        getEarlyStart(), false);
1636:            }
1637:
1638:            /** The amount of excess time an activity has between its Early Finish and Late Finish dates. */
1639:            public final long getFinishSlack() {
1640:                return getEffectiveWorkCalendar().compare(getLateFinish(),
1641:                        getEarlyFinish(), false); // note that this is same as total float
1642:            }
1643:
1644:            /**
1645:             * Used to calculate the free slack on a given dependency
1646:             * 
1647:             * @param dependency
1648:             * @return
1649:             */
1650:            private static long calcFreeSlack(Dependency dependency) {
1651:                ScheduleWindow predecessor = (ScheduleWindow) dependency
1652:                        .getPredecessor();
1653:                ScheduleWindow successor = (ScheduleWindow) dependency
1654:                        .getSuccessor();
1655:                long t = 0;
1656:                WorkCalendar cal = dependency.getEffectiveWorkCalendar();
1657:                if (dependency.getDependencyType() == DependencyType.FS) {
1658:                    t = cal.compare(cal.add(successor.getEarlyStart(),
1659:                            -dependency.getLeadValue(), true), predecessor
1660:                            .getEarlyFinish(), false);
1661:                } else if (dependency.getDependencyType() == DependencyType.FF) {
1662:                    t = cal.compare(cal.add(successor.getEarlyFinish(),
1663:                            -dependency.getLeadValue(), true), predecessor
1664:                            .getEarlyFinish(), false);
1665:                } else if (dependency.getDependencyType() == DependencyType.SS) {
1666:                    t = cal.compare(cal.add(successor.getEarlyStart(),
1667:                            -dependency.getLeadValue(), true), predecessor
1668:                            .getEarlyStart(), false);
1669:                } else if (dependency.getDependencyType() == DependencyType.SF) {
1670:                    t = cal.compare(cal.add(successor.getEarlyFinish(),
1671:                            -dependency.getLeadValue(), true), predecessor
1672:                            .getEarlyStart(), false);
1673:                }
1674:                return t;
1675:            }
1676:
1677:            /**
1678:             * Used in calculating free slack. Free Float = For FS: Early Start (next
1679:             * activity) � Lag (if any) � Early Finish*
1680:             * 
1681:             * @param dependencyList
1682:             * @param duration
1683:             * @return
1684:             */
1685:            public long getFreeSlack() {
1686:                long least = getTotalSlack(); // free slack is at most the total slack
1687:                Dependency dependency;
1688:                for (Iterator i = getSuccessorList().iterator(); i.hasNext();) {
1689:                    dependency = (Dependency) i.next();
1690:                    least = Math.min(least, calcFreeSlack(dependency));
1691:                }
1692:                return least;
1693:            }
1694:
1695:            /**********************************************************************************
1696:             * Access to Dependencies 
1697:             **********************************************************************************/
1698:
1699:            public AssociationList getPredecessorList() {
1700:                return dependencies.getPredecessorList();
1701:            }
1702:
1703:            public AssociationList getSuccessorList() {
1704:                return dependencies.getSuccessorList();
1705:            }
1706:
1707:            public AssociationList getDependencyList(boolean pred) {
1708:                return dependencies.getDependencyList(pred);
1709:            }
1710:
1711:            /************************************************************************************
1712:             * Critical Path stuff
1713:             **************************************************************************************/
1714:
1715:            /* (non-Javadoc)
1716:             * @see com.projity.pm.criticalpath.ScheduleWindow#calcOffsetFrom(long, boolean, boolean)
1717:             */
1718:            public long calcOffsetFrom(long startDate, long dependencyDate,
1719:                    boolean ahead, boolean remainingOnly, boolean useSooner) {
1720:                throw new RuntimeException(
1721:                        "calcOffsetFrom should not be called in ScheduleWindow");
1722:            }
1723:
1724:            public long getElapsedDuration() {
1725:                return Math.round(getEffectiveWorkCalendar().compare(getEnd(),
1726:                        getStart(), true)
1727:                        * CalendarOption.getInstance()
1728:                                .getFractionOfDayThatIsWorking());
1729:            }
1730:
1731:            public long getDeadline() {
1732:                return deadline;
1733:            }
1734:
1735:            public void setDeadline(long deadline) {
1736:                if (deadline != 0L)
1737:                    deadline = CalendarOption.getInstance().makeValidEnd(
1738:                            deadline, false);
1739:                this .deadline = deadline;
1740:            }
1741:
1742:            public boolean isMarkTaskAsMilestone() {
1743:                return markTaskAsMilestone;
1744:            }
1745:
1746:            public void setMarkTaskAsMilestone(boolean markTaskAsMilestone) {
1747:                this .markTaskAsMilestone = markTaskAsMilestone;
1748:            }
1749:
1750:            public int getEarnedValueMethod() {
1751:                return earnedValueMethod;
1752:            }
1753:
1754:            public void setEarnedValueMethod(int earnedValueMethod) {
1755:                this .earnedValueMethod = earnedValueMethod;
1756:            }
1757:
1758:            /** Update a task from the Update Project dialog.  There are several options:
1759:             * 
1760:             * @param date Date to either update completion to, or to move remaining work to
1761:             * @param updateWorkAsCompleteThrough If true, then update % complete, if false, then move remaining
1762:             *  to the date
1763:             * @param setFractionalPercentComplete If true, then allow setting of % complete for uncompleted tasks,
1764:             *  otherwise, if a task is not completed, it's current completion will not be modified
1765:             * @return True if task was updated, false if unchanged
1766:             */
1767:            public boolean updateProjectTask(long date,
1768:                    boolean updateWorkAsCompleteThrough,
1769:                    boolean setFractionalPercentComplete) {
1770:                long start = getStart();
1771:                long end = getEnd();
1772:                long completedDate = getStop();
1773:                boolean updated = false;
1774:                if (updateWorkAsCompleteThrough) {
1775:                    if (setFractionalPercentComplete) {
1776:                        if (completedDate != end) {// if task is not finished, adjust its completion.  This may actually reduce % complete
1777:                            setStop(date);
1778:                            updated = true;
1779:                        }
1780:                    } else if (date >= end) { // if date is equal or later to end date of task, set its percent complete to 100%, otherwise do nothing
1781:                        setPercentComplete(1.0);
1782:                        updated = true;
1783:                    }
1784:                } else {
1785:                    if (date > start) { // move remaining after status date
1786:                        moveRemainingToDate(date);
1787:                        updated = true;
1788:                    }
1789:                }
1790:                if (updated) {
1791:                    recalculate(this );
1792:                    setDirty(true);
1793:                }
1794:                return updated;
1795:            }
1796:
1797:            /**
1798:             * @return Returns the calculationStateCount.
1799:             */
1800:            public final int getCalculationStateCount() {
1801:                return calculationStateCount;
1802:            }
1803:
1804:            /**
1805:             * @param calculationStateCount The calculationStateCount to set.
1806:             */
1807:            public final void setCalculationStateCount(int calculationStateCount) {
1808:                this .calculationStateCount = calculationStateCount;
1809:            }
1810:
1811:            public void updateEndSentinel() {
1812:                if (getSuccessorList().isEmpty()) { // if pred has no successors, tell end sentinel about it
1813:                    project.addEndSentinelDependency(this );
1814:                } else { // make sure not in sentinel's list
1815:                    project.removeEndSentinelDependency(this );
1816:                }
1817:            }
1818:
1819:            public void updateStartSentinel() {
1820:                if (getPredecessorList().isEmpty()) { // if pred has no successors, tell end sentinel about it
1821:                    project.addStartSentinelDependency(this );
1822:                } else { // make sure not in sentinel's list
1823:                    project.removeStartSentinelDependency(this );
1824:                }
1825:            }
1826:
1827:            public final TaskSchedule getEarlySchedule() {
1828:                return earlySchedule;
1829:            }
1830:
1831:            public final TaskSchedule getLateSchedule() {
1832:                return lateSchedule;
1833:            }
1834:
1835:            public final TaskSchedule getSchedule(int scheduleType) {
1836:                if (scheduleType == TaskSchedule.CURRENT)
1837:                    return currentSchedule;
1838:                else if (scheduleType == TaskSchedule.EARLY)
1839:                    return earlySchedule;
1840:                else
1841:                    return lateSchedule;
1842:            }
1843:
1844:            /**
1845:             * Used for debugging primarily - says if a task was just modified by last recalculation - either has same count or is one less
1846:             * @return
1847:             */
1848:            public boolean isJustModified() {
1849:                if (project.getSchedulingAlgorithm() == null)
1850:                    return false;
1851:                return calculationStateCount
1852:                        + PredecessorTaskList.CALCULATION_STATUS_STEP >= project
1853:                        .getSchedulingAlgorithm().getCalculationStateCount();
1854:            }
1855:
1856:            public abstract boolean hasDuration();
1857:
1858:            /**
1859:             * @param markerStatus The markerStatus to set.
1860:             */
1861:            public final void setMarkerStatus(boolean markerStatus) {
1862:                this .markerStatus = markerStatus;
1863:            }
1864:
1865:            /**
1866:             * Set the task to be forward or rerverse scheduled
1867:             * @param forward
1868:             */
1869:            public void setForward(boolean forward) {
1870:                getCurrentSchedule().setForward(forward);
1871:                restrictToValidConstraintType();
1872:
1873:            }
1874:
1875:            /**
1876:             * Parent tasks have only 3 possible consraint types ASAP/ALAP (depending on forward or reverse scheduling), SNET, and FNLT
1877:             */
1878:            void restrictToValidConstraintType() {
1879:                setRawConstraintType(makeValidConstraintType(getConstraintType()));
1880:            }
1881:
1882:            protected int makeValidConstraintType(int type) {
1883:                if (isWbsParent()) { // parents have a limited choice of constraint types
1884:                    if (type == ConstraintType.FNLT
1885:                            || type == ConstraintType.SNET)
1886:                        return type;
1887:                    else
1888:                        return project.getDefaultConstraintType();
1889:                }
1890:                return type;
1891:
1892:            }
1893:
1894:            //	public boolean isNew() {
1895:            //		return hasKey.isNew();
1896:            //	}
1897:
1898:            public static Predicate instanceof Predicate() {
1899:                return new Predicate() {
1900:                    public boolean evaluate(Object arg0) {
1901:                        return arg0 instanceof  Task;
1902:                    }
1903:                };
1904:            }
1905:
1906:            public void invalidateSchedules() {
1907:                earlySchedule.invalidate();
1908:                lateSchedule.invalidate();
1909:            }
1910:
1911:            public Document getMasterDocument() {
1912:                if (getProject().getSchedulingAlgorithm() == null)
1913:                    return null;
1914:                return getProject().getSchedulingAlgorithm()
1915:                        .getMasterDocument();
1916:            }
1917:
1918:            public String getTaskAndProjectName() {
1919:                Project p = getOwningProject();
1920:                if (p == null)
1921:                    p = getProject();
1922:                return getName() + " (" + p.getName() + ")";
1923:            }
1924:
1925:            public String getSubprojectFile() {
1926:                return null;
1927:            }
1928:
1929:            public boolean fieldHideSubprojectFile(FieldContext fieldContext) {
1930:                return true;
1931:            }
1932:
1933:            public void setSubprojectFile(String sub) {
1934:            }
1935:
1936:            public boolean isSubprojectReadOnly() {
1937:                return false;
1938:            }
1939:
1940:            public boolean fieldHideSubprojectReadOnly(FieldContext fieldContext) {
1941:                return true;
1942:            }
1943:
1944:            public long getParentId(int outlineNumber) {
1945:                NodeModel model = project.getTaskOutline(outlineNumber);
1946:                if (model == null)
1947:                    return 0;
1948:                Node node = model.getParent(model.search(this ));
1949:                Object impl = node.getImpl();
1950:                if (impl != null && impl instanceof  HasKey)
1951:                    return ((HasKey) impl).getId();
1952:                return 0;
1953:            }
1954:
1955:            public int getOutlineLevel(int outlineNumber) {
1956:                NodeModel model = project.getTaskOutline(outlineNumber);
1957:                if (model == null)
1958:                    return 0;
1959:                Node node = model.getParent(model.search(this ));
1960:                return model.getHierarchy().getLevel(node);
1961:            }
1962:
1963:            public int getOutlineLevel() {
1964:                return getOutlineLevel(OutlineCollection.DEFAULT_OUTLINE);
1965:            }
1966:
1967:            public final int getDebugDependencyOrder() {
1968:                return debugDependencyOrder;
1969:            }
1970:
1971:            public final void setDebugDependencyOrder(int debugDependencyOrder) {
1972:                this .debugDependencyOrder = debugDependencyOrder;
1973:            }
1974:
1975:            public final long getLevelingDelay() {
1976:                return levelingDelay;
1977:            }
1978:
1979:            public final void setLevelingDelay(long levelingDelay) {
1980:                this .levelingDelay = levelingDelay;
1981:            }
1982:
1983:            public CustomFields getCustomFields() {
1984:                return customFields;
1985:            }
1986:
1987:            public void updateCachedDuration() {
1988:                setRawDuration(getDuration());
1989:            }
1990:
1991:            public boolean isDirty() {
1992:                return dirty || getStart() != getLastSavedStart()
1993:                        || getEnd() != getLastSavedFinish();
1994:            }
1995:
1996:            public void setDirty(boolean dirty) {
1997:                this .dirty = dirty;
1998:                if (dirty && project != null)
1999:                    project.setGroupDirty(true);
2000:            }
2001:
2002:            public boolean isMissedDeadline() {
2003:                if (deadline == 0)
2004:                    return false;
2005:                else
2006:                    return deadline < getEnd();
2007:            }
2008:
2009:            public final boolean isExternal() {
2010:                return external;
2011:            }
2012:
2013:            public final void setExternal(boolean external) {
2014:                this .external = external;
2015:            }
2016:
2017:            public final long getProjectId() {
2018:                return projectId;
2019:            }
2020:
2021:            public final void setProjectId(long projectId) {
2022:                this .projectId = projectId;
2023:            }
2024:
2025:            public Project getRootProject() {
2026:                Task parent = getWbsParentTask();
2027:                if (parent == null)
2028:                    return getProject();
2029:                return parent.getRootProject();
2030:            }
2031:
2032:            public Project getEnclosingProject() {
2033:                if (isSubproject())
2034:                    return ((SubProj) this ).getSubproject();
2035:                Task parent = getWbsParentTask();
2036:                if (parent == null)
2037:                    return getProject();
2038:                return parent.getEnclosingProject();
2039:            }
2040:
2041:            public SubProj getEnclosingSubproject() {
2042:                Task parent = getWbsParentTask();
2043:
2044:                if (parent == null)
2045:                    return null;
2046:                if (parent.isSubproject())
2047:                    return (SubProj) parent;
2048:                return parent.getEnclosingSubproject();
2049:            }
2050:
2051:            /**
2052:             * Will return a node in the master project that holds he subproject
2053:             * @return
2054:             */
2055:            public Node getEnclosingSubprojectNode() {
2056:                SubProj s = getEnclosingSubproject();
2057:                if (s == null)
2058:                    return null;
2059:                return ((Task) s).getProject().getTaskOutline().search(s);
2060:            }
2061:
2062:            public boolean liesInSubproject() {
2063:                Task parent = getWbsParentTask();
2064:                if (parent == null)
2065:                    return false;
2066:                if (parent.isSubproject())
2067:                    return true;
2068:                return parent.liesInSubproject();
2069:            }
2070:
2071:            public final boolean isInSubproject() {
2072:                return inSubproject;
2073:            }
2074:
2075:            public final void setInSubproject(boolean inSubproject) {
2076:                this .inSubproject = inSubproject;
2077:            }
2078:
2079:            public final Project getOwningProject() {
2080:                return owningProject;
2081:            }
2082:
2083:            public final void setOwningProject(Project owningProject) {
2084:                this .owningProject = owningProject;
2085:            }
2086:
2087:            public void copyScheduleTo(Task to) {
2088:                to.getCurrentSchedule().setStart(
2089:                        getCurrentSchedule().getStart());
2090:                to.getCurrentSchedule().setFinish(
2091:                        getCurrentSchedule().getFinish());
2092:                to.setRawDuration(getDuration());
2093:            }
2094:
2095:            /**
2096:             * Set all schedules to a fixed start and end
2097:             * @param start
2098:             * @param finish
2099:             */
2100:            protected void setAllSchedules(long start, long finish) {
2101:                getCurrentSchedule().setStart(start);
2102:                getCurrentSchedule().setFinish(finish);
2103:                getEarlySchedule().setStart(start);
2104:                getEarlySchedule().setFinish(finish);
2105:                getLateSchedule().setStart(start);
2106:                getLateSchedule().setFinish(finish);
2107:            }
2108:
2109:            public void setAllSchedulesToCurrentDates() {
2110:                long start = getCurrentSchedule().getStart();
2111:                long finish = getCurrentSchedule().getFinish();
2112:                setAllSchedules(start, finish);
2113:
2114:            }
2115:
2116:            public boolean isAssignable() {
2117:                return !isReadOnly();
2118:            }
2119:
2120:            public final long getLastSavedFinish() {
2121:                return lastSavedFinish;
2122:            }
2123:
2124:            public final void setLastSavedFinish(long currendFinish) {
2125:                this .lastSavedFinish = currendFinish;
2126:            }
2127:
2128:            public final long getLastSavedStart() {
2129:                return lastSavedStart;
2130:            }
2131:
2132:            public final void setLastSavedStart(long currentStart) {
2133:                this .lastSavedStart = currentStart;
2134:            }
2135:
2136:            public int getExpenseType() {
2137:                return expenseType;
2138:            }
2139:
2140:            public void setExpenseType(int budgetType) {
2141:                this .expenseType = budgetType;
2142:            }
2143:
2144:            public int getEffectiveExpenseType() {
2145:                int result = expenseType;
2146:                if (result == ExpenseType.NONE) {
2147:                    Task parent = getWbsParentTask();
2148:                    if (parent != null)
2149:                        result = parent.getEffectiveExpenseType();
2150:                }
2151:                if (result == ExpenseType.NONE)
2152:                    result = getOwningProject().getEffectiveExpenseType();
2153:                return result;
2154:            }
2155:
2156:            public boolean startsBeforeProject() { // special case for SNLT tasks that start before project
2157:                return (getConstraintType() == ConstraintType.SNLT // this was changed from SNET - MSP mistakenly displays SNET for these tasks
2158:                        && getPredecessorList().isEmpty() && getConstraintDate() < getOwningProject()
2159:                        .getStart());
2160:            }
2161:
2162:            /**
2163:             * Get value of delegateTo, or if null, recursively get parent's value
2164:             * @return
2165:             */
2166:            public Resource getDelegatedTo() {
2167:                if (delegatedTo == null) {
2168:                    Task parent = getWbsParentTask();
2169:                    if (parent != null)
2170:                        return parent.getDelegatedTo();
2171:                }
2172:                return delegatedTo;
2173:            }
2174:
2175:            public void setDelegatedTo(Resource delegatedTo) {
2176:                Resource old = this .delegatedTo;
2177:                this .delegatedTo = delegatedTo;
2178:                //		if (old == null) {
2179:                //			SwingUtilities.invokeLater(new Runnable() {
2180:                //
2181:                //				public void run() {
2182:                //					Task newOne = getOwningProject().cloneTask(Task.this);
2183:                //				}});
2184:                //		}
2185:            }
2186:
2187:            public boolean isDelegatedToUser() {
2188:                Resource del = getDelegatedTo();
2189:                return del != null
2190:                        && Environment.getLogin().equals(del.getUserAccount());
2191:            }
2192:
2193:            public String getDelegatedToName() {
2194:                Resource del = getDelegatedTo();
2195:                return del == null ? "" : del.getName();
2196:            }
2197:
2198:            public void forSnapshotsAssignments(Closure c, boolean onlyCurrent) {
2199:                if (onlyCurrent)
2200:                    forSnapshotsAssignments(c, -1);
2201:                else {
2202:                    for (int s = 0; s < Settings.numBaselines(); s++) {
2203:                        forSnapshotsAssignments(c, s);
2204:                    }
2205:                }
2206:            }
2207:
2208:            public void forSnapshotsAssignments(Closure c, int s) {
2209:                TaskSnapshot snapshot;
2210:                if (s == -1)
2211:                    snapshot = (TaskSnapshot) getCurrentSnapshot();
2212:                else
2213:                    snapshot = (TaskSnapshot) getSnapshot(new Integer(s));
2214:                if (snapshot == null)
2215:                    return;
2216:                AssociationList snapshotAssignments = snapshot
2217:                        .getHasAssignments().getAssignments();
2218:                if (snapshotAssignments.size() > 0) {
2219:                    for (Iterator j = snapshotAssignments.iterator(); j
2220:                            .hasNext();) {
2221:                        Assignment assignment = (Assignment) j.next();
2222:                        c.execute(assignment);
2223:                    }
2224:                }
2225:            }
2226:
2227:            public void forSnapshots(Closure c) {
2228:            }
2229:
2230:            public void forSnapshots(Closure c, int s) {
2231:            }
2232:
2233:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.