/* 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)); } } }