]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
example extension
authorKeiron Liddle <keiron@apache.org>
Tue, 5 Mar 2002 10:58:46 +0000 (10:58 +0000)
committerKeiron Liddle <keiron@apache.org>
Tue, 5 Mar 2002 10:58:46 +0000 (10:58 +0000)
this converts a dom into an svg document that should be rendered
by the renderer

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194691 13f79535-47bb-0310-9956-ffa450edef68

17 files changed:
contrib/plan/.cvsignore [new file with mode: 0644]
contrib/plan/build.sh [new file with mode: 0755]
contrib/plan/build.xml [new file with mode: 0644]
contrib/plan/docs/june.xml [new file with mode: 0644]
contrib/plan/docs/plan.fo [new file with mode: 0644]
contrib/plan/resources/META-INF/services/org.apache.fop.fo.ElementMapping [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/ActionInfo.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/EventList.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/GroupInfo.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/Main.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/PlanDrawer.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/PlanElement.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/PlanElementMapping.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/PlanHints.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/PlanObj.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/PlanRenderer.java [new file with mode: 0644]
contrib/plan/src/org/apache/fop/plan/SimplePlanDrawer.java [new file with mode: 0644]

diff --git a/contrib/plan/.cvsignore b/contrib/plan/.cvsignore
new file mode 100644 (file)
index 0000000..378eac2
--- /dev/null
@@ -0,0 +1 @@
+build
diff --git a/contrib/plan/build.sh b/contrib/plan/build.sh
new file mode 100755 (executable)
index 0000000..ad6ab48
--- /dev/null
@@ -0,0 +1,26 @@
+#!/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 $*
diff --git a/contrib/plan/build.xml b/contrib/plan/build.xml
new file mode 100644 (file)
index 0000000..367df26
--- /dev/null
@@ -0,0 +1,139 @@
+<?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>
+
diff --git a/contrib/plan/docs/june.xml b/contrib/plan/docs/june.xml
new file mode 100644 (file)
index 0000000..7f8092d
--- /dev/null
@@ -0,0 +1,84 @@
+<?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>
+
diff --git a/contrib/plan/docs/plan.fo b/contrib/plan/docs/plan.fo
new file mode 100644 (file)
index 0000000..77f1273
--- /dev/null
@@ -0,0 +1,107 @@
+<?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>
+
diff --git a/contrib/plan/resources/META-INF/services/org.apache.fop.fo.ElementMapping b/contrib/plan/resources/META-INF/services/org.apache.fop.fo.ElementMapping
new file mode 100644 (file)
index 0000000..7c6c472
--- /dev/null
@@ -0,0 +1,2 @@
+org.apache.fop.plan.PlanElementMapping
+
diff --git a/contrib/plan/src/org/apache/fop/plan/ActionInfo.java b/contrib/plan/src/org/apache/fop/plan/ActionInfo.java
new file mode 100644 (file)
index 0000000..42f34d7
--- /dev/null
@@ -0,0 +1,83 @@
+/* $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;
+    }
+
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/EventList.java b/contrib/plan/src/org/apache/fop/plan/EventList.java
new file mode 100644 (file)
index 0000000..bb0a095
--- /dev/null
@@ -0,0 +1,43 @@
+/* $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);
+    }
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/GroupInfo.java b/contrib/plan/src/org/apache/fop/plan/GroupInfo.java
new file mode 100644 (file)
index 0000000..0d59356
--- /dev/null
@@ -0,0 +1,52 @@
+/* $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;
+    }
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/Main.java b/contrib/plan/src/org/apache/fop/plan/Main.java
new file mode 100644 (file)
index 0000000..bfc60c4
--- /dev/null
@@ -0,0 +1,69 @@
+/* $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;
+    }
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/PlanDrawer.java b/contrib/plan/src/org/apache/fop/plan/PlanDrawer.java
new file mode 100644 (file)
index 0000000..62932af
--- /dev/null
@@ -0,0 +1,16 @@
+/* $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);
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/PlanElement.java b/contrib/plan/src/org/apache/fop/plan/PlanElement.java
new file mode 100644 (file)
index 0000000..3cfe450
--- /dev/null
@@ -0,0 +1,63 @@
+/* $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);
+    }
+}
+
diff --git a/contrib/plan/src/org/apache/fop/plan/PlanElementMapping.java b/contrib/plan/src/org/apache/fop/plan/PlanElementMapping.java
new file mode 100644 (file)
index 0000000..b12569c
--- /dev/null
@@ -0,0 +1,44 @@
+/* $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);
+        }
+    }
+
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/PlanHints.java b/contrib/plan/src/org/apache/fop/plan/PlanHints.java
new file mode 100644 (file)
index 0000000..4b15ae3
--- /dev/null
@@ -0,0 +1,23 @@
+/* $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";
+
+}
diff --git a/contrib/plan/src/org/apache/fop/plan/PlanObj.java b/contrib/plan/src/org/apache/fop/plan/PlanObj.java
new file mode 100644 (file)
index 0000000..6e9a718
--- /dev/null
@@ -0,0 +1,32 @@
+/* $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";
+    }
+}
+
diff --git a/contrib/plan/src/org/apache/fop/plan/PlanRenderer.java b/contrib/plan/src/org/apache/fop/plan/PlanRenderer.java
new file mode 100644 (file)
index 0000000..2836816
--- /dev/null
@@ -0,0 +1,220 @@
+/* $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();
+    }
+}
+
diff --git a/contrib/plan/src/org/apache/fop/plan/SimplePlanDrawer.java b/contrib/plan/src/org/apache/fop/plan/SimplePlanDrawer.java
new file mode 100644 (file)
index 0000000..a085d2e
--- /dev/null
@@ -0,0 +1,288 @@
+/* $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);
+
+
+    }
+}