--- /dev/null
+#!/bin/sh
+echo
+echo "Plan Build System"
+echo "----------------"
+echo
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "ERROR: JAVA_HOME not found in your environment."
+ echo
+ echo "Please, set the JAVA_HOME variable in your environment to match the"
+ echo "location of the Java Virtual Machine you want to use."
+ exit 1
+fi
+LIBDIR=../../lib
+LOCALCLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/classes.zip:$LIBDIR/ant.jar:$LIBDIR/batik.jar:$LIBDIR/buildtools.jar:$LIBDIR/xerces-1.4.3.jar:$LIBDIR/xalan-2.2D11.jar:../../build/fop.jar
+ANT_HOME=$LIBDIR
+
+echo
+CP=$LOCALCLASSPATH
+echo Building with classpath $CP
+
+
+echo Starting Ant...
+echo
+
+$JAVA_HOME/bin/java -Dant.home=$ANT_HOME -classpath "$CP" org.apache.tools.ant.Main $*
--- /dev/null
+<?xml version="1.0"?>
+
+<!-- ===========================================================================
+
+============================================================================ -->
+
+<project default="package" basedir=".">
+
+ <!-- =================================================================== -->
+ <!-- Initialization target -->
+ <!-- =================================================================== -->
+ <target name="init">
+ <tstamp/>
+ <property name="Name" value="Plan"/>
+ <property name="name" value="plan"/>
+ <property name="version" value="0.1-CVS"/>
+ <filter token="version" value="${version}"/>
+ <property name="year" value="2001"/>
+
+ <echo message="------------------- ${Name} ${version} [${year}] ----------------"/>
+
+ <property name="build.compiler" value="classic"/>
+ <property name="debug" value="off"/>
+ <property name="optimize" value="on"/>
+ <property name="deprecation" value="off"/>
+
+ <property name="src.dir" value="./src"/>
+ <property name="lib.dir" value="./lib"/>
+ <property name="packages" value="org.apache.fop.*"/>
+
+ <property name="build.dir" value="./build"/>
+ <property name="build.src" value="./build/src"/>
+ <property name="build.dest" value="./build/classes"/>
+
+ <property name="resource.dir" value="resources"/>
+ <property name="plan.dir" value="org/apache/fop/plan"/>
+
+ <property name="xslt" value="org.apache.xalan.xslt.Process"/>
+
+ <property name="main.class" value="org.apache.fop.plan.Main"/>
+ <property name="runtime.classpath" value="fop.jar xerces-1.4.3.jar xalan-2.4D11.jar batik.jar"/>
+
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Help on usage -->
+ <!-- =================================================================== -->
+ <target name="usage">
+ <echo message=""/>
+ <echo message=""/>
+ <echo message="${Name} Build file"/>
+ <echo message="-------------------------------------------------------------"/>
+ <echo message=""/>
+ <echo message=" available targets are:"/>
+ <echo message=""/>
+ <echo message=" package --> generates the ${name}.jar file (default)"/>
+ <echo message=" compile --> compiles the source code"/>
+ <echo message=" clean --> cleans up the directory"/>
+ <echo message=" site --> generates the ${Name} web site (not yet implemented)"/>
+ <echo message=""/>
+ <echo message=" See the comments inside the build.xml file for more details."/>
+ <echo message="-------------------------------------------------------------"/>
+ <echo message=""/>
+ <echo message=""/>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Prepares the build directory -->
+ <!-- =================================================================== -->
+ <target name="prepare" depends="init">
+ <!-- create directories -->
+ <echo message="Preparing the build directories"/>
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${build.src}"/>
+ <mkdir dir="${build.src}/${plan.dir}"/>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Prepares the source code -->
+ <!-- =================================================================== -->
+ <target name="prepare-src" depends="prepare">
+ <!-- copy src files -->
+ <copy todir="${build.src}">
+ <fileset dir="${src.dir}"
+ excludes="**/Makefile*, **/package.html"/>
+ </copy>
+ <copy todir="${build.dest}/">
+ <fileset dir="${resource.dir}"/>
+ </copy>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Compiles the source directory -->
+ <!-- =================================================================== -->
+ <target name="compile" depends="prepare-src">
+ <echo message="Compiling the sources "/>
+ <!-- create directories -->
+ <mkdir dir="${build.dest}"/>
+
+ <javac srcdir="${build.src}"
+ destdir="${build.dest}"
+ debug="${debug}"
+ deprecation="${deprecation}"
+ optimize="${optimize}"
+ excludes=""/>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Creates the class package -->
+ <!-- =================================================================== -->
+ <target name="package" depends="compile">
+ <echo message="Creating the jar file ${build.dir}/${name}.jar"/>
+ <tstamp>
+ <format property="ts" pattern="yyyyMMdd-HHmmss-z"/>
+ </tstamp>
+
+ <jar jarfile="${build.dir}/${name}.jar"
+ basedir="${build.dest}"
+ includes="**">
+ <manifest>
+ <attribute name="Main-Class" value="${main.class}"/>
+ <attribute name="Class-Path" value="${runtime.classpath}"/>
+ <attribute name="Implementation-Title" value="${Name}"/>
+ <attribute name="Implementation-Version" value="${version}"/>
+ <attribute name="Implementation-Vendor" value="Apache Software Foundation (http://xml.apache.org/fop/)"/>
+ <attribute name="Build-Id" value="${ts} (${user.name} [${os.name} ${os.version} ${os.arch}])"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Clean targets -->
+ <!-- =================================================================== -->
+ <target name="clean" depends="init">
+ <delete dir="${build.dir}"/>
+ </target>
+
+</project>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<plan xmlns="http://xml.apache.org/fop/plan" width="500" height="300" start="38320523" end="38320706">
+<title>Plan for June</title>
+<events>
+
+<group name="Bio-Park">
+<action type="grouping" id="construction">
+<label>Panel Installation</label>
+<owner>Constuctor Team</owner>
+<startdate>38320518</startdate>
+<enddate>38320607</enddate>
+</action>
+<action type="task" belongs="construction">
+<label>Integrety Test</label>
+<owner>Constuctor Team</owner>
+<startdate>38320527</startdate>
+<enddate>38320608</enddate>
+</action>
+<action type="milestone" depends="construction">
+<label>Shell Complete</label>
+<owner>Constuctor Team</owner>
+<startdate>38320608</startdate>
+</action>
+<action type="grouping">
+<label>Environment Installation</label>
+<owner>Enviros</owner>
+<startdate>38320608</startdate>
+<enddate>38320623</enddate>
+</action>
+<action type="task">
+<label>Gas</label>
+<owner>Enviros</owner>
+<startdate>38320608</startdate>
+<enddate>38320612</enddate>
+</action>
+</group>
+
+<group name="Education Centre">
+<action type="grouping">
+<label>Plan Optimisation</label>
+<owner>Simulators</owner>
+<startdate>38320602</startdate>
+<enddate>38320820</enddate>
+</action>
+<action type="task">
+<label>Simulation Params</label>
+<owner>Simulators</owner>
+<startdate>38320602</startdate>
+<enddate>38320610</enddate>
+</action>
+<action type="milestone">
+<label>Preparation Complete</label>
+<owner>Simulators</owner>
+<startdate>38320610</startdate>
+</action>
+<action type="grouping" id="simulation">
+<label>Paths</label>
+<owner>Simulators</owner>
+<startdate>38320610</startdate>
+<enddate>38320630</enddate>
+</action>
+<action type="task" id="opt" belongs="simulation">
+<label>Optimal Path</label>
+<owner>Simulators</owner>
+<startdate>38320610</startdate>
+<enddate>38320617</enddate>
+</action>
+<action type="task" belongs="simulation">
+<label>Alternatives</label>
+<owner>Simulators</owner>
+<startdate>38320617</startdate>
+<enddate>38320621</enddate>
+</action>
+<action type="task" depends="opt" belongs="simulation">
+<label>Risk Determination</label>
+<owner>Simulators</owner>
+<startdate>38320621</startdate>
+<enddate>38320630</enddate>
+</action>
+</group>
+
+</events>
+</plan>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master
+ margin-right="1.5cm"
+ margin-left="1.5cm"
+ margin-bottom="2cm"
+ margin-top="1cm"
+ page-width="21cm"
+ page-height="29.7cm"
+ master-name="first">
+ <fo:region-before extent="1cm"/>
+ <fo:region-body margin-top="1cm"/>
+ <fo:region-after extent="1.5cm"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="first">
+ <fo:static-content flow-name="xsl-region-before">
+ <fo:block line-height="14pt" font-size="10pt"
+ text-align="end">Plan Extension</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="xsl-region-after">
+ <fo:block line-height="14pt" font-size="10pt"
+ text-align="end">Page <fo:page-number/></fo:block>
+ </fo:static-content>
+
+ <fo:flow flow-name="xsl-region-body">
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+ The Plan Extension
+ </fo:block>
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+The plan extension is an addition to FOP that can be used to produce a
+simple plan diagram with tasks etc.
+ </fo:block>
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+ Options
+ </fo:block>
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+There a few basic options to specify the width, height and type of graph.
+The start and end date to display is optional.
+The locale specific information can also be specified.
+All other options are set in the style attribute.
+ </fo:block>
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+ Types of Graphs
+ </fo:block>
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+ Sample Action Plan
+ </fo:block>
+
+ <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
+<fo:block space-after.optimum="5pt">
+<fo:instream-foreign-object>
+<plan xmlns="http://xml.apache.org/fop/plan" width="500" height="200" start="20020612" end="20020702">
+<title>Example Plan</title>
+<events>
+
+<group name="Task Group">
+<action type="grouping" id="gr1">
+<label>First Task</label>
+<owner>Team</owner>
+<startdate>20020618</startdate>
+<enddate>20020630</enddate>
+</action>
+<action type="task" belongs="gr1">
+<label>Another Task</label>
+<owner>Team</owner>
+<startdate>20020620</startdate>
+<enddate>20020627</enddate>
+</action>
+<action type="milestone" depends="gr1">
+<label>Milestone</label>
+<owner>Team</owner>
+<startdate>20020628</startdate>
+</action>
+<action type="grouping">
+<label>Task</label>
+<owner>Team</owner>
+<startdate>20020620</startdate>
+<enddate>20020630</enddate>
+</action>
+<action type="task">
+<label>Difficult Task</label>
+<owner>individual</owner>
+<startdate>20020620</startdate>
+<enddate>20020630</enddate>
+</action>
+</group>
+
+</events>
+</plan>
+</fo:instream-foreign-object>
+</fo:block>
+
+ </fo:block>
+
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
+
--- /dev/null
+org.apache.fop.plan.PlanElementMapping
+
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.*;
+import java.text.*;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.font.FontRenderContext;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.*;
+import org.apache.fop.apps.*;
+import org.apache.fop.datatypes.*;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.svg.*;
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
+public class ActionInfo {
+ Date startDate;
+ Date endDate;
+ String owner;
+ String label;
+ int type = TASK;
+ public static final int TASK = 1;
+ public static final int MILESTONE = 2;
+ public static final int GROUPING = 3;
+ String dependant = "";
+
+ public void setType(int t) {
+ type = t;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setLabel(String str) {
+ label = str;
+ }
+
+ public void setOwner(String str) {
+ owner = str;
+ }
+
+ public void setStartDate(Date sd) {
+ startDate = sd;
+ if (endDate == null) {
+ endDate = startDate;
+ }
+ }
+
+ public void setEndDate(Date ed) {
+ endDate = ed;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.*;
+import java.text.*;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.font.FontRenderContext;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.*;
+import org.apache.fop.apps.*;
+import org.apache.fop.datatypes.*;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.svg.*;
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
+public class EventList {
+ ArrayList data = new ArrayList();
+
+ public void addGroupInfo(GroupInfo set) {
+ data.add(set);
+ }
+
+ public int getSize() {
+ return data.size();
+ }
+
+ public GroupInfo getGroupInfo(int count) {
+ return (GroupInfo) data.get(count);
+ }
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.*;
+import java.text.*;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.font.FontRenderContext;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.*;
+import org.apache.fop.apps.*;
+import org.apache.fop.datatypes.*;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.svg.*;
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
+public class GroupInfo {
+ String name;
+ ArrayList actions = new ArrayList();
+
+ public GroupInfo(String n) {
+ name = n;
+ }
+
+ public void addActionInfo(ActionInfo ai) {
+ actions.add(ai);
+ }
+
+ public int getSize() {
+ return actions.size();
+ }
+
+ public ActionInfo getActionInfo(int c) {
+ return (ActionInfo) actions.get(c);
+ }
+
+ public String getName() {
+ return name;
+ }
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.io.*;
+import org.w3c.dom.*;
+
+import org.apache.batik.transcoder.svg2svg.SVGTranscoder;
+import org.apache.batik.transcoder.TranscoderInput;
+import org.apache.batik.transcoder.TranscoderOutput;
+
+public class Main {
+
+ public static void main(String[] args) {
+ Main main = new Main();
+ main.convert(args);
+ System.exit(0);
+ }
+
+ public Main() {
+ }
+
+ public void convert(String[] params) {
+ if (params.length != 2) {
+ System.out.println("arguments: plan.xml output.svg");
+ return;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(params[0]);
+ Document doc = createSVGDocument(fis);
+ SVGTranscoder svgT = new SVGTranscoder();
+ TranscoderInput input = new TranscoderInput(doc);
+ Writer ostream = new FileWriter(params[1]);
+ TranscoderOutput output = new TranscoderOutput(ostream);
+ svgT.transcode(input, output);
+ ostream.flush();
+ ostream.close();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Document createSVGDocument(InputStream is) {
+ Document doc = null;
+
+ Element svgRoot = null;
+ try {
+ // DOMImplementation impl = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
+ // String ns = GraphElementMapping.URI;
+ // doc = impl.createDocument(ns, "graph", null);
+ doc = javax.xml.parsers.DocumentBuilderFactory.newInstance().
+ newDocumentBuilder().parse(is);
+
+ svgRoot = doc.getDocumentElement();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ PlanRenderer gr = new PlanRenderer();
+ gr.setFontInfo("sansserif", 12);
+ Document svgdoc = gr.createSVGDocument(doc);
+ return svgdoc;
+ }
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.HashMap;
+
+import org.w3c.dom.Document;
+
+public interface PlanDrawer {
+ public Document createDocument(EventList data, float w, float h,
+ HashMap hints);
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.geom.Point2D;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.svg.*;
+import org.apache.fop.apps.FOPException;
+
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+import org.xml.sax.Attributes;
+
+public class PlanElement extends PlanObj {
+ Document svgDoc = null;
+ float width;
+ float height;
+
+ public PlanElement(FONode parent) {
+ super(parent);
+ }
+
+ public void handleAttrs(Attributes attlist) throws FOPException {
+ super.handleAttrs(attlist);
+ createBasicDocument();
+ }
+
+ public void convertToSVG() {
+ if(svgDoc == null && doc != null) {
+ PlanRenderer pr = new PlanRenderer();
+ pr.setFontInfo("Helvetica", 12);
+ svgDoc = pr.createSVGDocument(doc);
+ width = pr.getWidth();
+ height = pr.getHeight();
+
+ doc = svgDoc;
+ }
+
+ }
+
+ public Document getDocument() {
+ convertToSVG();
+ return doc;
+ }
+
+ public String getDocumentNamespace() {
+ return "http://www.w3.org/2000/svg";
+ }
+
+ public Point2D getDimension(Point2D view) {
+ convertToSVG();
+ return new Point2D.Float(width, height);
+ }
+}
+
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import org.apache.fop.fo.*;
+
+import java.util.HashMap;
+
+public class PlanElementMapping implements ElementMapping {
+
+ public static final String URI = "http://xml.apache.org/fop/plan";
+
+ private static HashMap foObjs = null;
+
+ private static synchronized void setupPlan() {
+ if (foObjs == null) {
+ foObjs = new HashMap();
+ foObjs.put("plan", new PE());
+ foObjs.put(DEFAULT, new PlanMaker());
+ }
+ }
+
+ public void addToBuilder(FOTreeBuilder builder) {
+ setupPlan();
+ builder.addMapping(URI, foObjs);
+ }
+
+ static class PlanMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PlanObj(parent);
+ }
+ }
+
+ static class PE extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PlanElement(parent);
+ }
+ }
+
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import org.apache.fop.fo.*;
+
+
+public class PlanHints {
+ public static final String PLAN_BORDER = "border";
+ public static final String PLAN_LEGEND = "legend";
+ public static final String FONT_FAMILY = "font-family";
+ public static final String FONT_SIZE = "font-size";
+ public static final String LEGEND_TYPE = "legendType";
+ public static final String LOCALE = "locale";
+ public static final String LABEL_TYPE = "labelType";
+ public static final String LABEL_FONT_SIZE = "labelFontSize";
+ public static final String LABEL_FONT = "labelFont";
+
+}
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+// FOP
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.XMLObj;
+
+/**
+ * Since SVG objects are not layed out then this class checks
+ * that this element is not being layed out inside some incorrect
+ * element.
+ */
+public class PlanObj extends XMLObj {
+
+ /**
+ *
+ * @param parent the parent formatting object
+ */
+ public PlanObj(FONode parent) {
+ super(parent);
+ }
+
+ public String getNameSpace() {
+ return "http://xml.apache.org/fop/plan";
+ }
+}
+
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.*;
+import java.text.*;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.font.FontRenderContext;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.*;
+import org.apache.fop.apps.*;
+import org.apache.fop.datatypes.*;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.svg.*;
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
+public class PlanRenderer {
+ final static String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
+ String fontFamily = "sansserif";
+ float fontSize = 12;
+ private String type = "";
+ private String lang = "";
+ private String country = "";
+ private String variant = "";
+ float width;
+ float height;
+ float topEdge;
+ float rightEdge;
+ HashMap hints = new HashMap();
+
+ String[] colours;
+ String[] darkcolours;
+
+ public PlanRenderer() {
+ }
+
+ public void setFontInfo(String fam, float si) {
+ fontFamily = fam;
+ fontSize = si;
+ }
+
+ public float getWidth() {
+ return width;
+ }
+
+ public float getHeight() {
+ return height;
+ }
+
+ protected float toFloat(String str) {
+ return Float.parseFloat(str);
+ }
+
+ public Document createSVGDocument(Document planDoc) {
+
+ Element svgRoot = planDoc.getDocumentElement();
+
+ width = toFloat(svgRoot.getAttribute("width"));
+ height = toFloat(svgRoot.getAttribute("height"));
+ type = svgRoot.getAttribute("type");
+ lang = svgRoot.getAttribute("lang");
+ country = svgRoot.getAttribute("country");
+ variant = svgRoot.getAttribute("variant");
+ String style = svgRoot.getAttribute("style");
+ parseStyle(style);
+
+ Locale locale = new Locale(lang, country == null ? "" : country,
+ variant == null ? "" : variant);
+
+ String start = svgRoot.getAttribute("start");
+ String end = svgRoot.getAttribute("end");
+ Date sd = getDate(start, locale);
+ Date ed = getDate(end, locale);
+
+ String title = "";
+ EventList data = null;
+ NodeList childs = svgRoot.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ String nname = obj.getNodeName();
+ if (nname.equals("title")) {
+ title = ((Element) obj).getFirstChild().getNodeValue();
+ } else if (nname.equals("events")) {
+ data = getEvents((Element) obj, locale);
+ }
+ }
+
+ SimplePlanDrawer planDrawer = new SimplePlanDrawer();
+ planDrawer.setStartDate(sd);
+ planDrawer.setEndDate(ed);
+ hints.put(PlanHints.FONT_FAMILY, fontFamily);
+ hints.put(PlanHints.FONT_SIZE, new Float(fontSize));
+ hints.put(PlanHints.LOCALE, locale);
+ Document doc =
+ planDrawer.createDocument(data, width, height, hints);
+ return doc;
+ }
+
+ protected void parseStyle(String style) {
+ hints.put(PlanHints.PLAN_BORDER, new Boolean(true));
+ hints.put(PlanHints.FONT_FAMILY, fontFamily);
+ hints.put(PlanHints.FONT_SIZE, new Float(fontSize));
+ hints.put(PlanHints.LABEL_FONT_SIZE, new Float(fontSize));
+ hints.put(PlanHints.LABEL_FONT, fontFamily);
+ hints.put(PlanHints.LABEL_TYPE, "textOnly");
+
+ StringTokenizer st = new StringTokenizer(style, ";");
+ while (st.hasMoreTokens()) {
+ String pair = st.nextToken().trim();
+ int index = pair.indexOf(":");
+ String name = pair.substring(0, index).trim();
+ String val = pair.substring(index + 1).trim();
+ if (name.equals(PlanHints.PLAN_BORDER)) {
+ hints.put(name, Boolean.valueOf(val));
+ } else if (name.equals(PlanHints.FONT_SIZE)) {
+ hints.put(name, Float.valueOf(val));
+ } else if (name.equals(PlanHints.LABEL_FONT_SIZE)) {
+ hints.put(name, Float.valueOf(val));
+ } else {
+ hints.put(name, val);
+ }
+ }
+ }
+
+ public ActionInfo getActionInfo(Element ele, Locale locale) {
+ String t = ele.getAttribute("type");
+
+ NodeList childs = ele.getChildNodes();
+ ActionInfo data = new ActionInfo();
+ if (t.equals("milestone")) {
+ data.setType(ActionInfo.MILESTONE);
+ } else if (t.equals("task")) {
+ data.setType(ActionInfo.TASK);
+ } else if (t.equals("grouping")) {
+ data.setType(ActionInfo.GROUPING);
+ } else {
+ }
+
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ String nname = obj.getNodeName();
+ if (nname.equals("label")) {
+ String dat = ((Element) obj).getFirstChild().getNodeValue();
+ data.setLabel(dat);
+ } else if (nname.equals("owner")) {
+ String dat = ((Element) obj).getFirstChild().getNodeValue();
+ data.setOwner(dat);
+ } else if (nname.equals("startdate")) {
+ Date dat = getDate((Element) obj, locale);
+ data.setStartDate(dat);
+ } else if (nname.equals("enddate")) {
+ Date dat = getDate((Element) obj, locale);
+ data.setEndDate(dat);
+ }
+ }
+ return data;
+ }
+
+ public EventList getEvents(Element ele, Locale locale) {
+ EventList data = new EventList();
+ NodeList childs = ele.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("group")) {
+ GroupInfo dat = getGroupInfo((Element) obj, locale);
+ data.addGroupInfo(dat);
+ }
+ }
+ return data;
+ }
+
+ public GroupInfo getGroupInfo(Element ele, Locale locale) {
+ NodeList childs = ele.getChildNodes();
+ GroupInfo data = new GroupInfo(ele.getAttribute("name"));
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("action")) {
+ ActionInfo dat = getActionInfo((Element) obj, locale);
+ data.addActionInfo(dat);
+ }
+ }
+ return data;
+ }
+
+ public Date getDate(Element ele, Locale locale) {
+ String label = ele.getFirstChild().getNodeValue();
+ return getDate(label, locale);
+ }
+
+ public Date getDate(String label, Locale locale) {
+ Calendar cal = Calendar.getInstance(locale);
+
+ String str;
+ str = label.substring(0, 4);
+ int intVal = Integer.valueOf(str).intValue();
+ cal.set(Calendar.YEAR, intVal);
+
+ str = label.substring(4, 6);
+ intVal = Integer.valueOf(str).intValue();
+ cal.set(Calendar.MONTH, intVal - 1);
+
+ str = label.substring(6, 8);
+ intVal = Integer.valueOf(str).intValue();
+ cal.set(Calendar.DATE, intVal);
+ return cal.getTime();
+ }
+}
+
--- /dev/null
+/* $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.plan;
+
+import java.util.*;
+import java.text.*;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.font.FontRenderContext;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.*;
+import org.apache.fop.apps.*;
+import org.apache.fop.datatypes.*;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.svg.*;
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
+public class SimplePlanDrawer implements PlanDrawer {
+ final static String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
+ float fontSize;
+ HashMap hints;
+ java.awt.Font font = null;
+ boolean bord = false;
+ float lSpace = 15;
+ float width;
+ float height;
+ float topEdge;
+ float rightEdge;
+
+ String[] colours;
+ String[] darkcolours;
+
+ Date startDate;
+ Date endDate;
+
+ public void setStartDate(Date sd) {
+ startDate = sd;
+ }
+
+ public void setEndDate(Date ed) {
+ endDate = ed;
+ }
+
+ public Document createDocument(EventList data, float w, float h,
+ HashMap hints) {
+ this.width = w;
+ this.height = h;
+ this.hints = hints;
+ fontSize = ((Float) hints.get(PlanHints.FONT_SIZE)).floatValue();
+ bord = ((Boolean) hints.get(PlanHints.PLAN_BORDER)).booleanValue();
+
+ String title = "";
+
+ DOMImplementation impl =
+ SVGDOMImplementation.getDOMImplementation();
+ Document doc = impl.createDocument(svgNS, "svg", null);
+
+ Element svgRoot = doc.getDocumentElement();
+ svgRoot.setAttributeNS(null, "width", "" + width);
+ svgRoot.setAttributeNS(null, "height", "" + height);
+ svgRoot.setAttributeNS(null, "style",
+ "font-size:" + 8 + ";font-family:" +
+ hints.get(PlanHints.FONT_FAMILY));
+
+ font = new java.awt.Font( (String) hints.get(PlanHints.FONT_FAMILY),
+ java.awt.Font.PLAIN, (int) fontSize);
+
+ if (bord) {
+ Element border =
+ SVGUtilities.createRect(doc, 0, 0, width, height);
+ border.setAttributeNS(null, "style", "stroke:black;fill:none");
+ svgRoot.appendChild(border);
+ }
+
+ float strwidth = SVGUtilities.getStringWidth(title, font);
+
+ Element text;
+ float pos = (float)(80 - strwidth / 2.0);
+ if (pos < 5) {
+ pos = 5;
+ }
+ text = SVGUtilities.createText(doc, pos, 18, title);
+ text.setAttributeNS(null, "style", "font-size:14");
+ svgRoot.appendChild(text);
+
+ topEdge = SVGUtilities.getStringHeight(title, font) + 5;
+
+ // add the actual pie chart
+ addPlan(doc, svgRoot, data);
+ //addLegend(doc, svgRoot, data);
+
+ return doc;
+ }
+
+ protected void addPlan(Document doc, Element svgRoot, EventList data) {
+ Date currentDate = new Date();
+
+ Date lastWeek = startDate;
+ Date future = endDate;
+ Calendar lw = Calendar.getInstance();
+ if(lastWeek == null || future == null) {
+ int dow = lw.get(Calendar.DAY_OF_WEEK);
+ lw.add(Calendar.DATE, -dow - 6);
+ lastWeek = lw.getTime();
+ lw.add(Calendar.DATE, 5 * 7);
+ future = lw.getTime();
+ }
+ long totalDays = (long)((future.getTime() - lastWeek.getTime() + 43200000) / 86400000);
+ lw.setTime(lastWeek);
+ int startDay = lw.get(Calendar.DAY_OF_WEEK);
+
+ float graphTop = topEdge;
+ Element g;
+ Element line;
+ line = SVGUtilities.createLine(doc, 0, topEdge, width, topEdge);
+ line.setAttributeNS(null, "style", "fill:none;stroke:black");
+ svgRoot.appendChild(line);
+
+ Element clip1 = SVGUtilities.createClip(doc,
+ SVGUtilities.createPath(doc,
+ "m0 0l126 0l0 " + height + "l-126 0z"), "clip1");
+ Element clip2 = SVGUtilities.createClip(doc,
+ SVGUtilities.createPath(doc,
+ "m130 0l66 0l0 " + height + "l-66 0z"), "clip2");
+ Element clip3 = SVGUtilities.createClip(doc,
+ SVGUtilities.createPath(doc,
+ "m200 0l" + (width - 200) + " 0l0 " + height + "l-" +
+ (width - 200) + " 0z"), "clip3");
+ svgRoot.appendChild(clip1);
+ svgRoot.appendChild(clip2);
+ svgRoot.appendChild(clip3);
+
+ DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
+ Element text;
+ text = SVGUtilities.createText(doc, 201, topEdge - 1,
+ df.format(lastWeek));
+ svgRoot.appendChild(text);
+
+ text = SVGUtilities.createText(doc, width, topEdge - 1,
+ df.format(future));
+ text.setAttributeNS(null, "text-anchor", "end");
+ svgRoot.appendChild(text);
+
+ line = SVGUtilities.createLine(doc, 128, topEdge, 128, height);
+ line.setAttributeNS(null, "style", "fill:none;stroke:rgb(150,150,150)");
+ svgRoot.appendChild(line);
+ int offset = 0;
+ for (int count = startDay; count < startDay + totalDays - 1; count++) {
+ offset++;
+ if (count % 7 == 0 || count % 7 == 1) {
+ Element rect = SVGUtilities.createRect(doc,
+ 200 + (offset - 1) * (width - 200) / (totalDays - 2),
+ (float)(topEdge + 0.5), (width - 200) / (totalDays - 3),
+ height - 1 - topEdge);
+ rect.setAttributeNS(null, "style", "stroke:none;fill:rgb(230,230,230)");
+ svgRoot.appendChild(rect);
+ }
+ line = SVGUtilities.createLine(doc,
+ 200 + (offset - 1) * (width - 200) / (totalDays - 2),
+ (float)(topEdge + 0.5),
+ 200 + (offset - 1) * (width - 200) / (totalDays - 2),
+ (float)(height - 0.5));
+ line.setAttributeNS(null, "style", "fill:none;stroke:rgb(200,200,200)");
+ svgRoot.appendChild(line);
+ }
+
+
+ for (int count = 0; count < data.getSize(); count++) {
+ GroupInfo gi = data.getGroupInfo(count);
+ g = SVGUtilities.createG(doc);
+ text = SVGUtilities.createText(doc, 1, topEdge + 12,
+ gi.getName());
+ text.setAttributeNS(null, "style", "clip-path:url(#clip1)");
+ g.appendChild(text);
+ if (count > 0) {
+ line = SVGUtilities.createLine(doc, 0, topEdge + 2,
+ width, topEdge + 2);
+ line.setAttributeNS(null, "style", "fill:none;stroke:rgb(100,100,100)");
+ g.appendChild(line);
+ }
+
+ float lastTop = topEdge;
+ topEdge += 14;
+ boolean showing = false;
+ for (int count1 = 0; count1 < gi.getSize(); count1++) {
+ ActionInfo act = gi.getActionInfo(count1);
+ String name = act.getOwner();
+ String label = act.getLabel();
+ text = SVGUtilities.createText(doc, 8, topEdge + 12, label);
+ text.setAttributeNS(null, "style", "clip-path:url(#clip1)");
+ g.appendChild(text);
+
+ text = SVGUtilities.createText(doc, 130, topEdge + 12,
+ name);
+ text.setAttributeNS(null, "style", "clip-path:url(#clip2)");
+ g.appendChild(text);
+ int type = act.getType();
+ Date start = act.getStartDate();
+ Date end = act.getEndDate();
+ if (end.after(lastWeek) && start.before(future)) {
+ showing = true;
+ int left = 200;
+ int right = 500;
+
+ int daysToStart = (int)((start.getTime() -
+ lastWeek.getTime() + 43200000) / 86400000);
+ int days = (int)((end.getTime() - start.getTime() +
+ 43200000) / 86400000);
+ int daysFromEnd =
+ (int)((future.getTime() - end.getTime() +
+ 43200000) / 86400000);
+ Element taskGraphic;
+ switch (type) {
+ case ActionInfo.TASK:
+ taskGraphic = SVGUtilities.createRect(doc,
+ left + daysToStart * 300 / (totalDays - 2),
+ topEdge + 2, days * 300 / (totalDays - 2), 10);
+ taskGraphic.setAttributeNS(null, "style", "stroke:black;fill:blue;stroke-width:1;clip-path:url(#clip3)");
+ g.appendChild(taskGraphic);
+ break;
+ case ActionInfo.MILESTONE:
+ taskGraphic = SVGUtilities.createPath(doc,
+ "m " + (left +
+ daysToStart * 300 / (totalDays - 2) - 6) +
+ " " + (topEdge + 6) + "l6 6l6-6l-6-6z");
+ taskGraphic.setAttributeNS(null, "style", "stroke:black;fill:black;stroke-width:1;clip-path:url(#clip3)");
+ g.appendChild(taskGraphic);
+ text = SVGUtilities.createText(doc,
+ left + daysToStart * 300 / (totalDays - 2) + 8,
+ topEdge + 9, df.format(start));
+ g.appendChild(text);
+
+ break;
+ case ActionInfo.GROUPING:
+ taskGraphic = SVGUtilities.createPath(doc,
+ "m " + (left +
+ daysToStart * 300 / (totalDays - 2) - 6) +
+ " " + (topEdge + 6) + "l6 -6l" +
+ (days * 300 / (totalDays - 2)) +
+ " 0l6 6l-6 6l-4-4l" + -
+ (days * 300 / (totalDays - 2) - 8) + " 0l-4 4l-6-6z");
+ taskGraphic.setAttributeNS(null, "style", "stroke:black;fill:black;stroke-width:1;clip-path:url(#clip3)");
+ g.appendChild(taskGraphic);
+ break;
+ default:
+ break;
+ }
+ }
+
+ topEdge += 14;
+ }
+ if (showing) {
+ svgRoot.appendChild(g);
+ } else {
+ topEdge = lastTop;
+ }
+ }
+ int currentDays =
+ (int)((currentDate.getTime() - lastWeek.getTime() +
+ 43200000) / 86400000);
+
+ text = SVGUtilities.createText(doc,
+ (float)(200 + (currentDays + 0.5) * 300 / 35),
+ graphTop - 1, df.format(currentDate));
+ text.setAttributeNS(null, "text-anchor", "middle");
+ text.setAttributeNS(null, "style", "stroke:rgb(100,100,100)");
+ svgRoot.appendChild(text);
+
+ line = SVGUtilities.createLine(doc,
+ (float)(200 + (currentDays + 0.5) * 300 / 35), graphTop,
+ (float)(200 + (currentDays + 0.5) * 300 / 35), height);
+ line.setAttributeNS(null, "style", "fill:none;stroke:rgb(200,50,50);stroke-dasharray:5 5");
+ svgRoot.appendChild(line);
+
+
+ }
+}