Re: Loading & saving documents

ok,
	this is how I did it. it uses Chiba and some serverside stuff, but 
should work with any xforms engine. Here is my actual form builder 
form. with it you can select from a list of available existing forms 
or create a new one, you can then edit it and save it. you could 
easilly modify how the save works. my version http posts back to the 
server where it is processed and stored.
This form probably wont be instantly useful for you, but may help 
somebody, and encourace some xforms work in this area.
There are a number of xform hacks and workaround for both xforms and 
chiba shortcomings, but the result whilst not perfect does work very 
well.
This isnt rocket science and you are free to use/modify my code as 
you see fit. It would be nice if you would maintain an acknowledgment 
of my effort though if you choose to.

one benefit of this approach is that I have since been asked to 
incorporate workflow for others to vet the completed form. I can do 
this fairly easilly because I can generate different forms from the 
one instance so that users that need to test the form can do so 
without it sending emails etc to everyone, then once its approved I 
can regenerate the form complete with its submission detail. hope 
that makes sense.


<?xml version="1.0" encoding="UTF-8"?>
<!--    <html xmlns="http://www.w3.org/2002/06/xhtml2"
   xmlns:xf="http://www.w3.org/2002/xforms" 
   xmlns:ev="http://www.w3.org/2001/xml-events" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">   
 -->
<!--  Author: Jason Eacott
 	  Copyright Hardlight Interactive Pty Ltd 2005
 	  XForm Builder, for Chiba, integrated with Manifest as a Manifest 
plugin.
 	  Xforms are saved to Manifest Repository. The Actual Xforms 
themselves are generated via 
 	  XSLT run on the formdefinition instance which remains a part of 
the built XForm enabling
 	  it to be edited by this Builder Form. The working Xforms also use 
the formdefinition instance to store their own instance data.
 	  The datasink protocol is a custom generic XML data sink that will 
accept xml submissions from xforms and store them.
 	  each item element represent a control in the form being built.
 	  each submission element represents an email address that the 
resulting form's submitted data should be mailed to.   
 -->
 <snapin:xform xmlns:chiba="http://chiba.sourceforge.net/xforms" 
      chiba:stylesheet="vcard.xsl"
	  xmlns:snapin="http://www.hardlight.com.au" 
	  xmlns:xlink="http://www.w3.org/1999/xlink"
	  xmlns:xf="http://www.w3.org/2002/xforms" 
	  xmlns:ev="http://www.w3.org/2001/xml-events"
	  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	  ><Properties Title="Form Builder" />
   <head>
      <title>Form Builder</title>

     <xf:model id="model_1">
         <xf:submission id="debug" 
action="http://localhost/chiba1/jsp/return-instance.jsp" 
method="post" replace="all" ref="instance('formdefinition')" />
	    <xf:submission id="editform" 
action="FormManager?command=loadinstance" method="post" 
replace="instance" ref="instance('formdefinition')//mform" />
		<xf:submission id="deleteform" action="FormManager?command=delete" 
method="post" replace="none" ref="instance('formdefinition')//mform" 
/>
	    <xf:submission id="saveform" action="FormManager?command=save" 
method="post" replace="instance" ref="instance('formdefinition')" />
		<xf:submission id="loadformlist" 
action="FormManager?command=loadformlist" method="post" 
replace="instance" ref="instance('formlist')" />
		<xf:submission id="loadpagelist" 
action="FormManager?command=loadpagelist" method="post" 
replace="instance" ref="instance('pagelist')" />

         <xf:instance id="formdefinition">
            <data xmlns="">
               <mform title="" id="" instanceid="" name=""/>
               <item description="" value="" constraint="" 
readonly="" required="false" fieldtype="" mediatype="" 
filename=""><options multiselect="false" 
type="checkbox"><option/></options></item>
               <submissions>
                  <submission action=""/>
               </submissions>
			   <submission action="datasink://serversubmit" label="save" 
active="true" />
			   <forward url="page?pg=38" />
            </data>
         </xf:instance>

<!-- used to email to multiple targets for a given form -->
         <xf:bind id="fdsubmissions" 
nodeset="instance('formdefinition')/submissions" >
           <!-- -->

			   <xf:bind id="submission-bind-entry" nodeset="submission"  > 
					<xf:bind id="fdsubaction" nodeset="@action" required="true()" 
constraint="(string-length(.) = 0) or (string-length(.) > 2 and 
contains(., '@') and not(starts-with(., '@')) and not(substring(., 
string-length(.)) = '@'))"/>

						 <xf:bind id="fdsublabel" nodeset="@label" />

						 <xf:bind id="submission-bind-entry-value" nodeset="." />
            </xf:bind>
         </xf:bind>
 <xf:bind id="fdsinksubmission" 
nodeset="instance('formdefinition')/submission"  >
      <xf:bind id="fdsinkactive" nodeset="@active" 
relevant="count(instance('formdefinition')/submissions/submission)"/>
</xf:bind>
 <xf:bind id="fdforwardto" 
nodeset="instance('formdefinition')/forward">
     <xf:bind id="fdforwardurl" nodeset="@url" required="true()"/>
 </xf:bind>

         <xf:bind id="fdform" 
nodeset="instance('formdefinition')/mform">
            <xf:bind id="fdtitle" nodeset="@title" />
			<xf:bind id="fdname" nodeset="@name" required="true()" />
            <xf:bind id="fdid" nodeset="@id" />

            <xf:bind id="fdinstanceid" nodeset="@instanceid" />
		<!-- 	<xf:bind id="fdinstance" nodeset="inst" /> -->
         </xf:bind>

         <xf:bind id="fditem" 
nodeset="instance('formdefinition')/item">
            <xf:bind id="fdfieldtype" nodeset="@fieldtype" />

            <xf:bind id="fddescription" nodeset="@description" 
required="true()" />

            <xf:bind id="fdrequired" nodeset="@required" />
             <xf:bind id="fdconstraint" nodeset="@constraint" 
relevant="../@description='keep'" />
            <xf:bind id="fdoptions" nodeset="options[1]" 
relevant="../@fieldtype='option' ">
	<!-- 			<xf:bind id="fdoptionstype" nodeset="@type" />
				<xf:bind id="fdmultiselect" nodeset="@multiselect" />  -->
				<xf:bind id="fdoptionstype" nodeset="@type" />
				<xf:bind id="fdmultiselect" nodeset="@multiselect" /> 
               <xf:bind nodeset="option" id="optionbind-entry">
                  <xf:bind nodeset="." id="bind-entry-value" 
required="true()" />
               </xf:bind>
            </xf:bind>
         </xf:bind>

         <xf:bind id="bind-last-entry" 
nodeset="instance('formdefinition')/item[last()]" />

         <xf:instance id="scratchpad">
            <temp xmlns="">
               <dummy />

               <fieldTypeOptions>
			    <!-- <option value="blank" label="" /> -->
                  <option value="input" label="Input Field" />

                  <option value="textarea" label="Text Area">
                  </option>

                  <option value="option" maxselect="1" 
label="Option">
                  </option>

                  <option value="secret" label="Secret">
                  </option>

                  <option value="label" label="Output">
                  </option>

                  <option value="upload" label="Upload">
                  </option>
               </fieldTypeOptions>

               <tempoption>
                  <option value="" label="" />
               </tempoption>

               <work>
                  <item description="" constraint="" readonly="" 
required="" rele="" fieldtype="" priority="" />
               </work>
			   <mform url=""/>
            </temp>
         </xf:instance>

         <xf:bind id="bscratchfieldtypeoptions" 
nodeset="instance('scratchpad')/fieldTypeOptions[1]" 
required="@required='true'">
            <xf:bind nodeset="option" id="bscratchoptionbind-entry">
               <xf:bind nodeset="@label" id="bscratchbind-entry-
label" />
			   <xf:bind nodeset="@value" id="bscratchbind-entry-value" />
            </xf:bind>
         </xf:bind>

         <xf:bind id="bscratchtempoption" 
nodeset="instance('scratchpad')/tempoption/option" />
		<xf:bind id="thisform" nodeset="instance('scratchpad')/mform/@url" 
/>
<!-- required="true()"  -->
         <xf:action ev:event="xforms-ready">
<!-- delete the item ONLY if there is one and its description is 
empty. thsi should be enough to indicate we havent loaded an already 
built form. -->
           <xf:delete bind="fditem" at="if( 
(count(instance('formdefinition')/item)=1) and 
(instance('formdefinition')/item/@description=''),last(),0)" />
            <xf:delete bind="submission-bind-entry" at="if( 
(count(instance('formdefinition')/submissions/submission)=1) and 
instance('formdefinition')/submissions/submission/@action='',last(),0)
" />
			<xf:delete bind="mlform" at="if( 
(count(instance('formlist')/mform)=1) and 
(instance('formlist')/mform/@id=''),last(),0)" />
		 	 <xf:send submission="loadformlist"/>  
		
         </xf:action>

		<!--  needed cause output ref="concat(xpath)" breaks chiba  -->
<!--    <xf:action  ev:event="xforms-recalculate">
		<xf:setvalue bind="thisform" 
value="concat('http://willow/anty7/page?pg=',instance('formdefinition'
)/mform/@id)"/>
  </xf:action> -->
 <!-- <xf:instance id="formlist" 
src="http://willow/anty7/FormManager?command=loadformlist" > -->
		  <xf:instance id="formlist" > 
            <data xmlns="">
				<mform name="" title="" id="" source="" modifieddate="" 
creationdate=""/>
            </data>
         </xf:instance>

<xf:bind id="mlform" nodeset="instance('formlist')/mform">
	<xf:bind  nodeset="@title" id="mlformtitle"/>
	<xf:bind  nodeset="@name" id="mlformname"/>
	<xf:bind  nodeset="@id" id="mlformid"/>
<!-- 	<xf:bind  nodeset="inst" id="mlforminstance"/> -->
</xf:bind>

		  <xf:instance id="pagelist" > 
            <data xmlns="">
			    <mform id="" title="" name=""/>
				<page name="" id=""/>
            </data>
         </xf:instance>

<xf:bind id="plpagelist" nodeset="instance('pagelist')">
<xf:bind  nodeset="mform" id="plform">
  <xf:bind  nodeset="@name" id="plformname"/>
  <xf:bind  nodeset="@id" id="plformid"/>
</xf:bind>
<!--   <xf:bind  nodeset="page" id="plpages" 
calculate="concat('http://willow/anty7/',@id)"> -->
 <xf:bind  nodeset="page" id="plpages">
	<xf:bind  nodeset="@name" id="plpagename"/>
	<xf:bind  nodeset="@id" id="plpageid" />
	<xf:bind  nodeset="." id="plpage" />
  </xf:bind>
</xf:bind>


      </xf:model>

<!--   <xf:model id="model_list">
         <xf:instance id="formlist">
            <data xmlns="">
				<form title="form 1" id="1" 
source="http://willow/page?pg=1&amp;stypen=xml" />
				<form title="form 2" id="2" 
source="http://willow/page?pg=2&amp;stypen=xml" />
				<form title="form 3" id="3" 
source="http://willow/page?pg=3&amp;stypen=xml" />
				<form title="form 4" id="4" 
source="http://willow/page?pg=4&amp;stypen=xml" />
            </data>
         </xf:instance>
		
</xf:model> -->

   </head>

   <body>
<!-- ############# Form UI start here ###############-->
<!-- ################################################ -->

 <xf:switch id="switch">
 <xf:case id="case-formchooser" xf:selected="true">
 <xf:group id="group-formchooser">

 <xf:output bind="fdfieldtype" appearance="minimal">
       <xf:label>create a new form</xf:label>
 </xf:output>

<xf:trigger appearance="minimal">
  <xf:label>Create New Form</xf:label>
  <xf:action >
     <xf:reset id="reset-cancel" model="model_1"/> 
	 <xf:dispatch name="xforms-ready" target="model_1" /> 
	 <xf:toggle id="toggle-cancel" case="case-editor" /> 
  </xf:action>
</xf:trigger>



 <xf:group > 

 <xf:trigger>
  <xf:label>Refresh</xf:label> 
  <xf:send submission="loadformlist"/>
  <xf:refresh/> 
 </xf:trigger>
	
      <xf:repeat  id="repeatformlist" bind="mlform"> 
			<xf:output bind="mlformid" appearance="full"/>
			<xf:output bind="mlformname" appearance="full"/>
			<xf:output bind="mlformtitle" appearance="full"/>
      </xf:repeat> 

 <xf:group appearance="compact"> 
            <xf:trigger>
                    <xf:label>Edit Selected</xf:label>
                     <xf:hint>edit this item</xf:hint> 
					<!-- submit form and get new data -->
					<!-- 	set the id of the form we want to load -->
					
					 <xf:setvalue bind="fdid" 
value="instance('formlist')/mform[index('repeatformlist')]/@id" /> 
					<!-- <xf:setvalue bind="fdid" value="./@id" /> -->
					<xf:setvalue bind="fdinstanceid" value="''" />
					<xf:setvalue bind="fdname" value="'temp'" /> <!-- this is 
required so that the submission works it will always be replaced-->
					<xf:send submission="editform" />
					<!--  <xf:refresh ev:event="DOMActivate" />  -->
					   <xf:dispatch name="xforms-ready" target="model_1" />
					           <xf:setvalue bind="plformid" 
value="instance('formdefinition')//mform/@id" />
							   <xf:send submission="loadpagelist"/>
					  <xf:toggle id="toggle-cancel" case="case-editor" /> 
                   <!--  <xf:delete at="1" ev:event="DOMActivate" 
nodeset="."/>  -->
                  </xf:trigger> 

                    <xf:trigger>
                    <xf:label>Copy</xf:label>
                     <xf:hint>Make a new copy of this form</xf:hint> 
				<!-- 	set the id of the form we want to copy -->
					<xf:setvalue bind="fdid" 
value="instance('formlist')/mform[index('repeatformlist')]/@id" />
					<xf:setvalue bind="fdinstanceid" value="''" />
					<xf:setvalue bind="fdname" value="'temp'" /> <!-- this is 
required so that the submission works it will always be replaced-->
					<xf:send submission="editform" />
					   <xf:dispatch name="xforms-ready" target="model_1" />
				<!-- 	 set the form id to nothing to indicate to the server that 
this should be considered a new form.
					 clear the form name field too. -->
					<xf:setvalue bind="fdname" value="''" />
					<xf:setvalue bind="fdid" value="''" />
					<xf:setvalue bind="fdinstanceid" value="''" />
					
					 <xf:toggle id="toggle-cancel" case="case-editor" /> 
                   <!--  <xf:delete at="1" ev:event="DOMActivate" 
nodeset="."/>  -->
                  </xf:trigger> 

				  <xf:trigger>
                    <xf:label>Delete</xf:label>
                     <xf:hint>Delete this form</xf:hint> 
					 <xf:help>This will NOT delete the data associated with this 
form</xf:help> 
				<!-- 	set the id of the form we want to copy -->
					<xf:setvalue bind="fdid" 
value="instance('formlist')/mform[index('repeatformlist')]/@id" />
					<xf:setvalue bind="fdinstanceid" value="''" />
					<xf:setvalue bind="fdname" value="'temp'" /> <!-- this is 
required so that the submission works it will always be replaced-->
					<xf:send submission="deleteform" />
					<xf:send submission="loadformlist"/> <!-- because we cant submit 
from one instance and retreive into another  -->
                  </xf:trigger> 
 </xf:group> 
 </xf:group> 



 </xf:group>
  </xf:case>
 <xf:case id="case-editor">


 <xf:group id="group-editor">
  <xf:trigger id="trigger-formchooser">
	<xf:label>&lt;-FORMS</xf:label>
	<xf:action id="action-formchooser">
	<xf:setvalue bind="fdname" value="'temp'" /> <!-- this is required 
so that the submission works. it will always be replaced-->
		<xf:revalidate id="revalidate-formchooser" /> 
		<xf:toggle id="toggle-formchooser" xf:case="case-formchooser" /> 
	</xf:action>
 </xf:trigger>

 <xf:label>Form ID</xf:label>
<xf:output bind="fdid" appearance="full" />
<!-- <a href="http://willow/anty7/"<xf:output bind="plformid" 
appearance="full" /> -->






<!-- ######################### -->
 <xf:repeat bind="plpages"  id="repeatpagelist">

 	<xf:output value="@name" appearance="full" />: <xf:output 
value="@id" appearance="anchor" />

 </xf:repeat>






 <xf:label>Form Instance</xf:label>

      <xf:group appearance="minimal">
         <xf:label>Form Details</xf:label>

         <xf:input bind="fdname">
            <xf:label>Name</xf:label>
			<xf:hint id="hint-Name">
			Please enter a Name for the form,
			the form will be saved with this name.
			</xf:hint>
            <xf:alert id="alert-Name">Please enter a NAME for the 
Form</xf:alert>
         </xf:input>

         <xf:input bind="fdtitle">
            <xf:label>Title</xf:label>
			<xf:hint id="hint-Title">
			Please enter a TITLE for the form,
			the title will be used in Hyperlinks.
			</xf:hint>
            <xf:alert id="alert-Title">Please enter a TITLE for the 
form</xf:alert>
         </xf:input>

      </xf:group>

      <xf:group>
         <xf:group appearance="minimal">
            <xf:label>Form Controls</xf:label>
         </xf:group>
<xf:group>
         <xf:repeat id="repeat_1" bind="fditem" appearance="compact">

            <xf:textarea bind="fddescription">
               <xf:label>description</xf:label>

               <xf:alert id="alert-description">Please specify an 
entry value</xf:alert>

               <xf:help>Please specify an entry value</xf:help>

               <xf:hint>Please specify an entry value</xf:hint>
            </xf:textarea>

            <xf:output bind="fdfieldtype" appearance="minimal">
               <xf:label>Field Type</xf:label>
            </xf:output>

            <xf:select bind="fdrequired" appearance="full">
               <xf:label>Required?</xf:label>

               <xf:item>
                  <xf:value>true</xf:value>
               </xf:item>
            </xf:select>

            <xf:group bind="fdoptions" appearance="full">
               <xf:group appearance="minimal">
                  <xf:trigger>
                     <xf:label>Insert Option after 
selected</xf:label>

                     <xf:action>
                        <xf:revalidate />

                        <xf:insert bind="optionbind-entry" 
at="index('repeat_option')" position="after" />

<!-- reset this to empty if there is data here -->
                     </xf:action>
                  </xf:trigger>

                  <xf:trigger>
                     <xf:label>Delete selected option</xf:label>

                     <xf:action>
                        <xf:delete bind="optionbind-entry" 
at="index('repeat_option')" />
                     </xf:action>
                  </xf:trigger>
               </xf:group>
			 <!--   type -->
            <xf:select1 bind="fdoptionstype" appearance="full">
               <xf:label>Type</xf:label>
               <xf:item>
				  <xf:label>DropList</xf:label>
                  <xf:value>droplist</xf:value>
               </xf:item>
			   <xf:item>
				  <xf:label>CheckBox</xf:label>
                  <xf:value>checkbox</xf:value>
               </xf:item>
			   	<xf:item>
				  <xf:label>ListBox</xf:label>
                  <xf:value>listbox</xf:value>
               </xf:item>
            </xf:select1>

		      <xf:select bind="fdmultiselect" appearance="full">
               <xf:label>Multi Select?</xf:label>
               <xf:item>
                  <xf:value>true</xf:value>
               </xf:item>
            </xf:select>


               <xf:repeat id="repeat_option" bind="optionbind-entry">
                  <xf:label>Option</xf:label>

                  <xf:input bind="bind-entry-value">
                     <xf:label>Option</xf:label>

                     <xf:alert id="alert-option">Please specify an 
entry value</xf:alert>
                  </xf:input>
               </xf:repeat>
            </xf:group>
<!-- </xf:group > -->
 </xf:repeat>

        

         <xf:group appearance="minimal">
            <xf:select1 bind="bscratchtempoption" 
appearance="minimal">
<!-- <xf:label>Field Type</xf:label> -->
               <xf:itemset bind="bscratchoptionbind-entry">
                  <xf:label bind="bscratchbind-entry-label" />

                  <xf:value bind="bscratchbind-entry-value" />
               </xf:itemset>
            </xf:select1>

            <xf:trigger>
<!--  create a new item -->
               <xf:label>Insert Item after selected</xf:label>

               <xf:action>
                  <xf:revalidate />
					
                  <xf:insert bind="fditem" at="index('repeat_1')" 
position="after" />

                  <xf:setvalue 
ref="instance('formdefinition')/item[index('repeat_1')]/@fieldtype" 
value="instance('scratchpad')/tempoption/option" />

               </xf:action>
            </xf:trigger>

            <xf:trigger>
               <xf:label>Delete selected item</xf:label>

               <xf:action>
                  <xf:delete bind="fditem" at="index('repeat_1')" />
               </xf:action>
            </xf:trigger>
         </xf:group>



         <xf:group appearance="minimal">
            <xf:label>Send data from this form to the following Email 
addresses:</xf:label>
         </xf:group>

            <xf:group bind="fdsubmissions" appearance="full">
               <xf:group appearance="compact">
                  <xf:trigger>
                     <xf:label>Insert email after selected</xf:label>

                     <xf:action>
                        <xf:revalidate />

                        <xf:insert bind="submission-bind-entry" 
at="index('repeat_submission')" position="after" />

<!-- reset this to empty if there is data here -->
                     </xf:action>
                  </xf:trigger>

                  <xf:trigger>
                     <xf:label>Delete selected email</xf:label>

                     <xf:action>
                        <xf:delete bind="submission-bind-entry" 
at="index('repeat_submission')" />
                     </xf:action>
                  </xf:trigger>
               </xf:group>
			</xf:group>

               <xf:repeat id="repeat_submission" bind="submission-
bind-entry">
                  <xf:input bind="fdsubaction">
                     <xf:label>Email Address</xf:label>
                     <xf:alert id="alert-option">Please specify an 
entry value</xf:alert>
                  </xf:input>
               </xf:repeat>

			<xf:group bind="fdsinkactive">
		      <xf:select bind="fdsinkactive" appearance="full">
               <xf:label>Would you like to save the collected data 
from this form?</xf:label>
               <xf:item>
					<xf:label>Yes</xf:label>
                    <xf:value>true</xf:value>
               </xf:item>
              </xf:select>
			</xf:group>
         <xf:trigger>
            <xf:label>Save Form</xf:label>

            <xf:action ev:event="DOMActivate">
               <xf:send submission="saveform" />
			   <xf:dispatch name="xforms-ready" target="model_1" />
				<!-- <xf:send submission="loadformlist"/> -->
				<xf:setvalue bind="plformid" 
value="instance('formdefinition')//mform/@id" />
				<xf:send submission="loadpagelist"/>
			
<!--      <xforms:toggle case="responseGUI" /> -->
            </xf:action>
         </xf:trigger>
         <xf:trigger>
            <xf:label>Debug Form</xf:label>
            <xf:action ev:event="DOMActivate">
               <xf:send submission="debug" />
            </xf:action>
         </xf:trigger>

      <xf:group appearance="minimal">
         <xf:label>Enter a URL to navigate to After form 
submission</xf:label>
                  <xf:input bind="fdforwardurl">
                     <xf:label>URL:</xf:label>
                     <xf:alert id="alert-option">Required value MUST 
be a valid URL</xf:alert>
                  </xf:input>
	     </xf:group>		

<!-- get new id(s) back and list locations of form for viewing. -->
      </xf:group>
</xf:group>


  </xf:group> 
  </xf:case>

  </xf:switch>
  
 </body>
    </snapin:xform>








From:           	Allan Beaufour <abeaufour@novell.com>
To:             	www-forms@w3.org
Date sent:      	Wed, 5 Oct 2005 10:48:50 +0200
Subject:        	Re: Loading & saving documents
Forwarded by:   	www-forms@w3.org
Date forwarded: 	Wed, 05 Oct 2005 08:49:03 +0000

> 
> Tuesday 04 October 2005 15:52 skrev Flinton Adam:
> > I can start off hosting the page/form itself within a jsp but the files
> > to be opened would always be on the user's local disk & would need to be
> > persisted back to that disk.
> 
> The tricky bit is how to let the user choose what file to load from and store 
> to. As long as you have a server involved, the server could create an 
> instance with the possible data documents. The user could then select a 
> location with a select1, triggering a submission that loads the appropriate 
> instance data ... or creates it if the user chooses a new name.
> 
> Without a server, it's possible to load and store from the same document, but 
> not letting the user choose one.
> 
> Of course you get a bit of help from XForms Buddy, but it's not exactly 
> smooth, and you still depend on something "extra".
> 
> -- 
> Allan Beaufour
> Linux Software Engineer
> 
> Novell, Inc.
> Software for the Open Enterprise
> www.novell.com/open
> 

-- 
Jason Eacott
Hardlight Interactive
http://www.hardlight.com.au

Support bacteria - they're the only culture some people have.

Received on Wednesday, 5 October 2005 10:01:08 UTC