/*
Copyright 2003-2012 Dmitry Barashev, GanttProject Team
This file is part of GanttProject, an opensource project management tool.
GanttProject is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GanttProject is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GanttProject. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.ganttproject.parser;
import java.awt.Color;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import net.sourceforge.ganttproject.GPLogger;
import net.sourceforge.ganttproject.gui.TaskTreeUIFacade;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskManager;
import net.sourceforge.ganttproject.task.TaskManager.TaskBuilder;
import org.xml.sax.Attributes;
import com.google.common.base.Charsets;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import biz.ganttproject.core.chart.render.ShapePaint;
import biz.ganttproject.core.time.GanttCalendar;
public class TaskTagHandler extends AbstractTagHandler implements ParsingListener {
private final ParsingContext myContext;
private final TaskManager myManager;
private final TaskTreeUIFacade myTreeFacade;
private final Map<Integer, Boolean> myTaskIdToExpansionState = Maps.newHashMap();
public TaskTagHandler(TaskManager mgr, ParsingContext context, TaskTreeUIFacade treeFacade) {
super("task");
myManager = mgr;
myContext = context;
myTreeFacade = treeFacade;
}
@Override
protected boolean onStartElement(Attributes attrs) {
loadTask(attrs);
return true;
}
@Override
public void endElement(String namespaceURI, String sName, String qName) {
if (isMyTag(qName) && isTagStarted()) {
myContext.popTask();
if (myContext.isStackEmpty()) {
setTagStarted(false);
}
}
}
private void loadTask(Attributes attrs) {
String taskIdAsString = attrs.getValue("id");
int taskId;
try {
taskId = Integer.parseInt(taskIdAsString);
} catch (NumberFormatException e) {
throw new RuntimeException(
"Failed to parse the value '" + taskIdAsString + "' of attribute 'id' of tag <task>", e);
}
TaskBuilder builder = getManager().newTaskBuilder().withId(taskId);
String taskName = attrs.getValue("name");
if (taskName != null) {
builder = builder.withName(taskName);
}
String start = attrs.getValue("start");
if (start != null) {
builder = builder.withStartDate(GanttCalendar.parseXMLDate(start).getTime());
}
String duration = attrs.getValue("duration");
if (duration != null) {
try {
int length = Integer.parseInt(duration);
builder = builder.withDuration(getManager().createLength(length));
} catch (NumberFormatException e) {
throw new RuntimeException(
"Failed to parse the value '" + duration + "' of attribute 'duration' of tag <task>", e);
}
}
if (!myContext.isStackEmpty()) {
builder = builder.withParent(myContext.peekTask());
}
String isExpanded = attrs.getValue("expand");
if (isExpanded != null) {
builder = builder.withExpansionState(Boolean.parseBoolean(isExpanded));
}
String isLegacyMilestone = attrs.getValue("meeting");
if (Boolean.parseBoolean(isLegacyMilestone)) {
builder = builder.withLegacyMilestone();
}
Task task = builder.build();
myTaskIdToExpansionState.put(task.getTaskID(), task.getExpand());
// String newMilestone = attrs.getValue("milestone");
// if ("1".equals(newMilestone)) {
// task.setMilestone(true);
// }
String project = attrs.getValue("project");
if (project != null) {
task.setProjectTask(true);
}
String complete = attrs.getValue("complete");
if (complete != null) {
try {
task.setCompletionPercentage(Integer.parseInt(complete));
} catch (NumberFormatException e) {
throw new RuntimeException(
"Failed to parse the value '" + complete + "' of attribute 'complete' of tag <task>", e);
}
}
String priority = attrs.getValue("priority");
if (priority != null) {
task.setPriority(Task.Priority.fromPersistentValue(priority));
}
String color = attrs.getValue("color");
if (color != null) {
task.setColor(ColorValueParser.parseString(color));
}
String fixedStart = attrs.getValue("fixed-start");
if ("true".equals(fixedStart)) {
myContext.addTaskWithLegacyFixedStart(task);
}
String third = attrs.getValue("thirdDate");
if (third != null) {
task.setThirdDate(GanttCalendar.parseXMLDate(third));
}
String thirdConstraint = attrs.getValue("thirdDate-constraint");
if (thirdConstraint != null) {
try {
task.setThirdDateConstraint(Integer.parseInt(thirdConstraint));
} catch (NumberFormatException e) {
throw new RuntimeException("Failed to parse the value '" + thirdConstraint
+ "' of attribute 'thirdDate-constraint' of tag <task>", e);
}
}
String webLink_enc = attrs.getValue("webLink");
String webLink = webLink_enc;
if (webLink_enc != null)
try {
webLink = URLDecoder.decode(webLink_enc, Charsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
if (!GPLogger.log(e)) {
e.printStackTrace(System.err);
}
}
if (webLink != null) {
task.setWebLink(webLink);
}
String shape = attrs.getValue("shape");
if (shape != null) {
java.util.StringTokenizer st1 = new java.util.StringTokenizer(shape, ",");
int[] array = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
String token = "";
int count = 0;
while (st1.hasMoreTokens()) {
token = st1.nextToken();
array[count] = (new Integer(token)).intValue();
count++;
}
task.setShape(new ShapePaint(4, 4, array, Color.white, task.getColor()));
}
String costValue = attrs.getValue("cost-manual-value");
String costCalculated = attrs.getValue("cost-calculated");
if (costCalculated != null) {
task.getCost().setCalculated(Boolean.valueOf(costCalculated));
task.getCost().setValue(new BigDecimal(costValue));
} else {
task.getCost().setCalculated(true);
}
myContext.pushTask(task);
}
private TaskManager getManager() {
return myManager;
}
@Override
public void parsingStarted() {
}
@Override
public void parsingFinished() {
List<Task> tasksBottomUp = Lists.reverse(myManager.getTaskHierarchy().breadthFirstSearch(null, false));
for (Task t : tasksBottomUp) {
myTreeFacade.setExpanded(t, Objects.firstNonNull(myTaskIdToExpansionState.get(t.getTaskID()), Boolean.TRUE));
}
}
}