001: /**
002: * DefaultTask.java
003: * Created on 12.02.2003, 15:30:40 Alex
004: * Package: net.sf.memoranda
005: *
006: * @author Alex V. Alishevskikh, alex@openmechanics.net
007: * Copyright (c) 2003 Memoranda Team. http://memoranda.sf.net
008: */package net.sf.memoranda;
009:
010: import java.util.Collection;
011: import java.util.Vector;
012: import java.util.Calendar;
013:
014: import net.sf.memoranda.date.CalendarDate;
015: import net.sf.memoranda.date.CurrentDate;
016: import nu.xom.Attribute;
017: import nu.xom.Element;
018: import nu.xom.Elements;
019: import nu.xom.Node;
020:
021: /**
022: *
023: */
024: /*$Id: TaskImpl.java,v 1.15 2005/12/01 08:12:26 alexeya Exp $*/
025: public class TaskImpl implements Task, Comparable {
026:
027: private Element _element = null;
028: private TaskList _tl = null;
029:
030: /**
031: * Constructor for DefaultTask.
032: */
033: public TaskImpl(Element taskElement, TaskList tl) {
034: _element = taskElement;
035: _tl = tl;
036: }
037:
038: public Element getContent() {
039: return _element;
040: }
041:
042: public CalendarDate getStartDate() {
043: return new CalendarDate(_element.getAttribute("startDate")
044: .getValue());
045: }
046:
047: public void setStartDate(CalendarDate date) {
048: setAttr("startDate", date.toString());
049: }
050:
051: public CalendarDate getEndDate() {
052: String ed = _element.getAttribute("endDate").getValue();
053: if (ed != "")
054: return new CalendarDate(_element.getAttribute("endDate")
055: .getValue());
056: Task parent = this .getParentTask();
057: if (parent != null)
058: return parent.getEndDate();
059: Project pr = this ._tl.getProject();
060: if (pr.getEndDate() != null)
061: return pr.getEndDate();
062: return this .getStartDate();
063:
064: }
065:
066: public void setEndDate(CalendarDate date) {
067: if (date == null)
068: setAttr("endDate", "");
069: setAttr("endDate", date.toString());
070: }
071:
072: public long getEffort() {
073: Attribute attr = _element.getAttribute("effort");
074: if (attr == null) {
075: return 0;
076: } else {
077: try {
078: return Long.parseLong(attr.getValue());
079: } catch (NumberFormatException e) {
080: return 0;
081: }
082: }
083: }
084:
085: public void setEffort(long effort) {
086: setAttr("effort", String.valueOf(effort));
087: }
088:
089: /*
090: * @see net.sf.memoranda.Task#getParentTask()
091: */
092: public Task getParentTask() {
093: Node parentNode = _element.getParent();
094: if (parentNode instanceof Element) {
095: Element parent = (Element) parentNode;
096: if (parent.getLocalName().equalsIgnoreCase("task"))
097: return new TaskImpl(parent, _tl);
098: }
099: return null;
100: }
101:
102: public String getParentId() {
103: Task parent = this .getParentTask();
104: if (parent != null)
105: return parent.getID();
106: return null;
107: }
108:
109: public String getDescription() {
110: Element this Element = _element
111: .getFirstChildElement("description");
112: if (this Element == null) {
113: return null;
114: } else {
115: return this Element.getValue();
116: }
117: }
118:
119: public void setDescription(String s) {
120: Element desc = _element.getFirstChildElement("description");
121: if (desc == null) {
122: desc = new Element("description");
123: desc.appendChild(s);
124: _element.appendChild(desc);
125: } else {
126: desc.removeChildren();
127: desc.appendChild(s);
128: }
129: }
130:
131: /**s
132: * @see net.sf.memoranda.Task#getStatus()
133: */
134: public int getStatus(CalendarDate date) {
135: CalendarDate start = getStartDate();
136: CalendarDate end = getEndDate();
137: if (isFrozen())
138: return Task.FROZEN;
139: if (isCompleted())
140: return Task.COMPLETED;
141:
142: if (date.inPeriod(start, end)) {
143: if (date.equals(end))
144: return Task.DEADLINE;
145: else
146: return Task.ACTIVE;
147: } else if (date.before(start)) {
148: return Task.SCHEDULED;
149: }
150:
151: if (start.after(end)) {
152: return Task.ACTIVE;
153: }
154:
155: return Task.FAILED;
156: }
157:
158: /**
159: * Method isDependsCompleted.
160: * @return boolean
161: */
162: /*
163: private boolean isDependsCompleted() {
164: Vector v = (Vector) getDependsFrom();
165: boolean check = true;
166: for (Enumeration en = v.elements(); en.hasMoreElements();) {
167: Task t = (Task) en.nextElement();
168: if (t.getStatus() != Task.COMPLETED)
169: check = false;
170: }
171: return check;
172: }
173: */
174: private boolean isFrozen() {
175: return _element.getAttribute("frozen") != null;
176: }
177:
178: private boolean isCompleted() {
179: return getProgress() == 100;
180: }
181:
182: /**
183: * @see net.sf.memoranda.Task#getID()
184: */
185: public String getID() {
186: return _element.getAttribute("id").getValue();
187: }
188:
189: /**
190: * @see net.sf.memoranda.Task#getText()
191: */
192: public String getText() {
193: return _element.getFirstChildElement("text").getValue();
194: }
195:
196: public String toString() {
197: return getText();
198: }
199:
200: /**
201: * @see net.sf.memoranda.Task#setText()
202: */
203: public void setText(String s) {
204: _element.getFirstChildElement("text").removeChildren();
205: _element.getFirstChildElement("text").appendChild(s);
206: }
207:
208: /**
209: * @see net.sf.memoranda.Task#freeze()
210: */
211: public void freeze() {
212: setAttr("frozen", "yes");
213: }
214:
215: /**
216: * @see net.sf.memoranda.Task#unfreeze()
217: */
218: public void unfreeze() {
219: if (this .isFrozen())
220: _element.removeAttribute(new Attribute("frozen", "yes"));
221: }
222:
223: /**
224: * @see net.sf.memoranda.Task#getDependsFrom()
225: */
226: public Collection getDependsFrom() {
227: Vector v = new Vector();
228: Elements deps = _element.getChildElements("dependsFrom");
229: for (int i = 0; i < deps.size(); i++) {
230: String id = deps.get(i).getAttribute("idRef").getValue();
231: Task t = _tl.getTask(id);
232: if (t != null)
233: v.add(t);
234: }
235: return v;
236: }
237:
238: /**
239: * @see net.sf.memoranda.Task#addDependsFrom(net.sf.memoranda.Task)
240: */
241: public void addDependsFrom(Task task) {
242: Element dep = new Element("dependsFrom");
243: dep.addAttribute(new Attribute("idRef", task.getID()));
244: _element.appendChild(dep);
245: }
246:
247: /**
248: * @see net.sf.memoranda.Task#removeDependsFrom(net.sf.memoranda.Task)
249: */
250: public void removeDependsFrom(Task task) {
251: Elements deps = _element.getChildElements("dependsFrom");
252: for (int i = 0; i < deps.size(); i++) {
253: String id = deps.get(i).getAttribute("idRef").getValue();
254: if (id.equals(task.getID())) {
255: _element.removeChild(deps.get(i));
256: return;
257: }
258: }
259: }
260:
261: /**
262: * @see net.sf.memoranda.Task#getProgress()
263: */
264: public int getProgress() {
265: return new Integer(_element.getAttribute("progress").getValue())
266: .intValue();
267: }
268:
269: /**
270: * @see net.sf.memoranda.Task#setProgress(int)
271: */
272: public void setProgress(int p) {
273: if ((p >= 0) && (p <= 100))
274: setAttr("progress", new Integer(p).toString());
275: }
276:
277: /**
278: * @see net.sf.memoranda.Task#getPriority()
279: */
280: public int getPriority() {
281: Attribute pa = _element.getAttribute("priority");
282: if (pa == null)
283: return Task.PRIORITY_NORMAL;
284: return new Integer(pa.getValue()).intValue();
285: }
286:
287: /**
288: * @see net.sf.memoranda.Task#setPriority(int)
289: */
290: public void setPriority(int p) {
291: setAttr("priority", String.valueOf(p));
292: }
293:
294: private void setAttr(String a, String value) {
295: Attribute attr = _element.getAttribute(a);
296: if (attr == null)
297: _element.addAttribute(new Attribute(a, value));
298: else
299: attr.setValue(value);
300: }
301:
302: /**
303: * A "Task rate" is an informal index of importance of the task
304: * considering priority, number of days to deadline and current
305: * progress.
306: *
307: * rate = (100-progress) / (numOfDays+1) * (priority+1)
308: * @param CalendarDate
309: * @return long
310: */
311:
312: private long calcTaskRate(CalendarDate d) {
313: Calendar endDateCal = getEndDate().getCalendar();
314: Calendar dateCal = d.getCalendar();
315: int numOfDays = (endDateCal.get(Calendar.YEAR) * 365 + endDateCal
316: .get(Calendar.DAY_OF_YEAR))
317: - (dateCal.get(Calendar.YEAR) * 365 + dateCal
318: .get(Calendar.DAY_OF_YEAR));
319: if (numOfDays < 0)
320: return -1; //Something wrong ?
321: return (100 - getProgress()) / (numOfDays + 1)
322: * (getPriority() + 1);
323: }
324:
325: /**
326: * @see net.sf.memoranda.Task#getRate()
327: */
328:
329: public long getRate() {
330: /* Task t = (Task)task;
331: switch (mode) {
332: case BY_IMP_RATE: return -1*calcTaskRate(t, date);
333: case BY_END_DATE: return t.getEndDate().getDate().getTime();
334: case BY_PRIORITY: return 5-t.getPriority();
335: case BY_COMPLETION: return 100-t.getProgress();
336: }
337: return -1;
338: */
339: return -1 * calcTaskRate(CurrentDate.get());
340: }
341:
342: /*
343: * Comparable interface
344: */
345:
346: public int compareTo(Object o) {
347: Task task = (Task) o;
348: if (getRate() > task.getRate())
349: return 1;
350: else if (getRate() < task.getRate())
351: return -1;
352: else
353: return 0;
354: }
355:
356: public boolean equals(Object o) {
357: return ((o instanceof Task) && (((Task) o).getID().equals(this
358: .getID())));
359: }
360:
361: /*
362: * @see net.sf.memoranda.Task#getSubTasks()
363: */
364: public Collection getSubTasks() {
365: Elements subTasks = _element.getChildElements("task");
366: return convertToTaskObjects(subTasks);
367: }
368:
369: private Collection convertToTaskObjects(Elements tasks) {
370: Vector v = new Vector();
371: for (int i = 0; i < tasks.size(); i++) {
372: Task t = new TaskImpl(tasks.get(i), _tl);
373: v.add(t);
374: }
375: return v;
376: }
377:
378: /*
379: * @see net.sf.memoranda.Task#getSubTask(java.lang.String)
380: */
381: public Task getSubTask(String id) {
382: Elements subTasks = _element.getChildElements("task");
383: for (int i = 0; i < subTasks.size(); i++) {
384: if (subTasks.get(i).getAttribute("id").getValue()
385: .equals(id))
386: return new TaskImpl(subTasks.get(i), _tl);
387: }
388: return null;
389: }
390:
391: /*
392: * @see net.sf.memoranda.Task#hasSubTasks()
393: */
394: public boolean hasSubTasks(String id) {
395: Elements subTasks = _element.getChildElements("task");
396: for (int i = 0; i < subTasks.size(); i++)
397: if (subTasks.get(i).getAttribute("id").getValue()
398: .equals(id))
399: return true;
400: return false;
401: }
402:
403: }
|