Completely remove /contrib/retep, with Peter's approval; now on Source
Forge.
This commit is contained in:
parent
9c7cd8ba15
commit
20d31fd609
@ -1,7 +0,0 @@
|
||||
Fri Mar 02 16:08:00 GMT 2001 peter@retep.org.uk
|
||||
- Started importing in the rest of the retep tools.
|
||||
|
||||
Tue Jan 23 10:19:00 GMT 2001 peter@retep.org.uk
|
||||
- Finished the XML Export classes
|
||||
- First of the test data suite now in CVS.
|
||||
|
@ -1,116 +0,0 @@
|
||||
Retep Tools Implementation
|
||||
--------------------------
|
||||
|
||||
|
||||
The tools are designed to be put into a single jar file, but each one is
|
||||
executable either individually or part of one single application.
|
||||
|
||||
To run the big application, you can either:
|
||||
|
||||
java -jar retepTools.jar
|
||||
|
||||
or with the retepTools.jar in the classpath run:
|
||||
|
||||
java uk.org.retep.tools.Main
|
||||
|
||||
Windows users: For you you can also double click the retepTools.jar as windows
|
||||
will automatically run javac for you.
|
||||
|
||||
To run the individual tools, you must have the .jar file in your classpath and
|
||||
then run the relevant Main class.
|
||||
|
||||
Tool Type Class
|
||||
------------------------------------------------------------------------------
|
||||
pg_hba.conf Editor/repairer Editor uk.org.retep.util.hba.Main
|
||||
Properties Editor Editor uk.org.retep.util.proped.Main
|
||||
|
||||
|
||||
Layout of the classes
|
||||
---------------------
|
||||
|
||||
Simply, tools that work on property files (Java properties, resource files,
|
||||
configuration settings - pg_hba.conf for example) go under uk.org.retep.util in
|
||||
their own package. Other utility classes (like PropertyIO) go in to the
|
||||
uk.org.retep.util.misc package except for certain ones where they are related.
|
||||
|
||||
ie: TableModels. In swing you have JTable which uses a TableModel to display
|
||||
(and possibly update) some data. These go under uk.org.retep.util.models where
|
||||
you will find PropertiesTableModel for example. This one allows a Properties
|
||||
object to be displayed & updated.
|
||||
|
||||
Come core classes like Logger, ExceptionDialog etc go into the main
|
||||
uk.org.retep.util package.
|
||||
|
||||
Directory/Package Contents
|
||||
------------------------------------------------------------------------------
|
||||
uk.org.retep Home of the tools.properties file
|
||||
uk.org.retep.tools The main all-in-one application
|
||||
uk.org.retep.dtu The Data Transform Unit
|
||||
uk.org.retep.util Core utility classes
|
||||
uk.org.retep.util.hba pg_hba.conf editor/repairer
|
||||
uk.org.retep.util.misc Misc utility classes
|
||||
uk.org.retep.util.models Swing table models
|
||||
uk.org.retep.util.proped Property Editor
|
||||
uk.org.retep.util.xml.core Basic XML Factory
|
||||
uk.org.retep.util.xml.jdbc JDBC/XML interface
|
||||
uk.org.retep.util.xml.parser Simple SAX parser
|
||||
|
||||
Structure of a tool
|
||||
-------------------
|
||||
|
||||
Each tool has at least 2 base classes, and an entry in the tools.properties
|
||||
file. For this example, I'll show you the Properties Editor:
|
||||
|
||||
Base package uk.org.retep.util.proped
|
||||
Main tool class uk.org.retep.util.proped.PropertyEditor
|
||||
Standalone class uk.org.retep.util.proped.Main
|
||||
|
||||
The main tool class is the entry point used by the main application. Because
|
||||
they are used in a GUI, this class must extend javax.swing.JComponent and
|
||||
implement the uk.org.retep.tools.Tool interface. (NB: You will find I always
|
||||
use JPanel, but JComponent is used here so that any swing class can be used
|
||||
you are not limited to JPanel.)
|
||||
|
||||
The standalone class is a basic static class that implements the main method.
|
||||
It should extend the uk.org.retep.misc.StandaloneApp class and be written along
|
||||
the lines of the following example:
|
||||
|
||||
import uk.org.retep.util.StandaloneApp;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
public class Main extends StandaloneApp
|
||||
{
|
||||
public Main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
super(args);
|
||||
}
|
||||
|
||||
public JComponent init()
|
||||
throws Exception
|
||||
{
|
||||
// Your initialisation here. In this case the PropertyEditor
|
||||
PropertyEditor panel = new PropertyEditor();
|
||||
|
||||
// do stuff here, ie load a file if supplied
|
||||
|
||||
// return the tool
|
||||
return panel;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
Main main = new Main(args);
|
||||
main.pack();
|
||||
main.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
you will find a template in the uk.org.retep.util.Main class. Simply copy this
|
||||
classes source, as it gives you the basic stub. Just add your own implementation
|
||||
if init() like the one above. Look at the full Main class for the
|
||||
PropertiesEditor to see how to get at the command line args.
|
||||
|
||||
By convention, the standalone class is named Main.
|
||||
|
@ -1,30 +0,0 @@
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Makefile for contributed retep tools
|
||||
#
|
||||
# Copyright (c) 2001, PostgreSQL Global Development Group
|
||||
#
|
||||
# $Header: /cvsroot/pgsql/contrib/retep/Attic/Makefile,v 1.1 2001/07/06 23:07:20 petere Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
subdir = contrib/retep
|
||||
top_builddir = ../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
all:
|
||||
$(ANT) -buildfile $(srcdir)/build.xml all
|
||||
|
||||
install: installdirs
|
||||
$(ANT) -buildfile $(srcdir)/build.xml install \
|
||||
-Dinstall.directory=$(javadir)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(javadir)
|
||||
|
||||
uninstall:
|
||||
$(ANT) -buildfile $(srcdir)/build.xml uninstall \
|
||||
-Dinstall.directory=$(javadir)
|
||||
|
||||
clean distclean maintainer-clean:
|
||||
$(ANT) -buildfile $(srcdir)/build.xml clean
|
@ -1,35 +0,0 @@
|
||||
Before you ask what retepTools are, they are my personal suite of utilities.
|
||||
About 90% of them are JDBC related (either they use JDBC, or I use them in
|
||||
developing the JDBC driver).
|
||||
|
||||
Now, because of various reasons I won't go into now, in January 2001 I decided
|
||||
to release the entire lot to the public. I could have used something like
|
||||
SourceForge, but as they are mainly JDBC related I thought here is the best
|
||||
place.
|
||||
|
||||
Now all (bar retepPDF, see end-note) will over the next few months be going
|
||||
into the /contrib/retep directory. They range from simple XML Inport/Export
|
||||
classes to entire sub-systems that can be plugged into applications.
|
||||
|
||||
All this lot were never released, so I'm placing them under PostgreSQL's
|
||||
licence.
|
||||
|
||||
Please refer to Implementation for details of what package does what.
|
||||
|
||||
It all requires Java2SE (JDK1.2) as a minimum. I do have some plans for some
|
||||
EJB tools later, so those will need Java2EE, but not yet ;-)
|
||||
|
||||
Peter Mount
|
||||
peter@retep.org.uk
|
||||
March 2 2001
|
||||
|
||||
retepPDF: This is not included for two reasons:
|
||||
|
||||
1: It's big and not really related in any way to PostgreSQL
|
||||
2: More importantly, I (may be foolishly) released it some 3 years ago under
|
||||
the LGPL. As a few people have added to it, it's not really possible to
|
||||
change the licence, and I don't want to polute PostgreSQL's source tree ;-)
|
||||
|
||||
retepGraph: This was an old graphics library. It's been obsolete for 3 years
|
||||
now, so it's not going in.
|
||||
|
@ -1,98 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
|
||||
build file to build the donated retep tools packages
|
||||
|
||||
$Header: /cvsroot/pgsql/contrib/retep/Attic/build.xml,v 1.8 2001/07/06 23:07:20 petere Exp $
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE project [
|
||||
<!ENTITY jarname "retepTools.jar">
|
||||
]>
|
||||
|
||||
<project name="retep" default="all" basedir=".">
|
||||
|
||||
<!-- set global properties for this build -->
|
||||
<property name="srcdir" value="." />
|
||||
<property name="builddir" value="build" />
|
||||
<property name="package" value="uk/org/retep" />
|
||||
<property name="jardir" value="jars" />
|
||||
|
||||
<!-- Some checks used to build dependent on the environment -->
|
||||
<target name="checks">
|
||||
<available property="jdk1.2+" classname="java.lang.ThreadLocal" />
|
||||
<available property="jdk1.3+" classname="java.lang.StrictMath" />
|
||||
<available property="jdk1.2e+" classname="javax.sql.DataSource" />
|
||||
<available property="xml" classname="org.xml.sax.Parser" />
|
||||
</target>
|
||||
|
||||
<target name="warning" depends="checks" unless="jdk1.2+">
|
||||
<echo>
|
||||
*** WARNING: Contributed retep tools need jdk1.2 or later.
|
||||
*** Compilation NOT done
|
||||
</echo>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- default target -->
|
||||
<target name="all">
|
||||
<antcall target="jar" />
|
||||
</target>
|
||||
|
||||
|
||||
<!-- Builds the various jar files -->
|
||||
<target name="jar" depends="compile">
|
||||
<jar jarfile="${jardir}/&jarname;" whenempty="fail">
|
||||
<fileset dir="${builddir}">
|
||||
<include name="**/*.class" />
|
||||
</fileset>
|
||||
|
||||
<fileset dir="${srcdir}">
|
||||
<include name="**/*.properties" />
|
||||
</fileset>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- Builds the XML Tools -->
|
||||
<target name="compile" depends="checks,prepare,warning" if="jdk1.2+">
|
||||
<javac srcdir="${srcdir}" destdir="${builddir}">
|
||||
<include name="${package}/**" />
|
||||
<exclude name="${package}/**" unless="jdk1.2+" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- Prepares the build by creating a directory to place the class files -->
|
||||
<target name="prepare">
|
||||
<mkdir dir="${builddir}" />
|
||||
<mkdir dir="${jardir}" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="install" depends="all" if="install.directory">
|
||||
<copy todir="${install.directory}" overwrite="true" filtering="off">
|
||||
<fileset dir="${jardir}">
|
||||
<include name="&jarname;" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="uninstall" if="install.directory">
|
||||
<delete>
|
||||
<fileset dir="${install.directory}">
|
||||
<include name="&jarname;" />
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- This target removes any class files from the build directory -->
|
||||
<target name="clean">
|
||||
<delete quiet="true" dir="${builddir}" />
|
||||
<delete quiet="true" dir="${jardir}" />
|
||||
</target>
|
||||
|
||||
</project>
|
@ -1,16 +0,0 @@
|
||||
<!ELEMENT album (track*)+>
|
||||
<!ATTLIST album
|
||||
title CDATA #IMPLIED
|
||||
aid CDATA #IMPLIED
|
||||
>
|
||||
<!ELEMENT catalogue (group)>
|
||||
<!ELEMENT group (album*)>
|
||||
<!ATTLIST group
|
||||
name CDATA #IMPLIED
|
||||
>
|
||||
<!ELEMENT track (#PCDATA)>
|
||||
<!ATTLIST track
|
||||
tid CDATA #IMPLIED
|
||||
id CDATA #IMPLIED
|
||||
>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--JBuilder XML Project-->
|
||||
<project>
|
||||
<property category="idl" name="ProcessIDL" value="false" />
|
||||
<property category="runtime.0" name="RunnableType" value="com.borland.jbuilder.runtime.ApplicationRunner" />
|
||||
<property category="runtime.0" name="application.class" value="uk.org.retep.util.hba.Main" />
|
||||
<property category="runtime.0" name="application.parameters" value="-d2 pg_hba.conf" />
|
||||
<property category="runtime.0" name="appserver.ejbJarsSaved" value="1" />
|
||||
<property category="runtime.0" name="appserver.parameters" value="-jts -jns -jss -jdb" />
|
||||
<property category="runtime.0" name="appserver.servername" value="ejbcontainer" />
|
||||
<property category="runtime.0" name="appserver.vmparameters" value="" />
|
||||
<property category="runtime.0" name="jsprunner.docbase" value="." />
|
||||
<property category="runtime.0" name="jsprunner.jspfile" value="E%|/docs/java/xml/example6" />
|
||||
<property category="sys" name="AuthorLabel" value="@author" />
|
||||
<property category="sys" name="BackupPath" value="bak" />
|
||||
<property category="sys" name="BeansInstantiate" value="false" />
|
||||
<property category="sys" name="BraceStyle" value="1" />
|
||||
<property category="sys" name="CheckStable" value="1" />
|
||||
<property category="sys" name="Company" value="" />
|
||||
<property category="sys" name="CompanyLabel" value="Company:" />
|
||||
<property category="sys" name="Copyright" value="Copyright (c) 2001" />
|
||||
<property category="sys" name="CopyrightLabel" value="Copyright:" />
|
||||
<property category="sys" name="DefaultPackage" value="uk.org.retep.util.misc" />
|
||||
<property category="sys" name="Description" value="" />
|
||||
<property category="sys" name="DescriptionLabel" value="Description:" />
|
||||
<property category="sys" name="DocPath" value="doc" />
|
||||
<property category="sys" name="EventMatch" value="false" />
|
||||
<property category="sys" name="EventStyle" value="1" />
|
||||
<property category="sys" name="ExcludeClassEnabled" value="0" />
|
||||
<property category="sys" name="InstanceVisibility" value="0" />
|
||||
<property category="sys" name="JDK" value="java 1.3.0-C" />
|
||||
<property category="sys" name="LastTag" value="0" />
|
||||
<property category="sys" name="Libraries" value="JAXP;Oracle JDBC;JDK1.3 JRE" />
|
||||
<property category="sys" name="MakeStable" value="0" />
|
||||
<property category="sys" name="OutPath" value="build" />
|
||||
<property category="sys" name="SourcePath" value="." />
|
||||
<property category="sys" name="Title" value="" />
|
||||
<property category="sys" name="TitleLabel" value="Title:" />
|
||||
<property category="sys" name="Version" value="1.0" />
|
||||
<property category="sys" name="VersionLabel" value="@version" />
|
||||
<property category="sys" name="WorkingDirectory" value="." />
|
||||
<node type="Package" name="uk.org.retep.dtu" />
|
||||
<node type="Package" name="uk.org.retep.tools" />
|
||||
<node type="Package" name="uk.org.retep.util" />
|
||||
<node type="Package" name="uk.org.retep.xml.core" />
|
||||
<node type="Package" name="uk.org.retep.xml.jdbc" />
|
||||
<node type="Package" name="uk.org.retep.xml.parser" />
|
||||
<file path="build.xml" />
|
||||
<file path="CHANGELOG" />
|
||||
<file path="Implementation" />
|
||||
<file path="uk/org/retep/util/models/PropertiesTableModel.java" />
|
||||
<file path="README" />
|
||||
</project>
|
||||
|
@ -1,228 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class DCollection implements Collection
|
||||
{
|
||||
protected int num,max,inc;
|
||||
|
||||
protected DElement elements[];
|
||||
|
||||
public DCollection()
|
||||
{
|
||||
this(10);
|
||||
}
|
||||
|
||||
public DCollection(int aIncrement)
|
||||
{
|
||||
num=0;
|
||||
max=0;
|
||||
inc=aIncrement;
|
||||
elements=null;
|
||||
}
|
||||
|
||||
protected void resize()
|
||||
{
|
||||
if(num>=max) {
|
||||
max+=inc;
|
||||
DElement n[] = new DElement[max];
|
||||
if(elements!=null) {
|
||||
System.arraycopy(elements,0,n,0,elements.length);
|
||||
}
|
||||
elements=n;
|
||||
}
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return (num==0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the list using it's XML id.
|
||||
*/
|
||||
public synchronized boolean contains(Object parm1)
|
||||
{
|
||||
if(parm1 instanceof DElement) {
|
||||
DElement e = (DElement) parm1;
|
||||
int ei = e.getID();
|
||||
|
||||
// out of range?
|
||||
if(ei<0 || ei>=num)
|
||||
return false;
|
||||
|
||||
return elements[ei].equals(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return new iterator(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class to implement an Iterator
|
||||
*/
|
||||
protected class iterator implements Iterator
|
||||
{
|
||||
protected DCollection c;
|
||||
protected int i;
|
||||
|
||||
public iterator(DCollection aCollection)
|
||||
{
|
||||
c=aCollection;
|
||||
i=0;
|
||||
}
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return i<c.size();
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
return c.getElement(i++);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Object[] toArray()
|
||||
{
|
||||
Object o[] = new Object[num];
|
||||
System.arraycopy(elements,0,o,0,num);
|
||||
return o;
|
||||
}
|
||||
|
||||
public Object[] toArray(Object[] parm1)
|
||||
{
|
||||
/**@todo: Implement this java.util.Collection method*/
|
||||
throw new java.lang.UnsupportedOperationException("Method toArray() not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a node to the Collection, and sets it's ID to its position in the Collection
|
||||
*/
|
||||
public synchronized boolean add(Object parm1)
|
||||
{
|
||||
if(parm1 instanceof DElement) {
|
||||
DElement e = (DElement) parm1;
|
||||
|
||||
// Do nothing if it's already in a Collection
|
||||
if(e.getID()>-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add to the Collection
|
||||
resize();
|
||||
e.setID(num);
|
||||
elements[num++] = e;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized boolean remove(Object parm1)
|
||||
{
|
||||
if(parm1 instanceof DElement) {
|
||||
DElement e = (DElement) parm1;
|
||||
int ei = e.getID();
|
||||
if(ei<0 || ei>=num)
|
||||
return false;
|
||||
|
||||
// Mark the node as parentless
|
||||
e.setID(-1);
|
||||
|
||||
// Now remove from the array by moving latter nodes, fixing their ids
|
||||
// in the process
|
||||
for(int j=ei,k=ei+1;k<num;j++,k++) {
|
||||
elements[j]=elements[k];
|
||||
elements[j].setID(j);
|
||||
}
|
||||
num--;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection parm1)
|
||||
{
|
||||
/**@todo: Implement this java.util.Collection method*/
|
||||
throw new java.lang.UnsupportedOperationException("Method containsAll() not yet implemented.");
|
||||
}
|
||||
|
||||
public boolean addAll(Collection parm1)
|
||||
{
|
||||
/**@todo: Implement this java.util.Collection method*/
|
||||
throw new java.lang.UnsupportedOperationException("Method addAll() not yet implemented.");
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection parm1)
|
||||
{
|
||||
/**@todo: Implement this java.util.Collection method*/
|
||||
throw new java.lang.UnsupportedOperationException("Method removeAll() not yet implemented.");
|
||||
}
|
||||
|
||||
public boolean retainAll(Collection parm1)
|
||||
{
|
||||
/**@todo: Implement this java.util.Collection method*/
|
||||
throw new java.lang.UnsupportedOperationException("Method retainAll() not yet implemented.");
|
||||
}
|
||||
|
||||
public synchronized void clear()
|
||||
{
|
||||
// Mark each node as parentless
|
||||
for(int i=0;i<num;i++) {
|
||||
elements[i].setID(-1);
|
||||
}
|
||||
|
||||
// dispose the array
|
||||
num=0;
|
||||
max=0;
|
||||
elements=null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element with supplied id.
|
||||
* @return element or null
|
||||
*/
|
||||
public synchronized DElement getElement(int id)
|
||||
{
|
||||
if(id<0 || id>=num)
|
||||
return null;
|
||||
|
||||
return elements[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Repairs the collection, ensuring all id's are correct
|
||||
*/
|
||||
public synchronized void repair()
|
||||
{
|
||||
for(int i=0;i<num;i++) {
|
||||
elements[i].setID(i);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void saveXML(XMLFactory aFactory)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
for(int i=0;i<num;i++) {
|
||||
elements[i].saveXML(aFactory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
public class DConstants
|
||||
{
|
||||
/**
|
||||
* A global version number
|
||||
*/
|
||||
public static final String XML_VERSION_ID = "V7.1-2001-02-26";
|
||||
|
||||
/**
|
||||
* XML Tag names
|
||||
*/
|
||||
public static final String XML_DISPLAYNAME= "DISPLAYNAME";
|
||||
public static final String XML_FROM = "FROM";
|
||||
public static final String XML_ID = "ID";
|
||||
public static final String XML_MODULE = "MODULE";
|
||||
public static final String XML_NODE = "NODE";
|
||||
public static final String XML_TO = "TO";
|
||||
public static final String XML_TRANSFORM = "TRANSFORM";
|
||||
public static final String XML_TYPE = "TYPE";
|
||||
public static final String XML_VERSION = "VERSION";
|
||||
public static final String XML_X = "X";
|
||||
public static final String XML_Y = "Y";
|
||||
|
||||
public static final int NOP = 0; // No operation or always run transform
|
||||
public static final int SUCCESS = 1; // Run transform only if DNode.OK
|
||||
public static final int ERROR = 2; // Run transform only if DNode.ERROR
|
||||
|
||||
/**
|
||||
* Node types 20-39 reserved for Transformation types
|
||||
*/
|
||||
public static final int TRANSFORMBASE = 20;
|
||||
|
||||
/**
|
||||
* Node types 20-99 reserved for Internal Node implementations
|
||||
*/
|
||||
public static final int INTERNALBASE = 50;
|
||||
|
||||
/**
|
||||
* Node types 100+ are for user extensions
|
||||
*/
|
||||
public static final int USERBASE = 100;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface DElement
|
||||
{
|
||||
/**
|
||||
* Fetch the unique ID of this Element
|
||||
*/
|
||||
public int getID();
|
||||
|
||||
/**
|
||||
* Sets the unique id - normally set by DCollection
|
||||
*/
|
||||
public void setID(int id);
|
||||
|
||||
/**
|
||||
* @return the type of the Element
|
||||
*/
|
||||
public int getType();
|
||||
|
||||
/**
|
||||
* Set's the element type
|
||||
*/
|
||||
public void setType(int aType);
|
||||
|
||||
public void saveXML(XMLFactory aFactory) throws IOException, XMLFactoryException;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class DEnvironment
|
||||
{
|
||||
protected HashMap dsrc;
|
||||
|
||||
public DEnvironment()
|
||||
{
|
||||
dsrc=new HashMap();
|
||||
}
|
||||
|
||||
public void addDataSource(String aKey,Object aObject)
|
||||
{
|
||||
dsrc.put(aKey,aObject);
|
||||
}
|
||||
|
||||
public Object getDataSource(String aKey)
|
||||
{
|
||||
return dsrc.get(aKey);
|
||||
}
|
||||
|
||||
public Iterator getDataSources()
|
||||
{
|
||||
return dsrc.values().iterator();
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
import uk.org.retep.xml.parser.TagListener;
|
||||
import uk.org.retep.util.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* DModule represents a programatic module of steps used within the DTU
|
||||
*/
|
||||
public class DModule implements Serializable
|
||||
{
|
||||
// The nodes and transitions between them
|
||||
protected DCollection nodes;
|
||||
|
||||
protected String displayName;
|
||||
|
||||
public static final String DEFAULT_DISPLAYNAME = "unnamed module";
|
||||
|
||||
public DModule()
|
||||
{
|
||||
nodes=new DCollection();
|
||||
displayName=DEFAULT_DISPLAYNAME;
|
||||
Logger.log(Logger.DEBUG,"new DModule",this);
|
||||
}
|
||||
|
||||
// Expensive!
|
||||
public DNode getNode(int id)
|
||||
{
|
||||
return (DNode) nodes.getElement(id);
|
||||
}
|
||||
|
||||
public DNode addNode(DNode aNode)
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DModule.addNode",aNode);
|
||||
nodes.add(aNode);
|
||||
return aNode;
|
||||
}
|
||||
|
||||
public void removeNode(DNode aNode)
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DModule.removeNode",aNode);
|
||||
nodes.remove(aNode);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DModule.clear",this);
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
public void setDisplayName(String aName)
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DModule.setDisplayName",aName);
|
||||
displayName = aName;
|
||||
}
|
||||
|
||||
public String getDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return nodes.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an XML representation of this module to an XMLFactory. The caller
|
||||
* must close the factory after use!
|
||||
*/
|
||||
public synchronized void saveXML(XMLFactory aFactory)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DModule.saveXML start",this);
|
||||
Iterator it;
|
||||
|
||||
aFactory.startTag(DConstants.XML_MODULE);
|
||||
aFactory.addAttribute(DConstants.XML_DISPLAYNAME,displayName);
|
||||
aFactory.addAttribute(DConstants.XML_VERSION,DConstants.XML_VERSION_ID);
|
||||
|
||||
// The nodes
|
||||
nodes.saveXML(aFactory);
|
||||
|
||||
// The transforms
|
||||
//trans.saveXML(aFactory);
|
||||
|
||||
aFactory.endTag(); // MODULE
|
||||
Logger.log(Logger.DEBUG,"DModule.saveXML end",this);
|
||||
}
|
||||
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
import uk.org.retep.xml.parser.TagHandler;
|
||||
import uk.org.retep.xml.parser.TagListener;
|
||||
import uk.org.retep.util.Logger;
|
||||
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.Parser;
|
||||
import org.xml.sax.SAXException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
public class DModuleXML implements TagListener
|
||||
{
|
||||
protected TagHandler handler;
|
||||
|
||||
protected DModule module = null;
|
||||
protected DNode node = null;
|
||||
protected DTransform trans = null;
|
||||
|
||||
protected ArrayList txmap;
|
||||
|
||||
public DModuleXML()
|
||||
{
|
||||
handler = new TagHandler();
|
||||
handler.addTagListener(this);
|
||||
|
||||
txmap = new ArrayList();
|
||||
|
||||
Logger.log(Logger.DEBUG,"DModuleXML initialised");
|
||||
}
|
||||
|
||||
public TagHandler getTagHandler()
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to optimise the switch handling in tagStart.
|
||||
*
|
||||
* The values of each T_* constant must match the corresponding element no
|
||||
* in the tags static array.
|
||||
*/
|
||||
private static final int T_DEFAULT=-1;
|
||||
private static final int T_MODULE =0;
|
||||
private static final int T_NODE =1;
|
||||
private static final int T_TRANS =2;
|
||||
private static final String tags[] = {
|
||||
DConstants.XML_MODULE,
|
||||
DConstants.XML_NODE,
|
||||
DConstants.XML_TRANSFORM
|
||||
};
|
||||
|
||||
/**
|
||||
* This is called when a tag has just been started.
|
||||
* <p><b>NB:</b> args is volatile, so if you use it beyond the lifetime of
|
||||
* this call, then you must make a copy of the HashMap (and not use simply
|
||||
* store this HashMap).
|
||||
* @param level The number of tags above this
|
||||
* @param tag The tag name
|
||||
* @param args A HashMap of any arguments
|
||||
*/
|
||||
public void tagStart(int level,String tag,HashMap args)
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DModuleXML.tagStart",tag);
|
||||
|
||||
// Prefetch some common attributes
|
||||
String sType = (String) args.get(DConstants.XML_TYPE);
|
||||
String sX = (String) args.get(DConstants.XML_X);
|
||||
String sY = (String) args.get(DConstants.XML_Y);
|
||||
|
||||
int type=-1,x=-1,y=-1;
|
||||
|
||||
if(sType!=null) {
|
||||
type = Integer.parseInt(sType);
|
||||
}
|
||||
|
||||
if(sX!=null) {
|
||||
y = Integer.parseInt(sX);
|
||||
}
|
||||
|
||||
if(sY!=null) {
|
||||
x = Integer.parseInt(sY);
|
||||
}
|
||||
|
||||
// Match the tag against the tags array (used for switch() )
|
||||
int tagID=T_DEFAULT;
|
||||
for(int i=0;i<tags.length;i++) {
|
||||
if(tag.equals(tags[i])) {
|
||||
tagID=i;
|
||||
}
|
||||
}
|
||||
|
||||
switch(tagID)
|
||||
{
|
||||
// The main module tag
|
||||
case T_MODULE:
|
||||
module = new DModule();
|
||||
|
||||
String sDisplayName = (String) args.get(DConstants.XML_DISPLAYNAME);
|
||||
if(sDisplayName!=null) {
|
||||
module.setDisplayName(sDisplayName);
|
||||
}
|
||||
break;
|
||||
|
||||
// Basic nodes
|
||||
case T_NODE:
|
||||
node = new DNode();
|
||||
node.setType(type);
|
||||
module.addNode(node);
|
||||
break;
|
||||
|
||||
// Basic transforms
|
||||
case T_TRANS:
|
||||
trans = new DTransform();
|
||||
trans.setType(type);
|
||||
|
||||
// When finished we fix the transforms
|
||||
int to = Integer.parseInt((String) args.get(DConstants.XML_TO));
|
||||
txmap.add(new tx(node,trans,to));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// ignore unknown tags for now
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected class tx
|
||||
{
|
||||
public DNode node;
|
||||
public DTransform transform;
|
||||
public int toID;
|
||||
|
||||
public tx(DNode aNode,DTransform aTransform,int aID)
|
||||
{
|
||||
node=aNode;
|
||||
transform=aTransform;
|
||||
toID=aID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by ContHandler to process a tag once it has been
|
||||
* fully processed.
|
||||
* <p><b>NB:</b> content is volatile, so you must copy its contents if you use
|
||||
* it beyond the lifetime of this call.
|
||||
* @param content CharArrayWriter containing the content of the tag.
|
||||
*/
|
||||
public void tagContent(CharArrayWriter content)
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
|
||||
public void fixTransforms()
|
||||
{
|
||||
DNode to;
|
||||
Iterator it = txmap.iterator();
|
||||
|
||||
while(it.hasNext()) {
|
||||
tx x = (tx) it.next();
|
||||
|
||||
//Logger.log(Logger.DEBUG,"Fixing transform "+x.toID,x.transform,Integer.toString(x.node.getID()),Integer.toString(module.getNode(x.toID).getID()));
|
||||
to = module.getNode(x.toID);
|
||||
|
||||
x.transform.setFrom(x.node);
|
||||
x.transform.setTo(to);
|
||||
//to.setFrom(x.transform);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an InputSource and return the contained module.
|
||||
* @return DModule loaded, null if the xml file does not contain a module.
|
||||
*/
|
||||
public DModule parse(InputSource is)
|
||||
throws IOException,SAXException
|
||||
{
|
||||
getTagHandler().parse(is);
|
||||
fixTransforms();
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an uri and return the contained module.
|
||||
* @return DModule loaded, null if the xml file does not contain a module.
|
||||
*/
|
||||
public DModule parse(String uri)
|
||||
throws IOException,SAXException
|
||||
{
|
||||
getTagHandler().parse(uri);
|
||||
fixTransforms();
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug test - read xml from one file and save to another.
|
||||
*/
|
||||
public static void main(String args[]) throws Exception
|
||||
{
|
||||
if(args.length!=2) {
|
||||
System.err.println("Syntax: java DModuleXML in-file out-file");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
Logger.setLevel(Logger.DEBUG);
|
||||
|
||||
Logger.log(Logger.INFO,"DModuleXML Read test1.xml");
|
||||
DModuleXML dm = new DModuleXML();
|
||||
DModule module = dm.parse(new InputSource(new FileInputStream(args[0])));
|
||||
|
||||
Logger.log(Logger.INFO,"Parse complete");
|
||||
|
||||
Logger.log(Logger.INFO,"DModuleXML Write XML");
|
||||
FileWriter fw = new FileWriter(args[1]);
|
||||
module.saveXML(new XMLFactory(fw));
|
||||
fw.close();
|
||||
Logger.log(Logger.INFO,"Write complete");
|
||||
|
||||
DProcessor.run(module);
|
||||
}
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.util.Logger;
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This is the base class for all nodes.
|
||||
*/
|
||||
public class DNode implements DElement, Serializable
|
||||
{
|
||||
// The id of this node
|
||||
protected int id;
|
||||
|
||||
// The type of this node
|
||||
protected int type;
|
||||
|
||||
protected int x,y;
|
||||
|
||||
public static final int OK = 0; // Node last ran fine
|
||||
public static final int ERROR = 1; // Node failed on last run
|
||||
|
||||
/**
|
||||
* This type of node does nothing
|
||||
*/
|
||||
public static int NOP = 0; // No action
|
||||
|
||||
public DNode()
|
||||
{
|
||||
this(NOP);
|
||||
}
|
||||
|
||||
public DNode(int aType)
|
||||
{
|
||||
id=-1;
|
||||
type=aType;
|
||||
|
||||
// Init the transform linkage
|
||||
mf=mt=5;
|
||||
nf=nt=0;
|
||||
fn = new DTransform[mf];
|
||||
tn = new DTransform[mt];
|
||||
|
||||
Logger.log(Logger.DEBUG,"new DNode");
|
||||
}
|
||||
|
||||
public int getID()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setID(int aID)
|
||||
{
|
||||
id=aID;
|
||||
Logger.log(Logger.DEBUG,"DNode.setID",aID);
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int aType)
|
||||
{
|
||||
type=aType;
|
||||
Logger.log(Logger.DEBUG,"DNode.setType",aType);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void saveXML(XMLFactory aFactory)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
Logger.log(Logger.DEBUG,"DNode.saveXML start",this);
|
||||
Iterator it;
|
||||
|
||||
aFactory.startTag(DConstants.XML_NODE);
|
||||
aFactory.addAttribute(DConstants.XML_ID,new Integer(getID()));
|
||||
aFactory.addAttribute(DConstants.XML_TYPE,new Integer(getType()));
|
||||
|
||||
// used for display only
|
||||
aFactory.addAttribute(DConstants.XML_X,new Integer(getX()));
|
||||
aFactory.addAttribute(DConstants.XML_Y,new Integer(getY()));
|
||||
|
||||
// Save the transforms here (only the from list required)
|
||||
for(int i=0;i<nf;i++) {
|
||||
fn[i].saveXML(aFactory);
|
||||
}
|
||||
|
||||
aFactory.endTag(); // NODE
|
||||
Logger.log(Logger.DEBUG,"DNode.saveXML finish",this);
|
||||
}
|
||||
|
||||
public void setPosition(int aX,int aY)
|
||||
{
|
||||
x=aX;
|
||||
y=aY;
|
||||
}
|
||||
|
||||
public int getX()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setX(int aX)
|
||||
{
|
||||
x=aX;
|
||||
}
|
||||
|
||||
public void setY(int aY)
|
||||
{
|
||||
y=aY;
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be overidden to do something
|
||||
* @return Return status
|
||||
*/
|
||||
public int run(DEnvironment env)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node Transforms...
|
||||
*/
|
||||
protected int nf,mf,nt,mt;
|
||||
protected DTransform fn[],tn[];
|
||||
|
||||
/**
|
||||
* Executes the transform
|
||||
*/
|
||||
public DTransform getTransform(int aID)
|
||||
{
|
||||
return tn[aID];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of transforms
|
||||
*/
|
||||
public int getFromTransforms()
|
||||
{
|
||||
return nf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of transforms
|
||||
*/
|
||||
public int getToTransforms()
|
||||
{
|
||||
return nt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a transform to this node (called by DTransform)
|
||||
*/
|
||||
protected synchronized void setFrom(DTransform aTransform)
|
||||
{
|
||||
for(int i=0;i<nf;i++) {
|
||||
if(fn[i].equals(aTransform)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(nf>=mf) {
|
||||
mf+=5;
|
||||
DTransform nn[] = new DTransform[mf];
|
||||
System.arraycopy(fn,0,nn,0,nf);
|
||||
fn=nn;
|
||||
}
|
||||
fn[nf++]=aTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a transform to this node (called by DTransform)
|
||||
*/
|
||||
protected synchronized void setTo(DTransform aTransform)
|
||||
{
|
||||
for(int i=0;i<nt;i++) {
|
||||
if(tn[i].equals(aTransform)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(nt>=mt) {
|
||||
mt+=5;
|
||||
DTransform nn[] = new DTransform[mt];
|
||||
System.arraycopy(tn,0,nn,0,nt);
|
||||
tn=nn;
|
||||
}
|
||||
tn[nt++]=aTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a transform (called by DTransform)
|
||||
*/
|
||||
protected synchronized void removeFrom(DTransform aTransform)
|
||||
{
|
||||
for(int i=0;i<nf;i++) {
|
||||
if(tn[i].equals(aTransform)) {
|
||||
for(int j=i+1;j<nf;j++,i++) {
|
||||
fn[i]=fn[j];
|
||||
}
|
||||
nf--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a transform (called by DTransform)
|
||||
*/
|
||||
protected synchronized void removeTo(DTransform aTransform)
|
||||
{
|
||||
for(int i=0;i<nt;i++) {
|
||||
if(tn[i].equals(aTransform)) {
|
||||
for(int j=i+1;j<nt;j++,i++) {
|
||||
tn[i]=tn[j];
|
||||
}
|
||||
nt--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.util.Logger;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class processes a Module. It's implemented as a Thread and there can
|
||||
* be many threads running on a single module
|
||||
*/
|
||||
public class DProcessor
|
||||
{
|
||||
/**
|
||||
* This starts a module
|
||||
*/
|
||||
public static DProcessor run(DModule aModule) {
|
||||
// 3600000 is 1 hour in milliseconds
|
||||
return run(aModule,3600000);
|
||||
}
|
||||
|
||||
/**
|
||||
* This starts a module
|
||||
*/
|
||||
public static DProcessor run(DModule aModule,long timeout) {
|
||||
return new DProcessor(aModule,timeout);
|
||||
}
|
||||
|
||||
protected DProcessor(DModule aModule,long timeout) {
|
||||
ThreadGroup group = new ThreadGroup(aModule.getDisplayName()+" DProcessor");
|
||||
|
||||
// Setup the environment
|
||||
DEnvironment env = new DEnvironment();
|
||||
|
||||
// loop for any nodes without a transform pointing _to_ it.
|
||||
Iterator it = aModule.iterator();
|
||||
while(it.hasNext()) {
|
||||
DNode node = (DNode) it.next();
|
||||
|
||||
// Only start if we have no predecessor
|
||||
if(node.getFromTransforms()==0) {
|
||||
proc proc = new proc(group,aModule,node,env);
|
||||
proc.start();
|
||||
}
|
||||
}
|
||||
|
||||
// Now wait until all the threads have finished
|
||||
boolean running=true;
|
||||
try {
|
||||
int cnt=1; // must loop at least once!
|
||||
|
||||
while(cnt>0) {
|
||||
int numThreads = group.activeCount();
|
||||
Thread threads[] = new Thread[numThreads];
|
||||
cnt = group.enumerate(threads,false);
|
||||
|
||||
//Logger.log(Logger.DEBUG,"Waiting on threads",cnt);
|
||||
while(cnt>0) {
|
||||
//Logger.log(Logger.DEBUG,"Waiting on thread",cnt);
|
||||
threads[--cnt].join(timeout);
|
||||
}
|
||||
|
||||
Logger.log(Logger.DEBUG,"All threads appear to have died, retesting");
|
||||
}
|
||||
} catch(InterruptedException ie) {
|
||||
Logger.log(Logger.ERROR,"DProcessor, exception caught while waiting for threads to die",ie);
|
||||
}
|
||||
|
||||
// finally close any open datasources
|
||||
Logger.log(Logger.DEBUG,"DProcessor cleanup");
|
||||
|
||||
Logger.log(Logger.DEBUG,"DProcessor finished");
|
||||
}
|
||||
|
||||
class proc implements Runnable
|
||||
{
|
||||
protected DModule module; // The module being run
|
||||
protected DNode pc; // current Program Counter
|
||||
|
||||
protected DEnvironment env; // Shared environment
|
||||
|
||||
// Used when launching new threads only
|
||||
protected DTransform trans; // If not null, a transform to run first
|
||||
protected int status;
|
||||
|
||||
protected Thread thread;
|
||||
|
||||
/**
|
||||
* Start processing from DNode aNode. This is called by DProcessor at
|
||||
* initialisation only.
|
||||
*/
|
||||
protected proc(ThreadGroup aGroup,DModule aModule,DNode aNode,DEnvironment aEnv)
|
||||
{
|
||||
// aGroup will be null when forking...
|
||||
if(aGroup==null) {
|
||||
thread = new Thread(this);
|
||||
} else {
|
||||
thread = new Thread(aGroup,this);
|
||||
}
|
||||
|
||||
module = aModule;
|
||||
pc = aNode;
|
||||
env = aEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start processing the DTransform aTransform from aNode (does not execute
|
||||
* the node). This is called by this inner class itself when forking new
|
||||
* threads.
|
||||
*/
|
||||
protected proc(DModule aModule,DNode aNode,DEnvironment aEnv,DTransform aTransform,int aStatus)
|
||||
{
|
||||
this(null,aModule,aNode,aEnv);
|
||||
trans = aTransform;
|
||||
status = aStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start this thread
|
||||
*/
|
||||
public void start()
|
||||
{
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
// Handle an initial transform first. It's used when a new Thread was created.
|
||||
if(trans!=null) {
|
||||
transform(trans,false,status);
|
||||
trans=null;
|
||||
}
|
||||
|
||||
while(pc!=null) {
|
||||
//Logger.log(Logger.DEBUG,"running node ",pc.getID());
|
||||
|
||||
// Process the node
|
||||
int status = pc.run(env);
|
||||
//Logger.log(Logger.DEBUG," status ",status);
|
||||
|
||||
// Now the transforms. This thread continues with the first one that runs,
|
||||
// but any others that will also run will do so in their own thread.
|
||||
// If no transform runs (or there are none), then the thread will die.
|
||||
int numTrans = pc.getToTransforms();
|
||||
boolean fork=false;
|
||||
for(int i=0;i<numTrans;i++) {
|
||||
fork = transform(pc.getTransform(i),fork,status);
|
||||
//Logger.log(Logger.DEBUG,"fork",fork?"true":"false");
|
||||
}
|
||||
//Logger.log(Logger.DEBUG,"fork",fork?"true":"false");
|
||||
if(!fork) {
|
||||
// No transforms ran, so we quit this thread
|
||||
pc=null;
|
||||
}
|
||||
|
||||
// This lets the other threads a chance to run
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This executes a transform
|
||||
* @param aTransform DTransform to execute
|
||||
* @param fork true then a new process is triggered
|
||||
* @param status The return status of the previous node
|
||||
* @return true if the transform ran or a fork occured.
|
||||
*/
|
||||
public boolean transform(DTransform aTransform,boolean fork,int status)
|
||||
{
|
||||
// Check to see if the transform will run (based on the calling nodes return
|
||||
// status
|
||||
if(!aTransform.willRun(status,env)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fork) {
|
||||
// Create the new processor but this time we want a transform to run
|
||||
proc proc = new proc(module,pc,env,aTransform,status);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(aTransform.run(env)) {
|
||||
pc=aTransform.getTo();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // class proc
|
||||
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
package uk.org.retep.dtu;
|
||||
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This manages the links between two nodes.
|
||||
*/
|
||||
public class DTransform
|
||||
{
|
||||
protected DNode from,to;
|
||||
protected int type;
|
||||
|
||||
public DTransform()
|
||||
{
|
||||
this(null,null);
|
||||
}
|
||||
|
||||
public DTransform(DNode aFrom,DNode aTo)
|
||||
{
|
||||
from=aFrom;
|
||||
to=aTo;
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int aType)
|
||||
{
|
||||
type=aType;
|
||||
}
|
||||
|
||||
public void setFrom(DNode aNode)
|
||||
{
|
||||
if(from!=null) {
|
||||
from.removeTo(this);
|
||||
}
|
||||
|
||||
from=aNode;
|
||||
from.setTo(this);
|
||||
}
|
||||
|
||||
public DNode getFrom()
|
||||
{
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setTo(DNode aNode)
|
||||
{
|
||||
if(to!=null) {
|
||||
to.removeFrom(this);
|
||||
}
|
||||
|
||||
to=aNode;
|
||||
aNode.setFrom(this);
|
||||
}
|
||||
|
||||
public DNode getTo()
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* This ensures the minimum tag/attributes are generated.
|
||||
* To extend, extend saveCustomXML() which is called by this method
|
||||
* appropriately.
|
||||
*/
|
||||
public final void saveXML(XMLFactory aFactory)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
// Bare minimum is the tag type, and the destination node's id
|
||||
aFactory.startTag(DConstants.XML_TRANSFORM);
|
||||
aFactory.addAttribute(DConstants.XML_TYPE,Integer.toString(getType()));
|
||||
aFactory.addAttribute(DConstants.XML_TO,Integer.toString(to.getID()));
|
||||
saveCustomXML(aFactory);
|
||||
aFactory.endTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom transformations must overide this method and write direct to the
|
||||
* supplied XMLFactory. A tag is currently open when the method is called, but
|
||||
* is closed immediately this method exits.
|
||||
*/
|
||||
public void saveCustomXML(XMLFactory aFactory)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
// Default method does nothing...
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if we should run based on the calling nodes status. Overide
|
||||
* this to add this sort of checking.
|
||||
*
|
||||
* @param status The return status of the calling node
|
||||
* @param env DEnvironment we are using
|
||||
* @return true if we will run.
|
||||
*/
|
||||
public boolean willRun(int status,DEnvironment env)
|
||||
{
|
||||
switch(getType())
|
||||
{
|
||||
// NOP is the generic link - always run
|
||||
case DConstants.NOP:
|
||||
return true;
|
||||
|
||||
// SUCCESS only runs if the previous node was OK
|
||||
case DConstants.SUCCESS:
|
||||
return status==DNode.OK;
|
||||
|
||||
case DConstants.ERROR:
|
||||
return status==DNode.ERROR;
|
||||
|
||||
// Default - always run. Overide the method if you need to change this
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overide this for a transform to do something.
|
||||
* @param env DEnvironment we are using
|
||||
* @return true if we actually ran. DProcessor will jump to the getTo() node if so.
|
||||
*/
|
||||
public boolean run(DEnvironment env)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#Written by Retep PropertyEditor
|
||||
#Sat Mar 03 16:29:44 GMT+00:00 2001
|
||||
tool.hba=pg_hba.conf editor
|
||||
tool.hba.class=uk.org.retep.util.hba.Editor
|
||||
tool.proped.class=uk.org.retep.util.proped.PropertyEditor
|
||||
tool.hba.type=Misc
|
||||
tool.proped.type=Misc
|
||||
tool.proped=Properties Editor
|
@ -1,33 +0,0 @@
|
||||
package uk.org.retep.tools;
|
||||
|
||||
import javax.swing.JMenuBar;
|
||||
|
||||
/**
|
||||
* Tools can implement this interface to provide the parent manager (the big
|
||||
* application or the StandaloneApp class) enough details to display them.
|
||||
*
|
||||
* If a tool does not implement this class, it gets basic treatment.
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface Tool
|
||||
{
|
||||
/**
|
||||
* @return the JMenuBar for this tool, null if none.
|
||||
*/
|
||||
public JMenuBar getMenuBar();
|
||||
|
||||
/**
|
||||
* @return the title string to go into the JFrame/JInternalFrame's title bar.
|
||||
*/
|
||||
public String getTitle();
|
||||
|
||||
/**
|
||||
* Called by StandaloneApp to indicate this is within a StandaloneApp.
|
||||
* You should assume you are not in standalone mode until this is called.
|
||||
*/
|
||||
public void setStandaloneMode(boolean aMode);
|
||||
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
package uk.org.retep.util;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* Display an Exception to the user
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ExceptionDialog extends JDialog
|
||||
{
|
||||
// This is used to store the parent frame.
|
||||
// Classes like StandaloneApp set's this so that the
|
||||
// displayException() method can work without knowing/finding out
|
||||
// the parent Frame/JFrame.
|
||||
private static Frame globalFrame;
|
||||
|
||||
private static ExceptionDialog globalDialog;
|
||||
|
||||
JPanel panel1 = new JPanel();
|
||||
BorderLayout borderLayout1 = new BorderLayout();
|
||||
JTextArea message = new JTextArea();
|
||||
JPanel jPanel1 = new JPanel();
|
||||
JButton jButton1 = new JButton();
|
||||
GridLayout gridLayout1 = new GridLayout();
|
||||
JButton jButton2 = new JButton();
|
||||
JLabel jLabel1 = new JLabel();
|
||||
|
||||
public ExceptionDialog(Frame frame, String title, boolean modal)
|
||||
{
|
||||
super(frame, title, modal);
|
||||
try
|
||||
{
|
||||
jbInit();
|
||||
pack();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ExceptionDialog()
|
||||
{
|
||||
this(null, "", false);
|
||||
}
|
||||
void jbInit() throws Exception
|
||||
{
|
||||
panel1.setLayout(borderLayout1);
|
||||
message.setBorder(BorderFactory.createLoweredBevelBorder());
|
||||
message.setText("jTextArea1");
|
||||
message.setBackground(Color.lightGray);
|
||||
message.setEditable(false);
|
||||
jButton1.setText("Close");
|
||||
jButton1.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
jButton1_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jPanel1.setLayout(gridLayout1);
|
||||
jButton2.setEnabled(false);
|
||||
jButton2.setText("Stack Trace");
|
||||
jLabel1.setEnabled(false);
|
||||
getContentPane().add(panel1);
|
||||
panel1.add(message, BorderLayout.CENTER);
|
||||
this.getContentPane().add(jPanel1, BorderLayout.SOUTH);
|
||||
jPanel1.add(jButton2, null);
|
||||
jPanel1.add(jLabel1, null);
|
||||
jPanel1.add(jButton1, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Frame used to display all dialog boxes.
|
||||
*/
|
||||
public static void setFrame(Frame aFrame)
|
||||
{
|
||||
globalFrame = aFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a dialog based on the exception
|
||||
* @param ex Exception that was thrown
|
||||
*/
|
||||
public static void displayException(Exception ex)
|
||||
{
|
||||
displayException(ex,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a dialog based on the exception
|
||||
* @param ex Exception that was thrown
|
||||
*/
|
||||
public static void displayException(Exception ex,String msg)
|
||||
{
|
||||
String cname = ex.getClass().getName();
|
||||
int i=cname.lastIndexOf(".");
|
||||
displayException(cname.substring(i+1),ex,msg);
|
||||
}
|
||||
|
||||
public static void displayException(String title,Exception ex)
|
||||
{
|
||||
displayException(title,ex,null);
|
||||
}
|
||||
|
||||
public static void displayException(String title,Exception ex,String msg)
|
||||
{
|
||||
Logger.log(Logger.ERROR,title,ex.getMessage());
|
||||
|
||||
// Default to a stack trace if no frame set
|
||||
if(globalFrame==null) {
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if(globalDialog==null) {
|
||||
globalDialog=new ExceptionDialog(globalFrame,title,true);
|
||||
globalDialog.pack();
|
||||
}
|
||||
|
||||
globalDialog.setTitle(title);
|
||||
|
||||
if(msg!=null) {
|
||||
globalDialog.message.setText(msg);
|
||||
globalDialog.message.append(":\n");
|
||||
}
|
||||
globalDialog.message.append(ex.getMessage());
|
||||
|
||||
globalDialog.pack();
|
||||
globalDialog.setVisible(true);
|
||||
}
|
||||
|
||||
void jButton1_actionPerformed(ActionEvent e)
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
package uk.org.retep.util;
|
||||
|
||||
import uk.org.retep.util.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This is a Singleton that stores global properties, command line arguments
|
||||
* etc.
|
||||
*
|
||||
* All tools are guranteed that this will exist.
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class Globals
|
||||
{
|
||||
private static final Globals SINGLETON = new Globals();
|
||||
|
||||
private Hashtable global= new Hashtable();
|
||||
private Properties props = new Properties();
|
||||
private ArrayList args = new ArrayList();
|
||||
|
||||
private Globals()
|
||||
{
|
||||
}
|
||||
|
||||
public static Globals getInstance()
|
||||
{
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an object from the global pool
|
||||
* @param aKey key of the object
|
||||
* @return The object, null if not found
|
||||
*/
|
||||
public Object get(Object aKey)
|
||||
{
|
||||
return global.get(aKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an object into the global pool
|
||||
* @param aKey key of the object
|
||||
* @param aObj the object to store
|
||||
* @return aObj
|
||||
*/
|
||||
public Object put(Object aKey,Object aObj)
|
||||
{
|
||||
return global.put(aKey,aObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Properties object of all properties
|
||||
*/
|
||||
/*
|
||||
public Properties getProperties()
|
||||
{
|
||||
return props;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param aProp a property supplied to the command line
|
||||
* @return property or NULL if not present
|
||||
*/
|
||||
public String getProperty(String aProp)
|
||||
{
|
||||
return props.getProperty(aProp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aProp a property supplied to the command line
|
||||
* @param aDefault default to return if property was not supplied
|
||||
* @return property value
|
||||
*/
|
||||
public String getProperty(String aProp,String aDefault)
|
||||
{
|
||||
return props.getProperty(aProp,aDefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aID ID of the argument, 0 ... getArgumentCount()-1
|
||||
* @return argument
|
||||
*/
|
||||
public String getArgument(int aID)
|
||||
{
|
||||
return (String) args.get(aID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of String objects representing the arguments
|
||||
*/
|
||||
public String[] getArguments()
|
||||
{
|
||||
return (String[]) args.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator of the arguments
|
||||
*/
|
||||
public Iterator getArgumentIterator()
|
||||
{
|
||||
return args.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of arguments
|
||||
*/
|
||||
public int getArgumentCount()
|
||||
{
|
||||
return args.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the command line arguments
|
||||
*/
|
||||
public void parseArguments(String[] aArgs)
|
||||
throws Exception
|
||||
{
|
||||
for(int i=0;i<aArgs.length;i++) {
|
||||
String arg = aArgs[i];
|
||||
if(arg.startsWith("--") || arg.startsWith("-")) {
|
||||
if(arg.length()>1) {
|
||||
// Split the option at the first '=' char if any
|
||||
int s = arg.startsWith("--") ? 2 : 1 ; // -- or -
|
||||
int e = arg.indexOf("=");
|
||||
String key,val;
|
||||
if(e>s) {
|
||||
// Format: -key=value
|
||||
key=arg.substring(s,e-1);
|
||||
val=arg.substring(e+1);
|
||||
} else if(e>-1 && e<=s) {
|
||||
// Can't have a property without a key!
|
||||
throw new Exception("Invalid option -=");
|
||||
} else {
|
||||
key=arg.substring(s);
|
||||
val=""; // can't be null
|
||||
}
|
||||
|
||||
if(key.equals("d")) {
|
||||
// -d | --d is reserved to set the Logger level
|
||||
int level=0;
|
||||
if(!val.equals("")) {
|
||||
level=Integer.parseInt(val);
|
||||
}
|
||||
Logger.setLevel(level);
|
||||
} else {
|
||||
// Add all other properties into the Properties object
|
||||
props.put(key,val);
|
||||
Logger.log(Logger.INFO,"Argument",key,val);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Just a - on its own?
|
||||
System.out.println("Unknown option: -");
|
||||
}
|
||||
} else {
|
||||
// Add the argument to the array
|
||||
args.add(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
package uk.org.retep.util;
|
||||
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class Logger
|
||||
{
|
||||
protected static int level;
|
||||
protected static PrintWriter logger;
|
||||
|
||||
public static final int NONE = -1;
|
||||
public static final int INFO = 0;
|
||||
public static final int ERROR = 1;
|
||||
public static final int DEBUG = 2;
|
||||
public static final int ALL = 3;
|
||||
|
||||
static {
|
||||
level = NONE;
|
||||
logger = null;
|
||||
};
|
||||
|
||||
private static final String levels[] = {
|
||||
"INFO :",
|
||||
"ERROR:",
|
||||
"DEBUG:",
|
||||
"ALL :"
|
||||
};
|
||||
|
||||
public static void setLevel(int aLevel)
|
||||
{
|
||||
// Incase we have not yet set a logger
|
||||
if(logger==null) {
|
||||
logger = new PrintWriter(System.out);
|
||||
}
|
||||
|
||||
if(aLevel<NONE) {
|
||||
aLevel=NONE;
|
||||
} else if(aLevel>ALL) {
|
||||
aLevel=ALL;
|
||||
}
|
||||
|
||||
level=aLevel;
|
||||
|
||||
if(level>NONE) {
|
||||
log(INFO,"Log level changed to",level,levels[level]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setLogger(PrintWriter pw)
|
||||
{
|
||||
if(logger!=null) {
|
||||
try {
|
||||
logger.flush();
|
||||
logger.close();
|
||||
} catch(Exception ex) {
|
||||
logger=pw;
|
||||
log(ERROR,"Exception while closing logger",ex);
|
||||
}
|
||||
}
|
||||
logger=pw;
|
||||
}
|
||||
|
||||
public static void log(String msg)
|
||||
{
|
||||
log(INFO,msg);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg)
|
||||
{
|
||||
write(aLevel,msg,null);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,int arg1)
|
||||
{
|
||||
Object o[] = {new Integer(arg1)};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,int arg1,Object arg2)
|
||||
{
|
||||
Object o[] = {new Integer(arg1),arg2};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,double arg1)
|
||||
{
|
||||
Object o[] = {new Double(arg1)};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,double arg1,Object arg2)
|
||||
{
|
||||
Object o[] = {new Double(arg1),arg2};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,Object arg1)
|
||||
{
|
||||
Object o[] = {arg1};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,Object arg1,Object arg2)
|
||||
{
|
||||
Object o[] = {arg1,arg2};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,Object arg1,Object arg2,Object arg3)
|
||||
{
|
||||
Object o[] = {arg1,arg2,arg3};
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
public static void log(int aLevel,String msg,Throwable t)
|
||||
{
|
||||
CharArrayWriter buffer = new CharArrayWriter();
|
||||
PrintWriter printWriter = new PrintWriter(buffer);
|
||||
t.printStackTrace(printWriter);
|
||||
Object o[] = {buffer.toString()};
|
||||
buffer.close();
|
||||
write(aLevel,msg,o);
|
||||
}
|
||||
|
||||
private static void write(int aLevel,String aMsg,Object args[])
|
||||
{
|
||||
// Can't be above ALL
|
||||
if(aLevel>ALL) {
|
||||
aLevel=ALL;
|
||||
}
|
||||
|
||||
// Ignore if below or equal to NONE
|
||||
if(aLevel<INFO || aLevel>level) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.print("Logger:");
|
||||
logger.print(levels[aLevel]);
|
||||
logger.print(aMsg);
|
||||
if(args!=null) {
|
||||
for(int a=0;a<args.length;a++) {
|
||||
logger.print(":");
|
||||
logger.print(args[a]);
|
||||
}
|
||||
}
|
||||
logger.println();
|
||||
logger.flush();
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package uk.org.retep.util;
|
||||
|
||||
import uk.org.retep.util.StandaloneApp;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* This is a template for your own Tools. Copy not extend this class. Please
|
||||
* refer to Implementation for details.
|
||||
*
|
||||
* All you need to to is implement the init() method.
|
||||
*
|
||||
* $Id: Main.java,v 1.1 2001/03/05 09:15:36 peter Exp $
|
||||
*/
|
||||
|
||||
public class Main extends StandaloneApp
|
||||
{
|
||||
public Main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
super(args);
|
||||
}
|
||||
|
||||
public JComponent init()
|
||||
throws Exception
|
||||
{
|
||||
// Create your tool here, then do things like load files based on the
|
||||
// command line arguments. Then return that tool.
|
||||
|
||||
// NB: This just allows us to compile. You're implementation must return
|
||||
// the Tool itself.
|
||||
return new JLabel("Replace with your own tool!");
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
Main main = new Main(args);
|
||||
main.pack();
|
||||
main.setVisible(true);
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package uk.org.retep.util;
|
||||
|
||||
import uk.org.retep.tools.Tool;
|
||||
import uk.org.retep.util.Globals;
|
||||
import uk.org.retep.util.ExceptionDialog;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* This provides the basic services needed for enabling some of the tools to
|
||||
* run in a Stand-alone fassion.
|
||||
*
|
||||
* Note: Because it's designed for standalone use, if this window is closed,
|
||||
* the JVM is terminated. Do not use for normal application use.
|
||||
*
|
||||
* $Id: StandaloneApp.java,v 1.2 2001/03/05 10:18:48 peter Exp $
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class StandaloneApp extends JFrame
|
||||
{
|
||||
public StandaloneApp(String[] aArgs)
|
||||
throws Exception
|
||||
{
|
||||
super(); // Initialise JFrame
|
||||
|
||||
// Allow dialogs to work with us
|
||||
ExceptionDialog.setFrame(this);
|
||||
|
||||
// Add a window listener
|
||||
this.addWindowListener(new java.awt.event.WindowAdapter()
|
||||
{
|
||||
public void windowClosing(WindowEvent e)
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
// Parse the command line arguments
|
||||
Globals.getInstance().parseArguments(aArgs);
|
||||
|
||||
// Now initialise this tool (init is overidden)
|
||||
JComponent tool = null;
|
||||
try {
|
||||
tool = init();
|
||||
} catch(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Now add to this frame
|
||||
this.getContentPane().add(tool, BorderLayout.CENTER);
|
||||
|
||||
// Finally call the Tool interface
|
||||
if(tool instanceof Tool) {
|
||||
Tool t = (Tool) tool;
|
||||
|
||||
// Notify the tool we are a standalone
|
||||
t.setStandaloneMode(true);
|
||||
|
||||
// Fetch the title
|
||||
setTitle(t.getTitle());
|
||||
|
||||
// and a MenuBar (if needed)
|
||||
JMenuBar mb = t.getMenuBar();
|
||||
if(mb!=null) {
|
||||
setJMenuBar(t.getMenuBar());
|
||||
}
|
||||
} else {
|
||||
// Ok, set a default title string
|
||||
setTitle("RetepTools Standalone");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* You must overide this method with your initialiser.
|
||||
*/
|
||||
public abstract JComponent init() throws Exception;
|
||||
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
package uk.org.retep.util.hba;
|
||||
|
||||
import uk.org.retep.tools.Tool;
|
||||
import uk.org.retep.util.models.HBATableModel;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.swing.table.*;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* pg_hba.conf editor (& repairer)
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class Editor extends JPanel implements Tool
|
||||
{
|
||||
BorderLayout borderLayout1 = new BorderLayout();
|
||||
HBATableModel model = new HBATableModel();
|
||||
JPanel jPanel1 = new JPanel();
|
||||
GridBagLayout gridBagLayout1 = new GridBagLayout();
|
||||
JLabel jLabel1 = new JLabel();
|
||||
JComboBox typeEntry = new JComboBox();
|
||||
JLabel jLabel2 = new JLabel();
|
||||
JLabel jLabel3 = new JLabel();
|
||||
JLabel jLabel4 = new JLabel();
|
||||
JTextField ipEntry = new JTextField();
|
||||
JTextField maskEntry = new JTextField();
|
||||
JComboBox authEntry = new JComboBox();
|
||||
JTextField argEntry = new JTextField();
|
||||
JLabel jLabel5 = new JLabel();
|
||||
JPanel jPanel2 = new JPanel();
|
||||
FlowLayout flowLayout1 = new FlowLayout();
|
||||
JButton jButton1 = new JButton();
|
||||
JButton jButton2 = new JButton();
|
||||
JScrollPane jScrollPane1 = new JScrollPane();
|
||||
JButton jButton3 = new JButton();
|
||||
JTable jTable1 = new JTable();
|
||||
|
||||
public Editor()
|
||||
{
|
||||
try
|
||||
{
|
||||
jbInit();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
void jbInit() throws Exception
|
||||
{
|
||||
this.setLayout(borderLayout1);
|
||||
jTable1.setPreferredSize(new Dimension(600, 300));
|
||||
jTable1.setModel(model);
|
||||
this.setPreferredSize(new Dimension(600, 300));
|
||||
this.add(jScrollPane1, BorderLayout.CENTER);
|
||||
jScrollPane1.getViewport().add(jTable1, null);
|
||||
jPanel1.setLayout(gridBagLayout1);
|
||||
jLabel1.setText("Type");
|
||||
jLabel2.setText("IP Address");
|
||||
jLabel3.setText("Mask");
|
||||
jLabel4.setText("Authentication");
|
||||
ipEntry.setText("jTextField1");
|
||||
maskEntry.setText("jTextField2");
|
||||
argEntry.setText("jTextField3");
|
||||
jLabel5.setText("Argument");
|
||||
jPanel2.setLayout(flowLayout1);
|
||||
jButton1.setText("New entry");
|
||||
jButton2.setText("Validate");
|
||||
jButton3.setText("Devele");
|
||||
this.add(jPanel1, BorderLayout.SOUTH);
|
||||
jPanel1.add(jLabel1, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(typeEntry, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(jLabel2, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(jLabel3, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(jLabel4, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(ipEntry, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(maskEntry, new GridBagConstraints(4, 1, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(authEntry, new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(argEntry, new GridBagConstraints(4, 2, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(jLabel5, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0
|
||||
,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel1.add(jPanel2, new GridBagConstraints(0, 3, 5, 1, 0.0, 0.0
|
||||
,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
jPanel2.add(jButton3, null);
|
||||
jPanel2.add(jButton1, null);
|
||||
jPanel2.add(jButton2, null);
|
||||
}
|
||||
|
||||
public void openFile(String aFilename)
|
||||
throws IOException
|
||||
{
|
||||
FileInputStream fis = new FileInputStream(aFilename);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
|
||||
ArrayList list = model.getArray();
|
||||
|
||||
String s = br.readLine();
|
||||
while(s!=null) {
|
||||
if(s.startsWith("#")) {
|
||||
// ignore comments
|
||||
} else {
|
||||
Record rec = Record.parseLine(s);
|
||||
if(rec!=null) {
|
||||
rec.validate();
|
||||
list.add(rec);
|
||||
}
|
||||
}
|
||||
s=br.readLine();
|
||||
}
|
||||
|
||||
model.fireTableDataChanged();
|
||||
}
|
||||
|
||||
public JMenuBar getMenuBar()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return "pg_hba.conf Editor/Repair tool";
|
||||
}
|
||||
|
||||
public void setStandaloneMode(boolean aMode)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package uk.org.retep.util.hba;
|
||||
|
||||
import uk.org.retep.util.ExceptionDialog;
|
||||
import uk.org.retep.util.Globals;
|
||||
import uk.org.retep.util.Logger;
|
||||
import uk.org.retep.util.StandaloneApp;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* Standalone entry point for the Properties editor
|
||||
*
|
||||
* $Id: Main.java,v 1.1 2001/03/05 09:15:37 peter Exp $
|
||||
*/
|
||||
|
||||
public class Main extends StandaloneApp
|
||||
{
|
||||
public Main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
super(args);
|
||||
}
|
||||
|
||||
public JComponent init()
|
||||
throws Exception
|
||||
{
|
||||
Globals globals = Globals.getInstance();
|
||||
|
||||
Editor editor = new Editor();
|
||||
|
||||
if(globals.getArgumentCount()>0) {
|
||||
editor.openFile(globals.getArgument(0));
|
||||
}
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
Main main = new Main(args);
|
||||
main.pack();
|
||||
main.setVisible(true);
|
||||
}
|
||||
}
|
@ -1,238 +0,0 @@
|
||||
package uk.org.retep.util.hba;
|
||||
|
||||
import uk.org.retep.util.Logger;
|
||||
import uk.org.retep.util.misc.IPAddress;
|
||||
import uk.org.retep.util.misc.WStringTokenizer;
|
||||
|
||||
/**
|
||||
* Used to store the entries of a pg_hba.conf file
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class Record
|
||||
{
|
||||
int type;
|
||||
String dbname;
|
||||
IPAddress ip;
|
||||
IPAddress mask;
|
||||
int authType;
|
||||
String authArg;
|
||||
|
||||
public static final int TYPE_LOCAL = 0;
|
||||
public static final int TYPE_HOST = 1;
|
||||
public static final int TYPE_HOSTSSL = 2;
|
||||
|
||||
public static final String types[] = {
|
||||
"local","host","hostssl"
|
||||
};
|
||||
|
||||
public static final int AUTH_TRUST = 0;
|
||||
public static final int AUTH_PASSWORD = 1;
|
||||
public static final int AUTH_CRYPT = 2;
|
||||
public static final int AUTH_IDENT = 3;
|
||||
public static final int AUTH_KRB4 = 4;
|
||||
public static final int AUTH_KRB5 = 5;
|
||||
public static final int AUTH_REJECT = 6;
|
||||
|
||||
public static final String auths[] = {
|
||||
"trust","password","crypt",
|
||||
"ident",
|
||||
"krb4","krb5",
|
||||
"reject"
|
||||
};
|
||||
|
||||
private static final String spc = " ";
|
||||
|
||||
public Record()
|
||||
{
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int aType)
|
||||
{
|
||||
type=aType;
|
||||
}
|
||||
|
||||
public String getDatabase()
|
||||
{
|
||||
return dbname;
|
||||
}
|
||||
|
||||
public void setDatabase(String aDB)
|
||||
{
|
||||
dbname=aDB;
|
||||
}
|
||||
|
||||
public int getAuthType()
|
||||
{
|
||||
return authType;
|
||||
}
|
||||
|
||||
public void setAuthType(int aType)
|
||||
{
|
||||
authType=aType;
|
||||
}
|
||||
|
||||
public String getAuthArgs()
|
||||
{
|
||||
return authArg;
|
||||
}
|
||||
|
||||
public void setAuthArgs(String aArg)
|
||||
{
|
||||
authArg=aArg;
|
||||
}
|
||||
|
||||
public IPAddress getIP()
|
||||
{
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIP(String aArg)
|
||||
{
|
||||
setIP(new IPAddress(aArg));
|
||||
}
|
||||
|
||||
public void setIP(IPAddress aArg)
|
||||
{
|
||||
ip=aArg;
|
||||
}
|
||||
|
||||
public IPAddress getMask()
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
public void setMask(String aArg)
|
||||
{
|
||||
setMask(new IPAddress(aArg));
|
||||
}
|
||||
|
||||
public void setMask(IPAddress aArg)
|
||||
{
|
||||
mask=aArg;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
write(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public void write(StringBuffer buf)
|
||||
{
|
||||
buf.append(types[type]).append(spc);
|
||||
|
||||
if(type==TYPE_HOST || type==TYPE_HOSTSSL) {
|
||||
buf.append(getIP()).append(spc);
|
||||
buf.append(getMask()).append(spc);
|
||||
}
|
||||
|
||||
buf.append(auths[authType]);
|
||||
|
||||
// Now the authArg
|
||||
switch(type)
|
||||
{
|
||||
// These have no authArgs
|
||||
case AUTH_TRUST:
|
||||
case AUTH_REJECT:
|
||||
case AUTH_KRB4:
|
||||
case AUTH_KRB5:
|
||||
break;
|
||||
|
||||
// These must have an arg
|
||||
case AUTH_IDENT:
|
||||
buf.append(spc).append(getAuthArgs());
|
||||
break;
|
||||
|
||||
// These may have an optional arg
|
||||
case AUTH_PASSWORD:
|
||||
case AUTH_CRYPT:
|
||||
if(!(authArg==null || authArg.equals("")))
|
||||
buf.append(spc).append(getAuthArgs());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static WStringTokenizer tok;
|
||||
|
||||
public static Record parseLine(String s)
|
||||
{
|
||||
Record res = new Record();
|
||||
int type;
|
||||
|
||||
if(s==null || s.equals("") || s.startsWith("#"))
|
||||
return null;
|
||||
|
||||
if(tok==null)
|
||||
tok=new WStringTokenizer();
|
||||
|
||||
tok.setString(s);
|
||||
|
||||
type=WStringTokenizer.matchToken(types,tok.nextToken());
|
||||
res.setType(type);
|
||||
|
||||
res.setDatabase(tok.nextToken());
|
||||
|
||||
if(type==TYPE_HOST || type==TYPE_HOSTSSL) {
|
||||
res.setIP(new IPAddress(tok.nextToken()));
|
||||
res.setMask(new IPAddress(tok.nextToken()));
|
||||
}
|
||||
|
||||
res.setAuthType(WStringTokenizer.matchToken(auths,tok.nextToken()));
|
||||
res.setAuthArgs(tok.nextToken());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static final int VALID = 0;
|
||||
public static final int INVALID_TYPE = 1;
|
||||
public static final int INVALID_IPREQUIRED = 2;
|
||||
|
||||
/**
|
||||
* Validates the record
|
||||
*/
|
||||
public int validate()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_HOST:
|
||||
case TYPE_HOSTSSL:
|
||||
if(ip==null || ip.isInvalid()) {
|
||||
Logger.log(Logger.INFO,"pg_hba.conf: IP missing or invalid - repairing");
|
||||
setMask("127.0.0.1");
|
||||
}
|
||||
|
||||
if(mask==null || mask.isInvalid() || !ip.validateMask(mask)) {
|
||||
Logger.log(Logger.INFO,"pg_hba.conf: IP address without mask - repairing");
|
||||
setMask(ip.getMask());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_LOCAL:
|
||||
break;
|
||||
|
||||
default:
|
||||
return INVALID_TYPE;
|
||||
}
|
||||
|
||||
return VALID;
|
||||
}
|
||||
|
||||
/*
|
||||
# host all 192.168.54.1 255.255.255.255 reject
|
||||
# host all 0.0.0.0 0.0.0.0 krb5
|
||||
# host all 192.168.0.0 255.255.0.0 ident omicron
|
||||
#
|
||||
|
||||
local all trust
|
||||
host all 127.0.0.1 255.255.255.255 trust
|
||||
*/
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
package uk.org.retep.util.misc;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Represent an IP address
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class IPAddress
|
||||
{
|
||||
protected long address;
|
||||
protected long b[] = new long[4];
|
||||
protected boolean invalid=true;
|
||||
|
||||
public IPAddress()
|
||||
{
|
||||
}
|
||||
|
||||
public IPAddress(String s)
|
||||
{
|
||||
setAddress(s);
|
||||
}
|
||||
|
||||
public synchronized void setAddress(String s)
|
||||
{
|
||||
if(s==null || s.equals("")) {
|
||||
invalid=true;
|
||||
return;
|
||||
}
|
||||
|
||||
address=0;
|
||||
StringTokenizer tok = new StringTokenizer(s,".");
|
||||
int i=0;
|
||||
while(i<4 && tok.hasMoreElements()) {
|
||||
b[i++] = Long.parseLong(tok.nextToken());
|
||||
}
|
||||
while(i<4) {
|
||||
b[i++]=0;
|
||||
}
|
||||
|
||||
invalid=false;
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void refresh()
|
||||
{
|
||||
if(invalid)
|
||||
return;
|
||||
address = (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | (b[3]);
|
||||
}
|
||||
|
||||
public boolean isInvalid()
|
||||
{
|
||||
refresh();
|
||||
return invalid;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
refresh();
|
||||
if(invalid)
|
||||
return "*INVALID*";
|
||||
|
||||
return Long.toString(b[0])+"."+Long.toString(b[1])+"."+Long.toString(b[2])+"."+Long.toString(b[3]);
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(o instanceof IPAddress) {
|
||||
IPAddress ip = (IPAddress) o;
|
||||
|
||||
refresh();
|
||||
ip.refresh();
|
||||
|
||||
if(ip.invalid == invalid)
|
||||
return false;
|
||||
|
||||
return address==ip.address;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int gethoststart(long b)
|
||||
{
|
||||
if((b & 0x80)==0x00) return 1; // class A
|
||||
if((b & 0xc0)==0x80) return 2; // class B
|
||||
if((b & 0xe0)==0xc0) return 3; // class C
|
||||
return 4; // class D
|
||||
}
|
||||
|
||||
public boolean validateMask(IPAddress mask)
|
||||
{
|
||||
// If were a network check the host mask
|
||||
int i=gethoststart(b[0]);
|
||||
System.out.println("Host start "+i);
|
||||
while(i<4 && b[i]==0) {
|
||||
if(mask.b[i++]>0)
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i=0;i<4;i++) {
|
||||
if((b[i]&mask.b[i])!=b[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public IPAddress getMask()
|
||||
{
|
||||
IPAddress mask = new IPAddress();
|
||||
int i=3;
|
||||
while(i>-1 && b[i]==0) {
|
||||
mask.b[i--]=0;
|
||||
}
|
||||
while(i>-1) {
|
||||
mask.b[i--]=255;
|
||||
}
|
||||
mask.invalid=false;
|
||||
mask.refresh();
|
||||
return mask;
|
||||
}
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
package uk.org.retep.util.misc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Misc Properties utilities..
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PropertiesIO
|
||||
{
|
||||
|
||||
public PropertiesIO()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a TreeMap based on the given Properties object. This is useful
|
||||
* because the keys will be in sorted order.
|
||||
*/
|
||||
public static TreeMap getTreeMap(Properties p)
|
||||
{
|
||||
TreeMap map = new TreeMap();
|
||||
Iterator e = p.keySet().iterator();
|
||||
while(e.hasNext()) {
|
||||
Object k = e.next();
|
||||
map.put(k,p.get(k));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Properties file to the writer. This is similar to Properties.save
|
||||
* except you can pick the key/value separator
|
||||
*/
|
||||
public static synchronized void save(Properties p,OutputStream out,char sep,String header)
|
||||
throws IOException
|
||||
{
|
||||
save(p,p.keySet().iterator(),out,sep,header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Properties file to the writer. This is similar to Properties.save
|
||||
* except you can pick the key/value separator and the keys are written
|
||||
* in a sorted manner
|
||||
*/
|
||||
public static synchronized void saveSorted(Properties p,OutputStream out,char sep,String header)
|
||||
throws IOException
|
||||
{
|
||||
save(p,getTreeMap(p).keySet().iterator(),out,sep,header);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the same as save, only the keys in the enumeration are written.
|
||||
*/
|
||||
public static synchronized void save(Properties p,Iterator e, OutputStream out,char sep,String header)
|
||||
throws IOException
|
||||
{
|
||||
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
|
||||
|
||||
if (header != null) {
|
||||
w.write('#');
|
||||
w.write(header);
|
||||
w.newLine();
|
||||
}
|
||||
|
||||
w.write('#');
|
||||
w.write(new Date().toString());
|
||||
w.newLine();
|
||||
|
||||
while(e.hasNext()) {
|
||||
String key = (String)e.next();
|
||||
w.write(encode(key,true));
|
||||
w.write(sep);
|
||||
w.write(encode((String)p.get(key),false));
|
||||
w.newLine();
|
||||
}
|
||||
w.flush();
|
||||
}
|
||||
|
||||
private static final String specialSaveChars = "=: \t\r\n\f#!";
|
||||
|
||||
/**
|
||||
* Encodes a string in a way similar to the JDK's Properties method
|
||||
*/
|
||||
public static String encode(String s, boolean escapeSpace)
|
||||
{
|
||||
int l=s.length();
|
||||
StringBuffer buf = new StringBuffer(l<<1);
|
||||
|
||||
for(int i=0;i<l;i++) {
|
||||
char c = s.charAt(i);
|
||||
switch(c)
|
||||
{
|
||||
case ' ':
|
||||
if(i==0 || escapeSpace) {
|
||||
buf.append('\\');
|
||||
}
|
||||
buf.append(' ');
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
buf.append('\\').append('\\');
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
buf.append('\\').append('t');
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
buf.append('\\').append('n');
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
buf.append('\\').append('r');
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
buf.append('\\').append('f');
|
||||
break;
|
||||
|
||||
default:
|
||||
if((c<0x20)||(c>0x7e)) {
|
||||
buf.append('\\').append('u');
|
||||
buf.append(toHex((c >> 12) & 0xF));
|
||||
buf.append(toHex((c >> 8) & 0xF));
|
||||
buf.append(toHex((c >> 4) & 0xF));
|
||||
buf.append(toHex( c & 0xF));
|
||||
} else {
|
||||
if (specialSaveChars.indexOf(c) != -1)
|
||||
buf.append('\\');
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a nibble to a hex character
|
||||
* @param nibble the nibble to convert.
|
||||
*/
|
||||
public static char toHex(int n) {
|
||||
return hd[(n & 0xF)];
|
||||
}
|
||||
|
||||
/** A table of hex digits */
|
||||
private static final char[] hd = {
|
||||
'0','1','2','3','4','5','6','7',
|
||||
'8','9','A','B','C','D','E','F'
|
||||
};
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package uk.org.retep.util.misc;
|
||||
|
||||
/**
|
||||
* Similar to StringTokenizer but handles white spaces and multiple delimiters
|
||||
* between tokens. It also handles quotes
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class WStringTokenizer
|
||||
{
|
||||
String string;
|
||||
int pos,len;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public WStringTokenizer()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor: set the initial string
|
||||
* @param aString String to tokenise
|
||||
*/
|
||||
public WStringTokenizer(String aString)
|
||||
{
|
||||
setString(aString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aString String to tokenise
|
||||
*/
|
||||
public void setString(String aString)
|
||||
{
|
||||
string=aString;
|
||||
pos=0;
|
||||
len=string.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if more tokens may be possible
|
||||
*/
|
||||
public boolean hasMoreTokens()
|
||||
{
|
||||
return !(string==null || pos==len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return next token, null if complete.
|
||||
*/
|
||||
public String nextToken()
|
||||
{
|
||||
char c;
|
||||
boolean q=false;
|
||||
|
||||
if(!hasMoreTokens())
|
||||
return null;
|
||||
|
||||
// find start of token
|
||||
while(pos<len) {
|
||||
c = string.charAt(pos);
|
||||
if(c=='\'' || c=='\"')
|
||||
q=!q;
|
||||
if(q || c==' '||c=='\t')
|
||||
pos++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// find last char of token
|
||||
int p=pos;
|
||||
while(pos<len) {
|
||||
c = string.charAt(pos);
|
||||
if(c=='\'' || c=='\"')
|
||||
q=!q;
|
||||
if(!q && (c==' '||c=='\t') )
|
||||
break;
|
||||
else
|
||||
pos++;
|
||||
}
|
||||
|
||||
return string.substring(p,pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare a string against an array of strings and return the index
|
||||
* @param t array to compare against (all lowercase)
|
||||
* @param s string to test
|
||||
* @return index in t of s, -1 if not present
|
||||
*/
|
||||
public static int matchToken(String[] t,String s)
|
||||
{
|
||||
s=s.toLowerCase();
|
||||
for(int i=0;i<t.length;i++)
|
||||
if(t[i].equals(s))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package uk.org.retep.util.models;
|
||||
|
||||
import uk.org.retep.util.hba.Record;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import javax.swing.table.*;
|
||||
|
||||
/**
|
||||
* A TableModel to display the contents of a pg_hba.conf file
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class HBATableModel extends AbstractTableModel
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
private static final String cols[] = {
|
||||
"Type","Database","IP Address","IP Mask","Authentication","Arguments"
|
||||
};
|
||||
|
||||
|
||||
public HBATableModel()
|
||||
{
|
||||
}
|
||||
|
||||
public ArrayList getArray()
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
public int getColumnCount()
|
||||
{
|
||||
return cols.length;
|
||||
}
|
||||
|
||||
public Object getValueAt(int aRow, int aCol)
|
||||
{
|
||||
Record rec = (Record) list.get(aRow);
|
||||
int t;
|
||||
|
||||
switch(aCol)
|
||||
{
|
||||
case 0:
|
||||
t = rec.getType();
|
||||
return t<0 ? "ERR" : Record.types[t] ;
|
||||
|
||||
case 1:
|
||||
return rec.getDatabase();
|
||||
|
||||
case 2:
|
||||
return rec.getIP();
|
||||
|
||||
case 3:
|
||||
return rec.getMask();
|
||||
|
||||
case 4:
|
||||
t=rec.getAuthType();
|
||||
return t<0 ? "ERR" : Record.auths[t] ;
|
||||
|
||||
case 5:
|
||||
return rec.getAuthArgs();
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public int getRowCount()
|
||||
{
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex)
|
||||
{
|
||||
/**@todo: Override this javax.swing.table.AbstractTableModel method*/
|
||||
return super.isCellEditable( rowIndex, columnIndex);
|
||||
}
|
||||
|
||||
public String getColumnName(int aColumn)
|
||||
{
|
||||
return cols[aColumn];
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
|
||||
{
|
||||
/**@todo: Override this javax.swing.table.AbstractTableModel method*/
|
||||
super.setValueAt( aValue, rowIndex, columnIndex);
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
package uk.org.retep.util.models;
|
||||
|
||||
import uk.org.retep.util.Logger;
|
||||
import uk.org.retep.util.misc.PropertiesIO;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.swing.table.*;
|
||||
|
||||
import java.text.*;
|
||||
|
||||
/**
|
||||
* A TableModel that shows a view of a PropertyFile object
|
||||
*
|
||||
* $Id: PropertiesTableModel.java,v 1.1 2001/03/05 09:15:37 peter Exp $
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PropertiesTableModel extends AbstractTableModel
|
||||
{
|
||||
// The properties
|
||||
protected TreeMap properties;
|
||||
protected Properties origProperties;
|
||||
protected Object keys[];
|
||||
|
||||
public PropertiesTableModel()
|
||||
{
|
||||
this(new Properties());
|
||||
}
|
||||
|
||||
public PropertiesTableModel(Properties aProperties)
|
||||
{
|
||||
setProperties(aProperties);
|
||||
}
|
||||
|
||||
public synchronized int getKeyRow(Object k)
|
||||
{
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if(keys[i].equals(k)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Best not use this one to update, use the put method in this class!
|
||||
*/
|
||||
public Properties getProperties()
|
||||
{
|
||||
return origProperties;
|
||||
}
|
||||
|
||||
public synchronized void put(Object k,Object v)
|
||||
{
|
||||
properties.put(k,v);
|
||||
origProperties.put(k,v);
|
||||
refresh();
|
||||
}
|
||||
|
||||
public Object get(Object k)
|
||||
{
|
||||
return origProperties.get(k);
|
||||
}
|
||||
|
||||
public synchronized void remove(Object k)
|
||||
{
|
||||
properties.remove(k);
|
||||
origProperties.remove(k);
|
||||
refresh();
|
||||
}
|
||||
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
return origProperties.contains(o);
|
||||
}
|
||||
|
||||
public boolean containsKey(Object o)
|
||||
{
|
||||
return origProperties.containsKey(o);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object o)
|
||||
{
|
||||
return origProperties.containsValue(o);
|
||||
}
|
||||
|
||||
public void setProperties(Properties aProperties)
|
||||
{
|
||||
origProperties=aProperties;
|
||||
properties = PropertiesIO.getTreeMap(aProperties);
|
||||
refresh();
|
||||
}
|
||||
|
||||
public void refresh()
|
||||
{
|
||||
keys = properties.keySet().toArray();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
private static final String cols[] = {
|
||||
"Property","Value"
|
||||
};
|
||||
|
||||
public int getColumnCount()
|
||||
{
|
||||
return cols.length;
|
||||
}
|
||||
|
||||
public Object getValueAt(int aRow, int aColumn)
|
||||
{
|
||||
if(aRow<0 || aRow>=keys.length || aColumn<0 || aColumn>=cols.length)
|
||||
return null;
|
||||
|
||||
Object key = keys[aRow];
|
||||
|
||||
switch(aColumn)
|
||||
{
|
||||
case 0:
|
||||
return key;
|
||||
|
||||
case 1:
|
||||
return properties.get(key);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getRowCount()
|
||||
{
|
||||
return keys.length;
|
||||
}
|
||||
|
||||
public String getColumnName(int aColumn)
|
||||
{
|
||||
return cols[aColumn];
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, int aRow, int aColumn)
|
||||
{
|
||||
if(aRow<0 || aRow>=keys.length || aColumn<0 || aColumn>=cols.length)
|
||||
return;
|
||||
|
||||
switch(aColumn)
|
||||
{
|
||||
// Rename the key (only if not already present). If already present
|
||||
// the refresh() will replace with the old one anyhow...
|
||||
case 0:
|
||||
if(!properties.containsKey(aValue)) {
|
||||
Object oldValue = get(keys[aRow]);
|
||||
remove(keys[aRow]);
|
||||
put(aValue,oldValue);
|
||||
}
|
||||
refresh();
|
||||
break;
|
||||
|
||||
// Update the value...
|
||||
case 1:
|
||||
put(keys[aRow],aValue);
|
||||
//refresh();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should never be called
|
||||
Logger.log(Logger.ERROR,"PropertiesTableModel: Column range",aColumn);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int aRow, int aColumn)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package uk.org.retep.util.proped;
|
||||
|
||||
import uk.org.retep.util.ExceptionDialog;
|
||||
import uk.org.retep.util.Globals;
|
||||
import uk.org.retep.util.Logger;
|
||||
import uk.org.retep.util.StandaloneApp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
* Standalone entry point for the Properties editor
|
||||
*
|
||||
* $Id: Main.java,v 1.1 2001/03/05 09:15:38 peter Exp $
|
||||
*/
|
||||
|
||||
public class Main extends StandaloneApp
|
||||
{
|
||||
public Main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
super(args);
|
||||
}
|
||||
|
||||
public JComponent init()
|
||||
throws Exception
|
||||
{
|
||||
Globals globals = Globals.getInstance();
|
||||
|
||||
PropertyEditor panel = new PropertyEditor();
|
||||
|
||||
// Only handle 1 open at a time in standalone mode
|
||||
if(globals.getArgumentCount()>0) {
|
||||
try {
|
||||
panel.openFile(globals.getArgument(0));
|
||||
} catch(IOException ioe) {
|
||||
ExceptionDialog.displayException(ioe,"while loading "+globals.getArgument(0));
|
||||
throw (Exception) ioe.fillInStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws Exception
|
||||
{
|
||||
Main main = new Main(args);
|
||||
main.pack();
|
||||
main.setVisible(true);
|
||||
}
|
||||
}
|
@ -1,381 +0,0 @@
|
||||
package uk.org.retep.util.proped;
|
||||
|
||||
import uk.org.retep.util.ExceptionDialog;
|
||||
import uk.org.retep.util.misc.PropertiesIO;
|
||||
import uk.org.retep.util.models.PropertiesTableModel;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* A property file editor
|
||||
*
|
||||
* $Id: PropertyEditor.java,v 1.1 2001/03/05 09:15:38 peter Exp $
|
||||
*
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PropertyEditor
|
||||
extends JPanel
|
||||
implements uk.org.retep.tools.Tool
|
||||
{
|
||||
BorderLayout borderLayout1 = new BorderLayout();
|
||||
|
||||
// The filename, null if not set
|
||||
String filename;
|
||||
File file;
|
||||
|
||||
JScrollPane jScrollPane1 = new JScrollPane();
|
||||
JTable contentTable = new JTable();
|
||||
|
||||
PropertiesTableModel model = new PropertiesTableModel();
|
||||
|
||||
boolean standaloneMode;
|
||||
|
||||
private static final String TITLE_PREFIX = "Retep PropertyEditor";
|
||||
JPopupMenu popupMenu = new JPopupMenu();
|
||||
JMenuItem newPopupItem = new JMenuItem();
|
||||
JMenuItem dupPopupItem = new JMenuItem();
|
||||
JMenuItem delPopupItem = new JMenuItem();
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
JMenu jMenu1 = new JMenu();
|
||||
JMenuItem jMenuItem4 = new JMenuItem();
|
||||
JMenuItem jMenuItem5 = new JMenuItem();
|
||||
JMenuItem jMenuItem6 = new JMenuItem();
|
||||
JMenuItem jMenuItem7 = new JMenuItem();
|
||||
JMenuItem jMenuItem8 = new JMenuItem();
|
||||
JMenuItem closeMenuItem = new JMenuItem();
|
||||
|
||||
public PropertyEditor()
|
||||
{
|
||||
try
|
||||
{
|
||||
jbInit();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the default menubar
|
||||
*/
|
||||
public JMenuBar getMenuBar()
|
||||
{
|
||||
return menuBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the File menu
|
||||
*/
|
||||
public JMenu getMenu()
|
||||
{
|
||||
return jMenu1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the recomended title string for the parent JFrame/JInternalFrame
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
if(filename==null) {
|
||||
return TITLE_PREFIX;
|
||||
}
|
||||
return TITLE_PREFIX+": "+filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets menus up to Standalone mode
|
||||
*/
|
||||
public void setStandaloneMode(boolean aMode)
|
||||
{
|
||||
standaloneMode=aMode;
|
||||
if(aMode) {
|
||||
closeMenuItem.setText("Exit");
|
||||
} else {
|
||||
closeMenuItem.setText("Close");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStandalone()
|
||||
{
|
||||
return standaloneMode;
|
||||
}
|
||||
|
||||
public void openFile(String aFile)
|
||||
throws IOException
|
||||
{
|
||||
openFile(new File(aFile));
|
||||
}
|
||||
|
||||
public void openFile(File aFile)
|
||||
throws IOException
|
||||
{
|
||||
FileInputStream fis = new FileInputStream(aFile);
|
||||
Properties p = new Properties();
|
||||
p.load(fis);
|
||||
fis.close();
|
||||
model.setProperties(p);
|
||||
|
||||
file=aFile;
|
||||
filename = aFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
public void saveFile(File aFile)
|
||||
throws IOException
|
||||
{
|
||||
FileOutputStream fis = new FileOutputStream(aFile);
|
||||
PropertiesIO.save(model.getProperties(),fis,'=',"Written by "+TITLE_PREFIX);
|
||||
fis.close();
|
||||
|
||||
filename = aFile.getAbsolutePath();
|
||||
file = aFile;
|
||||
}
|
||||
|
||||
void jbInit() throws Exception
|
||||
{
|
||||
this.setLayout(borderLayout1);
|
||||
contentTable.setToolTipText("");
|
||||
contentTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||
contentTable.setModel(model);
|
||||
contentTable.addMouseListener(new java.awt.event.MouseAdapter()
|
||||
{
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
contentTable_mouseClicked(e);
|
||||
}
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
contentTable_mouseReleased(e);
|
||||
}
|
||||
});
|
||||
newPopupItem.setText("New");
|
||||
newPopupItem.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
newPopupItem_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
dupPopupItem.setText("Duplicate");
|
||||
dupPopupItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(67, java.awt.event.KeyEvent.CTRL_MASK, false));
|
||||
dupPopupItem.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
dupPopupItem_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
delPopupItem.setText("Delete");
|
||||
delPopupItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(68, java.awt.event.KeyEvent.CTRL_MASK, false));
|
||||
delPopupItem.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
delPopupItem_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenu1.setText("File");
|
||||
jMenuItem4.setText("Open");
|
||||
jMenuItem4.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
jMenuItem4_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenuItem5.setText("Save");
|
||||
jMenuItem5.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
jMenuItem5_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenuItem6.setText("Save As");
|
||||
jMenuItem6.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
jMenuItem6_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenuItem7.setText("Revert");
|
||||
jMenuItem7.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
jMenuItem7_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenuItem8.setText("Print");
|
||||
closeMenuItem.setText("Close");
|
||||
closeMenuItem.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
closeMenuItem_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenu2.setText("Edit");
|
||||
jMenuItem1.setText("New");
|
||||
jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(78, java.awt.event.KeyEvent.CTRL_MASK, false));
|
||||
jMenuItem1.addActionListener(new java.awt.event.ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
newPopupItem_actionPerformed(e);
|
||||
}
|
||||
});
|
||||
jMenuItem2.setText("Duplicate");
|
||||
jMenuItem3.setText("Delete");
|
||||
this.add(jScrollPane1, BorderLayout.CENTER);
|
||||
jScrollPane1.getViewport().add(contentTable, null);
|
||||
popupMenu.add(newPopupItem);
|
||||
popupMenu.add(dupPopupItem);
|
||||
popupMenu.add(delPopupItem);
|
||||
menuBar.add(jMenu1);
|
||||
menuBar.add(jMenu2);
|
||||
jMenu1.add(jMenuItem4);
|
||||
jMenu1.add(jMenuItem5);
|
||||
jMenu1.add(jMenuItem6);
|
||||
jMenu1.add(jMenuItem7);
|
||||
jMenu1.addSeparator();
|
||||
jMenu1.add(jMenuItem8);
|
||||
jMenu1.addSeparator();
|
||||
jMenu1.add(closeMenuItem);
|
||||
jMenu2.add(jMenuItem1);
|
||||
jMenu2.add(jMenuItem2);
|
||||
jMenu2.add(jMenuItem3);
|
||||
}
|
||||
|
||||
Point popupPoint = new Point();
|
||||
JMenu jMenu2 = new JMenu();
|
||||
JMenuItem jMenuItem1 = new JMenuItem();
|
||||
JMenuItem jMenuItem2 = new JMenuItem();
|
||||
JMenuItem jMenuItem3 = new JMenuItem();
|
||||
void contentTable_mouseClicked(MouseEvent e)
|
||||
{
|
||||
if(e.isPopupTrigger()) {
|
||||
popupPoint.setLocation(e.getX(),e.getY());
|
||||
popupMenu.show(contentTable,e.getX(),e.getY());
|
||||
}
|
||||
}
|
||||
|
||||
void contentTable_mouseReleased(MouseEvent e)
|
||||
{
|
||||
contentTable_mouseClicked(e);
|
||||
}
|
||||
|
||||
void jMenuItem4_actionPerformed(ActionEvent e)
|
||||
{
|
||||
JFileChooser fc = new JFileChooser();
|
||||
if(fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
try {
|
||||
openFile(fc.getSelectedFile());
|
||||
} catch(IOException ioe) {
|
||||
ExceptionDialog.displayException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void closeMenuItem_actionPerformed(ActionEvent e)
|
||||
{
|
||||
if(standaloneMode) {
|
||||
System.exit(0);
|
||||
} else {
|
||||
filename="";
|
||||
file=null;
|
||||
model.setProperties(new Properties());
|
||||
}
|
||||
}
|
||||
|
||||
void newPopupItem_actionPerformed(ActionEvent e)
|
||||
{
|
||||
int y = contentTable.rowAtPoint(popupPoint);
|
||||
|
||||
// create a new unique key based on the current one
|
||||
String key=(String) model.getValueAt(y,0);
|
||||
|
||||
if(key==null) {
|
||||
key="new-key";
|
||||
}
|
||||
|
||||
int uid=1;
|
||||
while(model.containsKey(key+uid)) {
|
||||
uid++;
|
||||
}
|
||||
|
||||
key=key+uid;
|
||||
model.put(key,"");
|
||||
contentTable.clearSelection();
|
||||
}
|
||||
|
||||
void dupPopupItem_actionPerformed(ActionEvent e)
|
||||
{
|
||||
int y = contentTable.rowAtPoint(popupPoint);
|
||||
|
||||
// create a new unique key based on the current one
|
||||
String key=(String) model.getValueAt(y,0);
|
||||
Object val=model.get(key);
|
||||
|
||||
int uid=1;
|
||||
while(model.containsKey(key+uid)) {
|
||||
uid++;
|
||||
}
|
||||
|
||||
key=key+uid;
|
||||
model.put(key,val);
|
||||
contentTable.clearSelection();
|
||||
}
|
||||
|
||||
void delPopupItem_actionPerformed(ActionEvent e)
|
||||
{
|
||||
int y = contentTable.rowAtPoint(popupPoint);
|
||||
model.remove(model.getValueAt(y,0));
|
||||
}
|
||||
|
||||
void jMenuItem6_actionPerformed(ActionEvent e)
|
||||
{
|
||||
JFileChooser fc = new JFileChooser();
|
||||
if(fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||
try {
|
||||
saveFile(fc.getSelectedFile());
|
||||
} catch(IOException ioe) {
|
||||
ExceptionDialog.displayException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void jMenuItem5_actionPerformed(ActionEvent e)
|
||||
{
|
||||
if(filename==null) {
|
||||
jMenuItem6_actionPerformed(e);
|
||||
} else {
|
||||
try {
|
||||
saveFile(file);
|
||||
} catch(IOException ioe) {
|
||||
ExceptionDialog.displayException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void jMenuItem7_actionPerformed(ActionEvent e)
|
||||
{
|
||||
// add check here
|
||||
if(file!=null) {
|
||||
try {
|
||||
openFile(file);
|
||||
} catch(IOException ioe) {
|
||||
ExceptionDialog.displayException(ioe);
|
||||
}
|
||||
} else {
|
||||
jMenuItem4_actionPerformed(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,334 +0,0 @@
|
||||
package uk.org.retep.xml.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* An XMLFactory is used to render XML Tags, accounting for nesting etc
|
||||
*/
|
||||
public class XMLFactory
|
||||
{
|
||||
/**
|
||||
* The lest level (ie, how many tags down the tree we are)
|
||||
*/
|
||||
protected int level;
|
||||
|
||||
/**
|
||||
* The size of our tag name cache
|
||||
*/
|
||||
protected int maxlevel;
|
||||
|
||||
/**
|
||||
* Our tag name cache
|
||||
*/
|
||||
protected String[] names;
|
||||
|
||||
/**
|
||||
* Used to keep track of how formatting is done
|
||||
*/
|
||||
protected boolean hascontent;
|
||||
protected boolean[] contbuf;
|
||||
|
||||
/**
|
||||
* Scratch used by nest()
|
||||
*/
|
||||
private char[] nestbuf;
|
||||
|
||||
/**
|
||||
* The destination Writer
|
||||
*/
|
||||
protected Writer out;
|
||||
|
||||
/**
|
||||
* True if we are still within a tag
|
||||
*/
|
||||
protected boolean inTag;
|
||||
|
||||
/**
|
||||
* True if we have just created a tag so parameters are valid
|
||||
*/
|
||||
protected boolean inArg;
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory with no output Writer
|
||||
*/
|
||||
public XMLFactory()
|
||||
{
|
||||
this(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory with no output Writer
|
||||
* @param m Expected number of leaves in the XML Tree
|
||||
*/
|
||||
public XMLFactory(int m)
|
||||
{
|
||||
// Initialise the names cache
|
||||
level=0;
|
||||
maxlevel=m;
|
||||
names=new String[maxlevel];
|
||||
contbuf=new boolean[maxlevel];
|
||||
|
||||
// This is used by nest()
|
||||
nestbuf=new char[maxlevel];
|
||||
for(int i=0;i<maxlevel;i++)
|
||||
nestbuf[i]=' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
*/
|
||||
public XMLFactory(Writer out)
|
||||
throws IOException
|
||||
{
|
||||
this();
|
||||
setWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
* @param encoding The XML encoding
|
||||
*/
|
||||
public XMLFactory(Writer out,String encoding)
|
||||
throws IOException
|
||||
{
|
||||
this();
|
||||
setWriter(out,encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
* @param m Expected number of leaves in the XML Tree
|
||||
*/
|
||||
public XMLFactory(int m,Writer out)
|
||||
throws IOException
|
||||
{
|
||||
this(m);
|
||||
setWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
* @param encoding The XML encoding
|
||||
* @param m Expected number of leaves in the XML Tree
|
||||
*/
|
||||
public XMLFactory(int m,Writer out,String encoding)
|
||||
throws IOException
|
||||
{
|
||||
this(m);
|
||||
setWriter(out,encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Writer to send the output to. This call will also send the
|
||||
* XML header.
|
||||
*
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void setWriter(Writer out)
|
||||
throws IOException
|
||||
{
|
||||
setWriter(out,"ISO-8859-1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Writer to send the output to. This call will also send the
|
||||
* XML header using the supplied encoding. It is up to the user code to
|
||||
* implement this encoding.
|
||||
*
|
||||
* @param out Writer to send output to
|
||||
* @param encoding Encoding of the XML Output
|
||||
*/
|
||||
public void setWriter(Writer out,String encoding)
|
||||
throws IOException
|
||||
{
|
||||
this.out=out;
|
||||
out.write("<?xml version=\"1.0\" encoding=\"");
|
||||
out.write(encoding);
|
||||
out.write("\" ?>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Writer the XML is being sent out on.
|
||||
*/
|
||||
public Writer getWriter() {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* This starts a tag
|
||||
* @param name The tag name
|
||||
*/
|
||||
public void startTag(String name)
|
||||
throws IOException
|
||||
{
|
||||
if(inTag && inArg) {
|
||||
// Handles two startTag() calls in succession.
|
||||
out.write(">");
|
||||
}
|
||||
|
||||
nest(level);
|
||||
out.write('<');
|
||||
out.write(name);
|
||||
inTag=true;
|
||||
inArg=true;
|
||||
|
||||
// cache the current tag name
|
||||
names[level]=name;
|
||||
|
||||
// cache the current hascontent value & reset
|
||||
contbuf[level]=hascontent;
|
||||
hascontent=false;
|
||||
|
||||
// increase the level and the cache's as necessary
|
||||
level++;
|
||||
if(level>maxlevel) {
|
||||
maxlevel=maxlevel+10;
|
||||
|
||||
String n[]=new String[maxlevel];
|
||||
System.arraycopy(names,0,n,0,level);
|
||||
names=n;
|
||||
|
||||
boolean b[] = new boolean[maxlevel];
|
||||
System.arraycopy(contbuf,0,b,0,level);
|
||||
contbuf=b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This ends a tag
|
||||
*/
|
||||
public void endTag()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(level<1)
|
||||
throw new XMLFactoryException("endTag called above root node");
|
||||
|
||||
level--;
|
||||
|
||||
if(inArg) {
|
||||
// We are still within the opening tag
|
||||
out.write(" />");
|
||||
} else {
|
||||
// We must have written some content or child tags
|
||||
|
||||
// hascontent is true if addContent() was called. If it was never called
|
||||
// to get here some child tags must have been written, so we call nest()
|
||||
// so that the close tag is on it's own line, and everything looks neat
|
||||
// and tidy.
|
||||
if(!hascontent)
|
||||
nest(level);
|
||||
|
||||
out.write("</");
|
||||
out.write(names[level]);
|
||||
out.write('>');
|
||||
}
|
||||
|
||||
inArg=false; // The parent tag must be told it now has content
|
||||
inTag= level>0; // Are we still in a tag?
|
||||
hascontent=contbuf[level]; // retrieve this level's hascontent value
|
||||
}
|
||||
|
||||
/**
|
||||
* This completes the document releasing any open resources.
|
||||
*/
|
||||
public void close()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
while(level>0)
|
||||
endTag();
|
||||
out.write('\n');
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes an attribute to the current tag. If the value is null, then no action is taken.
|
||||
* @param name Name of the parameter
|
||||
* @param value Value of the parameter
|
||||
* @throw XMLFactoryException if out of context
|
||||
*/
|
||||
public void addAttribute(String name,Object value)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(value==null)
|
||||
return;
|
||||
|
||||
if(inArg) {
|
||||
out.write(' ');
|
||||
out.write(name);
|
||||
out.write("=\"");
|
||||
out.write(encode(value.toString()));
|
||||
out.write("\"");
|
||||
} else
|
||||
throw new XMLFactoryException("Cannot add attribute outside of a tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes some content to the current tag. Once this has been called,
|
||||
* you cannot add any more attributes to the current tag. Note, if c is null,
|
||||
* no action is taken.
|
||||
* @param c content to add.
|
||||
*/
|
||||
public void addContent(Object c)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(c==null)
|
||||
return;
|
||||
|
||||
if(inTag) {
|
||||
if(inArg) {
|
||||
// close the open tag
|
||||
out.write('>');
|
||||
inArg=false;
|
||||
}
|
||||
out.write(c.toString());
|
||||
|
||||
// This is used by endTag()
|
||||
hascontent=true;
|
||||
} else
|
||||
throw new XMLFactoryException("Cannot add content outside of a tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a comment to the XML file. This is normally used at the start of
|
||||
* any XML output.
|
||||
* @parm c Comment to include
|
||||
*/
|
||||
public void addComment(Object c)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(inTag)
|
||||
throw new XMLFactoryException("Cannot add comments within a tag");
|
||||
|
||||
out.write("\n<!-- ");
|
||||
out.write(c.toString());
|
||||
out.write(" -->");
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents the output according to the level
|
||||
* @param level The indent level to generate
|
||||
*/
|
||||
protected void nest(int level)
|
||||
throws IOException
|
||||
{
|
||||
out.write('\n');
|
||||
while(level>nestbuf.length) {
|
||||
out.write(nestbuf,0,nestbuf.length);
|
||||
level-=nestbuf.length;
|
||||
}
|
||||
out.write(nestbuf,0,level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the string so that any XML tag chars are translated
|
||||
*/
|
||||
protected String encode(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package uk.org.retep.xml.core;
|
||||
|
||||
/**
|
||||
* Title:
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2001
|
||||
* Company:
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class XMLFactoryException extends Exception
|
||||
{
|
||||
|
||||
public XMLFactoryException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
@ -1,237 +0,0 @@
|
||||
package uk.org.retep.xml.jdbc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
public class XMLDatabase
|
||||
{
|
||||
/**
|
||||
* The XMLFactory being used by this instance
|
||||
*/
|
||||
protected XMLFactory factory;
|
||||
|
||||
/**
|
||||
* Constructor. setXMLFactory() must be called if this method is used.
|
||||
*/
|
||||
public XMLDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param fac XMLFactory to use
|
||||
*/
|
||||
public XMLDatabase(XMLFactory fac)
|
||||
{
|
||||
this();
|
||||
setXMLFactory(fac);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory to use.
|
||||
* @param factory XMLFactory to use
|
||||
*/
|
||||
public void setXMLFactory(XMLFactory factory)
|
||||
{
|
||||
this.factory=factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the XMLFactory being used.
|
||||
*/
|
||||
public XMLFactory getXMLFactory()
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all output to the Writer.
|
||||
* @throw IOException from Writer
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void close()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
factory.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the schema of a table.
|
||||
* @param con Connection to database
|
||||
* @param table Table name
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void writeTable(Connection con,String table)
|
||||
throws IOException,SQLException,XMLFactoryException
|
||||
{
|
||||
writeTable(con.getMetaData(),table);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the schema of a table.
|
||||
* @param db DatabaseMetaData for the database
|
||||
* @param table Table name
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void writeTable(DatabaseMetaData db,String table)
|
||||
throws IOException,SQLException,XMLFactoryException
|
||||
{
|
||||
writeTable(db,null,null,table);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the schema of a table.
|
||||
* @param db DatabaseMetaData for the database
|
||||
* @param table Table name
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void writeTable(DatabaseMetaData db,String cat,String schem,String table)
|
||||
throws IOException,SQLException,XMLFactoryException
|
||||
{
|
||||
ResultSet trs;
|
||||
|
||||
factory.startTag("TABLE");
|
||||
factory.addAttribute("NAME",table);
|
||||
// fetch the remarks for this table (if any)
|
||||
trs = db.getTables(null,null,table,null);
|
||||
if(trs!=null) {
|
||||
if(trs.next()) {
|
||||
String rem = trs.getString(5);
|
||||
if(rem!=null)
|
||||
factory.addContent(rem);
|
||||
}
|
||||
trs.close();
|
||||
}
|
||||
|
||||
trs = db.getColumns(null,null,table,"%");
|
||||
if(trs!=null) {
|
||||
while(trs.next()) {
|
||||
factory.startTag("COLUMN");
|
||||
factory.addAttribute("NAME",trs.getString(4));
|
||||
factory.addAttribute("TYPE",trs.getString(6));
|
||||
factory.addAttribute("COLUMN_SIZE",trs.getString(7));
|
||||
factory.addAttribute("DECIMAL_DIGITS",trs.getString(9));
|
||||
factory.addAttribute("NUM_PREC_RADIX",trs.getString(10));
|
||||
factory.addAttribute("NULLABLE",trs.getString(11));
|
||||
factory.addAttribute("COLUMN_DEF",trs.getString(13));
|
||||
factory.addAttribute("CHAR_OCTET_LENGTH",trs.getString(16));
|
||||
factory.addAttribute("ORDINAL_POSITION",trs.getString(17));
|
||||
factory.addAttribute("IS_NULLABLE",trs.getString(18));
|
||||
factory.addAttribute("TABLE_CAT",trs.getString(1));
|
||||
factory.addAttribute("TABLE_SCHEM",trs.getString(2));
|
||||
String rem = trs.getString(12);
|
||||
if(rem!=null)
|
||||
factory.addContent(rem);
|
||||
factory.endTag();
|
||||
}
|
||||
trs.close();
|
||||
}
|
||||
|
||||
factory.endTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db Connection to database
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(Connection db,String table)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db.getMetaData(),null,null,table);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(DatabaseMetaData db,String table)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db,null,null,table);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param cat Catalog (may be null)
|
||||
* @param schem Schema (may be null)
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(Connection db)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db.getMetaData(),null,null,"%");
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param cat Catalog (may be null)
|
||||
* @param schem Schema (may be null)
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(DatabaseMetaData db)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db,null,null,"%");
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param cat Catalog (may be null)
|
||||
* @param schem Schema (may be null)
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(DatabaseMetaData db,String cat,String schem,String table)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
ResultSet rs = db.getTables(cat,schem,table,null);
|
||||
if(rs!=null) {
|
||||
factory.startTag("DATABASE");
|
||||
factory.addAttribute("PRODUCT",db.getDatabaseProductName());
|
||||
factory.addAttribute("VERSION",db.getDatabaseProductVersion());
|
||||
|
||||
while(rs.next()) {
|
||||
writeTable(db,rs.getString(1),rs.getString(2),rs.getString(3));
|
||||
}
|
||||
|
||||
factory.endTag();
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,505 +0,0 @@
|
||||
package uk.org.retep.xml.jdbc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
/**
|
||||
* This class takes a java.sql.ResultSet object and generates an XML stream
|
||||
* based on it's contents.
|
||||
*
|
||||
* $Id: XMLResultSet.java,v 1.1 2001/01/23 10:22:20 peter Exp $
|
||||
*/
|
||||
public class XMLResultSet
|
||||
{
|
||||
/**
|
||||
* The current ResultSet to process
|
||||
*/
|
||||
protected ResultSet rs;
|
||||
|
||||
/**
|
||||
* The XMLFactory being used by this instance
|
||||
*/
|
||||
protected XMLFactory factory;
|
||||
|
||||
/**
|
||||
* The default properties used when none are supplied by the user
|
||||
*/
|
||||
protected static Properties defaults;
|
||||
|
||||
/**
|
||||
* The default property name for defining the tag name used to define a
|
||||
* ResultSet
|
||||
*/
|
||||
public static String RESULTSET_NAME = "resultset.name";
|
||||
|
||||
/**
|
||||
* The default tag name for a resultset
|
||||
*/
|
||||
public static String DEFAULT_RESULTSET_NAME = "RESULTSET";
|
||||
|
||||
/**
|
||||
* The default property name for defining the tag name used to define a row
|
||||
*/
|
||||
public static String ROW_NAME = "row.name";
|
||||
|
||||
/**
|
||||
* The default tag name for a row
|
||||
*/
|
||||
public static String DEFAULT_ROW_NAME = "RECORD";
|
||||
|
||||
/**
|
||||
* The default tag name for a resultset
|
||||
*/
|
||||
public static String COLNAME = ".name";
|
||||
|
||||
/**
|
||||
* The value of the property (named as its related column) used to define
|
||||
* how the column is generated. This indicates that the columns data is
|
||||
* enclosed within a pair of tags, ie: <id>1234</id>
|
||||
*/
|
||||
public static String CONTENT = "content";
|
||||
|
||||
/**
|
||||
* The value of the property (named as its related column) used to define
|
||||
* how the column is generated. This indicates that the columns data is
|
||||
* an attribute in the columns tag. ie: <id value="1234" />
|
||||
*/
|
||||
public static String ATTRIBUTE = "attribute";
|
||||
|
||||
/**
|
||||
* This is the default attribute name used when the ATTRIBUTE option is set.
|
||||
*/
|
||||
public static String DEFAULT_ATTRIBUTE = "VALUE";
|
||||
|
||||
/**
|
||||
* The value of the property (named as its related column) used to define
|
||||
* how the column is generated. This indicates that the columns data is
|
||||
* an attribute in the parent's tag. ie: <row id="1234" />
|
||||
*/
|
||||
public static String ROW_ATTRIBUTE = "row";
|
||||
|
||||
/**
|
||||
* This property name marks the begining row number within the ResultSet to
|
||||
* start processing.
|
||||
*/
|
||||
public static String FIRST_ROW = "row.first";
|
||||
|
||||
/**
|
||||
* This property name marks the last row number within the ResultSet to
|
||||
* end processing.
|
||||
*/
|
||||
public static String LAST_ROW = "row.last";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public XMLResultSet()
|
||||
{
|
||||
factory = new XMLFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public XMLResultSet(ResultSet rs)
|
||||
{
|
||||
this();
|
||||
setResultSet(rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ResultSet to use
|
||||
* @param rs ResultSet
|
||||
*/
|
||||
public void setResultSet(ResultSet rs)
|
||||
{
|
||||
this.rs=rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current ResultSet
|
||||
*
|
||||
*/
|
||||
public ResultSet getResultSet()
|
||||
{
|
||||
return rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Writer to send all output to
|
||||
* @param out Writer
|
||||
* @throws IOException from XMLFactory
|
||||
* @see XMLFactory.setWriter
|
||||
*/
|
||||
public void setWriter(Writer out)
|
||||
throws IOException
|
||||
{
|
||||
factory.setWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Writer output is going to
|
||||
*/
|
||||
public Writer getWriter()
|
||||
{
|
||||
return factory.getWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XMLFactory being used
|
||||
*/
|
||||
public XMLFactory getXMLFactory()
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all output to the Writer
|
||||
* @throw IOException from Writer
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void close()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
factory.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default properties used by translate() and buildDTD()
|
||||
* @return Properties default property settings
|
||||
*/
|
||||
public static Properties getDefaultProperties()
|
||||
{
|
||||
if(defaults==null) {
|
||||
defaults=new Properties();
|
||||
defaults.setProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME);
|
||||
defaults.setProperty(ROW_NAME,DEFAULT_ROW_NAME);
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the supplied
|
||||
* Writer.
|
||||
* @param rs ResultSet to convert
|
||||
* @param p Properties for the conversion
|
||||
* @param out Writer to send output to (replaces existing one)
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs,Properties p,Writer out)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
factory.setWriter(out);
|
||||
translate(rs,p);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the supplied
|
||||
* Writer using a default tag struct
|
||||
* @param rs ResultSet to convert
|
||||
* @param out Writer to send output to (replaces existing one)
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs,Writer out)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
factory.setWriter(out);
|
||||
translate(rs,(Properties)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the current
|
||||
* output stream using a default tag structure.
|
||||
* @param rs ResultSet to convert
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
translate(rs,(Properties)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the current
|
||||
* output stream.
|
||||
* @param rs ResultSet to convert
|
||||
* @param p Properties for the conversion
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs,Properties p)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
// if we don't pass any properties, create an empty one and cache it if
|
||||
// further calls do the same
|
||||
if(p==null) {
|
||||
p=getDefaultProperties();
|
||||
}
|
||||
|
||||
// Fetch some common values
|
||||
String setName = p.getProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME);
|
||||
String rowName = p.getProperty(ROW_NAME,DEFAULT_ROW_NAME);
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int numcols = rsmd.getColumnCount();
|
||||
|
||||
String colname[] = new String[numcols]; // field name cache
|
||||
int coltype[] = new int[numcols]; // true to use attribute false content
|
||||
String colattr[] = new String[numcols]; // Attribute name
|
||||
|
||||
// These deal with when an attribute is to go into the row's tag parameters
|
||||
int parentFields[] = getRowAttributes(numcols,colname,colattr,coltype,rsmd,p); // used to cache the id's
|
||||
int numParents= parentFields==null ? 0 : parentFields.length; // number of parent fields
|
||||
boolean haveParent= numParents>0; // true only if we need to us these
|
||||
|
||||
// This allows some limiting of the output result
|
||||
int firstRow = Integer.parseInt(p.getProperty(FIRST_ROW,"0"));
|
||||
int lastRow = Integer.parseInt(p.getProperty(LAST_ROW,"0"));
|
||||
int curRow=0;
|
||||
|
||||
// Start the result set's tag
|
||||
factory.startTag(setName);
|
||||
|
||||
while(rs.next()) {
|
||||
if(firstRow<=curRow && (lastRow==0 || curRow<lastRow)) {
|
||||
factory.startTag(rowName);
|
||||
|
||||
if(haveParent) {
|
||||
// Add any ROW_ATTRIBUTE entries
|
||||
for(int i=0;i<numParents;i++)
|
||||
factory.addAttribute(colname[i],rs.getString(i+1));
|
||||
}
|
||||
|
||||
// Process any CONTENT & ATTRIBUTE entries.
|
||||
// This skips if all the entries are ROW_ATTRIBUTE's
|
||||
if(numParents < numcols) {
|
||||
for(int i=1;i<=numcols;i++) {
|
||||
// Now do we write the value as an argument or as PCDATA?
|
||||
switch(coltype[i-1]) {
|
||||
case 1:
|
||||
factory.startTag(colname[i-1]);
|
||||
factory.addAttribute(colattr[i-1],rs.getString(i));
|
||||
factory.endTag();
|
||||
break;
|
||||
|
||||
case 0:
|
||||
factory.startTag(colname[i-1]);
|
||||
factory.addContent(rs.getString(i));
|
||||
factory.endTag();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown type. This should only be called for ROW_ATTRIBUTE which
|
||||
// is handled before this loop.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End the row
|
||||
factory.endTag();
|
||||
}
|
||||
curRow++;
|
||||
|
||||
} // check for firstRow <= curRow <= lastRow
|
||||
|
||||
// Close the result set's tag
|
||||
factory.endTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current writer
|
||||
* @param rs ResultSet
|
||||
*/
|
||||
public void buildDTD(ResultSet rs)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
buildDTD(rs,null,getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current writer
|
||||
* @param rs ResultSet
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void buildDTD(ResultSet rs,Writer out)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
buildDTD(rs,null,out);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current writer
|
||||
* @param rs ResultSet
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void buildDTD(ResultSet rs,Properties p)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
buildDTD(rs,p,getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current a.
|
||||
*
|
||||
* <p>ToDo:<ol>
|
||||
* <li>Add ability to have NULLABLE columns appear as optional (ie instead of
|
||||
* x, have x? (DTD for Optional). Can't use + or * as that indicates more than
|
||||
* 1 instance).
|
||||
* </ol>
|
||||
*
|
||||
* @param rs ResultSet
|
||||
* @param p Properties defining tag types (as translate)
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void buildDTD(ResultSet rs,Properties p,Writer out)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
// if we don't pass any properties, create an empty one and cache it if
|
||||
// further calls do the same
|
||||
if(p==null) {
|
||||
p=getDefaultProperties();
|
||||
}
|
||||
|
||||
// Fetch some common values
|
||||
String setName = p.getProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME);
|
||||
String rowName = p.getProperty(ROW_NAME,DEFAULT_ROW_NAME);
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int numcols = rsmd.getColumnCount();
|
||||
|
||||
String colname[] = new String[numcols]; // field name cache
|
||||
int coltype[] = new int[numcols]; // true to use attribute false content
|
||||
String colattr[] = new String[numcols]; // Attribute name
|
||||
|
||||
// These deal with when an attribute is to go into the row's tag parameters
|
||||
int parentFields[] = getRowAttributes(numcols,colname,colattr,coltype,rsmd,p); // used to cache the id's
|
||||
int numParents= parentFields==null ? 0 : parentFields.length; // number of parent fields
|
||||
boolean haveParent= numParents>0; // true only if we need to us these
|
||||
|
||||
// Now the dtd defining the ResultSet
|
||||
out.write("<!ELEMENT ");
|
||||
out.write(setName);
|
||||
out.write(" (");
|
||||
out.write(rowName);
|
||||
out.write("*)>\n");
|
||||
|
||||
// Now the dtd defining each row
|
||||
out.write("<!ELEMENT ");
|
||||
out.write(rowName);
|
||||
out.write(" (");
|
||||
boolean s=false;
|
||||
for(int i=0;i<numcols;i++) {
|
||||
if(coltype[i]!=2) { // not ROW_ATTRIBUTE
|
||||
if(s)
|
||||
out.write(",");
|
||||
out.write(colname[i]);
|
||||
s=true;
|
||||
}
|
||||
}
|
||||
out.write(")>\n");
|
||||
|
||||
// Now handle any ROW_ATTRIBUTE's
|
||||
if(haveParent) {
|
||||
out.write("<!ATTLIST ");
|
||||
out.write(rowName);
|
||||
for(int i=0;i<numParents;i++) {
|
||||
out.write("\n ");
|
||||
out.write(colname[parentFields[i]]);
|
||||
out.write(" CDATA #IMPLIED");
|
||||
}
|
||||
out.write("\n>\n");
|
||||
}
|
||||
|
||||
// Now add any CONTENT & ATTRIBUTE fields
|
||||
for(int i=0;i<numcols;i++) {
|
||||
if(coltype[i]!=2) {
|
||||
out.write("<!ELEMENT ");
|
||||
out.write(colname[i]);
|
||||
|
||||
// CONTENT
|
||||
if(coltype[i]==0) {
|
||||
out.write(" (#PCDATA)");
|
||||
} else {
|
||||
out.write(" EMPTY");
|
||||
}
|
||||
|
||||
out.write(">\n");
|
||||
|
||||
// ATTRIBUTE
|
||||
if(coltype[i]==1) {
|
||||
out.write("<!ATTLIST ");
|
||||
out.write(colname[i]);
|
||||
out.write("\n ");
|
||||
out.write(colattr[i]);
|
||||
out.write(" CDATA #IMPLIED\n>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method used by the core translate and buildDTD methods.
|
||||
* @param numcols Number of columns in ResultSet
|
||||
* @param colname Array of column names
|
||||
* @param colattr Array of column attribute names
|
||||
* @param coltype Array of column types
|
||||
* @param rsmd ResultSetMetaData for ResultSet
|
||||
* @param p Properties being used
|
||||
* @return array containing field numbers which should appear as attributes
|
||||
* within the rows tag.
|
||||
* @throws SQLException from JDBC
|
||||
*/
|
||||
private int[] getRowAttributes(int numcols,
|
||||
String colname[],String colattr[],
|
||||
int coltype[],
|
||||
ResultSetMetaData rsmd,Properties p)
|
||||
throws SQLException
|
||||
{
|
||||
int pf[] = null;
|
||||
int nf = 0;
|
||||
|
||||
// Now we put a columns value as an attribute if the property
|
||||
// fieldname=attribute (ie myname=attribute)
|
||||
// and if the fieldname.name property exists, use it as the attribute name
|
||||
for(int i=0;i<numcols;i++) {
|
||||
colname[i] = rsmd.getColumnName(i+1);
|
||||
colattr[i] = p.getProperty(colname[i]+COLNAME,DEFAULT_ATTRIBUTE);
|
||||
if(p.getProperty(colname[i],CONTENT).equals(ROW_ATTRIBUTE)) {
|
||||
// Ok, ROW_ATTRIBUTE's need to be cached, so add them in here
|
||||
coltype[i]=2;
|
||||
if(pf==null) {
|
||||
pf = new int[numcols]; // Max possible number of entries
|
||||
}
|
||||
pf[nf++] = i;
|
||||
} else {
|
||||
// Normal CONTENT or ATTRIBUTE entry
|
||||
coltype[i] = p.getProperty(colname[i],CONTENT).equals(ATTRIBUTE) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Form an array exactly nf elements long
|
||||
if(nf>0) {
|
||||
int r[] = new int[nf];
|
||||
System.arraycopy(pf,0,r,0,nf);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Return null if no tags are to appear as attributes to the row's tag
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,201 +0,0 @@
|
||||
package uk.org.retep.xml.parser;
|
||||
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import org.xml.sax.AttributeList;
|
||||
import org.xml.sax.HandlerBase;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.Parser;
|
||||
import org.xml.sax.SAXException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
/**
|
||||
* This class implements the base of the XML handler. You create an instance,
|
||||
* register classes (who implement TagListener) that are interested in the tags
|
||||
* and pass it to SAX.
|
||||
*
|
||||
* <p>Or you create an instance, register the TagListeners and use the getParser()
|
||||
* method to create a Parser. Then start parsing by calling it's parse() method.
|
||||
*/
|
||||
|
||||
public class TagHandler extends HandlerBase {
|
||||
|
||||
/**
|
||||
* The current active level
|
||||
*/
|
||||
private int level;
|
||||
|
||||
/**
|
||||
* cache used to handle nesting of tags
|
||||
*/
|
||||
private List contents;
|
||||
|
||||
/**
|
||||
* cache used to handle nesting of tags
|
||||
*/
|
||||
private List tags;
|
||||
|
||||
/**
|
||||
* cache used to handle nesting of tags
|
||||
*/
|
||||
private List args;
|
||||
|
||||
// Current active content writer
|
||||
private CharArrayWriter content;
|
||||
|
||||
// List of TagListener's who want to be fed data
|
||||
private HashSet tagListeners;
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
public TagHandler() {
|
||||
level=0;
|
||||
contents = new ArrayList();
|
||||
tags = new ArrayList();
|
||||
args = new ArrayList();
|
||||
tagListeners = new HashSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by SAX when a tag is begun. This simply creates a new level in the
|
||||
* cache and stores the parameters and tag name in there.
|
||||
*/
|
||||
public void startElement(String p0, AttributeList p1) throws SAXException {
|
||||
|
||||
// Now move up and fetch a CharArrayWriter from the cache
|
||||
// creating if this is the first time at this level
|
||||
if(contents.size()<=level) {
|
||||
contents.add(new CharArrayWriter());
|
||||
tags.add(p0);
|
||||
args.add(new HashMap());
|
||||
}
|
||||
|
||||
content=(CharArrayWriter) contents.get(level);
|
||||
content.reset();
|
||||
|
||||
// Also cache the tag's text and argument list
|
||||
tags.set(level,p0);
|
||||
|
||||
HashMap h = (HashMap) args.get(level);
|
||||
h.clear();
|
||||
for(int i=p1.getLength()-1;i>-1;i--) {
|
||||
h.put(p1.getName(i),p1.getValue(i));
|
||||
}
|
||||
|
||||
// Now notify any TagListeners
|
||||
Iterator it = tagListeners.iterator();
|
||||
while(it.hasNext())
|
||||
( (TagListener) it.next() ).tagStart(level,p0,h);
|
||||
|
||||
// Now move up a level
|
||||
level++;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called by SAX at the end of a tag. This calls handleTag() and then
|
||||
* raises the level, so that the previous parent tag may continue.
|
||||
*/
|
||||
public void endElement(String p0) throws SAXException {
|
||||
// move up a level retrieving that level's current content
|
||||
// Now this exception should never occur as the underlying parser should
|
||||
// actually trap it.
|
||||
if(level<1)
|
||||
throw new SAXException("Already at top level?");
|
||||
level--;
|
||||
|
||||
// Now notify any TagListeners
|
||||
Iterator it = tagListeners.iterator();
|
||||
while(it.hasNext())
|
||||
( (TagListener) it.next() ).tagContent(content);
|
||||
|
||||
// allows large content to be released early
|
||||
content.reset();
|
||||
|
||||
// Now reset content to the previous level
|
||||
content=(CharArrayWriter) contents.get(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by SAX so that content between the start and end tags are captured.
|
||||
*/
|
||||
public void characters(char[] p0, int p1, int p2) throws SAXException {
|
||||
content.write(p0,p1,p2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a TagListener so that it is notified of tags as they are processed.
|
||||
* @param handler TagListener to add
|
||||
*/
|
||||
public void addTagListener(TagListener h) {
|
||||
tagListeners.add(h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the TagListener so it no longer receives notifications of tags
|
||||
*/
|
||||
public void removeTagListener(TagListener h) {
|
||||
tagListeners.remove(h);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a org.xml.sax.Parser object that will parse the
|
||||
* contents of a URI.
|
||||
*
|
||||
* <p>Normally you would call this method, then call the parse(uri) method of
|
||||
* the returned object.
|
||||
* @return org.xml.sax.Parser object
|
||||
*/
|
||||
public Parser getParser()
|
||||
throws SAXException
|
||||
{
|
||||
try {
|
||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
|
||||
String validation = System.getProperty ("javax.xml.parsers.validation", "false");
|
||||
if (validation.equalsIgnoreCase("true"))
|
||||
spf.setValidating (true);
|
||||
|
||||
SAXParser sp = spf.newSAXParser();
|
||||
Parser parser = sp.getParser ();
|
||||
|
||||
parser.setDocumentHandler(this);
|
||||
|
||||
return(parser);
|
||||
} catch(ParserConfigurationException pce) {
|
||||
throw new SAXException(pce.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will parse the specified URI.
|
||||
*
|
||||
* <p>Internally this is the same as getParser().parse(uri);
|
||||
* @param uri The URI to parse
|
||||
*/
|
||||
public void parse(String uri)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
getParser().parse(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will parse the specified InputSource.
|
||||
*
|
||||
* <p>Internally this is the same as getParser().parse(is);
|
||||
* @param is The InputSource to parse
|
||||
*/
|
||||
public void parse(InputSource is)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
getParser().parse(is);
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package uk.org.retep.xml.parser;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.io.CharArrayWriter;
|
||||
|
||||
/**
|
||||
* This interface defines the methods a class needs to implement if it wants the
|
||||
* xml parser to notify it of any xml tags.
|
||||
*/
|
||||
|
||||
public interface TagListener {
|
||||
/**
|
||||
* This is called when a tag has just been started.
|
||||
* <p><b>NB:</b> args is volatile, so if you use it beyond the lifetime of
|
||||
* this call, then you must make a copy of the HashMap (and not use simply
|
||||
* store this HashMap).
|
||||
* @param level The number of tags above this
|
||||
* @param tag The tag name
|
||||
* @param args A HashMap of any arguments
|
||||
*/
|
||||
public void tagStart(int level,String tag,HashMap args);
|
||||
/**
|
||||
* This method is called by ContHandler to process a tag once it has been
|
||||
* fully processed.
|
||||
* <p><b>NB:</b> content is volatile, so you must copy its contents if you use
|
||||
* it beyond the lifetime of this call.
|
||||
* @param content CharArrayWriter containing the content of the tag.
|
||||
*/
|
||||
public void tagContent(CharArrayWriter content);
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
package uk.org.retep.xml.test;
|
||||
|
||||
import java.lang.Exception;
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
import uk.org.retep.xml.jdbc.XMLDatabase;
|
||||
import uk.org.retep.xml.jdbc.XMLResultSet;
|
||||
|
||||
/**
|
||||
* This "test" class is a fully functional tool in its own right. It utilises
|
||||
* the xml classes to query and export to XML, or to dump database structures
|
||||
* into XML.
|
||||
*/
|
||||
|
||||
public class XMLExport
|
||||
{
|
||||
/**
|
||||
* The current Database Connection
|
||||
*/
|
||||
protected Connection conn;
|
||||
protected Statement stat;
|
||||
protected String drvr,url,table;
|
||||
|
||||
protected XMLResultSet xrs;
|
||||
protected XMLDatabase xdb;
|
||||
protected Properties prop;
|
||||
protected boolean outXML;
|
||||
protected boolean outDTD;
|
||||
protected boolean outTAB;
|
||||
protected int maxRows=0;
|
||||
|
||||
public XMLExport(String[] args)
|
||||
throws IOException,SQLException,XMLFactoryException,ClassNotFoundException
|
||||
{
|
||||
xrs = new XMLResultSet();
|
||||
xrs.setWriter(new OutputStreamWriter(System.out));
|
||||
//Properties p = new Properties(xrs.getDefaultProperties());
|
||||
prop = (Properties) xrs.getDefaultProperties().clone();
|
||||
|
||||
xdb = new XMLDatabase(xrs.getXMLFactory());
|
||||
|
||||
for(int i=0;i<args.length;i++) {
|
||||
String arg=args[i];
|
||||
if(arg.startsWith("-D")) {
|
||||
// Load JDBC Driver
|
||||
drvr=arg.substring(2);
|
||||
Class.forName(drvr);
|
||||
System.out.println("Now using JDBC Driver: "+drvr);
|
||||
} else if(arg.startsWith("-J")) {
|
||||
// Open a JDBC Connection (closing the existing one, if any)
|
||||
close();
|
||||
url = arg.substring(2);
|
||||
conn = DriverManager.getConnection(url);
|
||||
System.out.println("Opened "+url);
|
||||
stat=null;
|
||||
} else if(arg.startsWith("-M")) {
|
||||
// Set the maximum number of rows to process (0=no limit)
|
||||
maxRows=Integer.parseInt(arg.substring(2));
|
||||
if(maxRows<0)
|
||||
maxRows=0;
|
||||
prop.setProperty(XMLResultSet.FIRST_ROW,"0");
|
||||
prop.setProperty(XMLResultSet.LAST_ROW,Integer.toString(maxRows));
|
||||
} else if(arg.startsWith("-O")) {
|
||||
// Set the output file for XML & DTD
|
||||
xrs.setWriter(new FileWriter(arg.substring(2)));
|
||||
System.out.println("XML/DTD Output now going to "+arg.substring(2));
|
||||
} else if(arg.startsWith("-P")) {
|
||||
// Set a parameter for XML & DTD
|
||||
int p = arg.indexOf('=');
|
||||
prop.setProperty(arg.substring(2,p),arg.substring(p+1));
|
||||
} else if(arg.startsWith("-S")) {
|
||||
// -Stable generate schema of just table
|
||||
// -S generate schema of entire database
|
||||
if(arg.length()>2) {
|
||||
String table=arg.substring(2);
|
||||
System.out.println("Generating XML Schema of table "+table);
|
||||
xdb.writeTable(conn,table);
|
||||
xdb.close();
|
||||
} else {
|
||||
System.out.println("Generating XML Schema of database");
|
||||
xdb.writeDatabase(conn);
|
||||
xdb.close();
|
||||
}
|
||||
} else if(arg.equals("-V")) {
|
||||
// Select table output
|
||||
outXML=outDTD=false;
|
||||
} else if(arg.equals("-X")) {
|
||||
// Select XML output
|
||||
outXML=true;
|
||||
outDTD=outTAB=false;
|
||||
} else if(arg.equals("-Y")) {
|
||||
// Select DTD output
|
||||
outXML=outTAB=false;
|
||||
outDTD=true;
|
||||
} else if(arg.startsWith("-")) {
|
||||
System.err.println("Unknown argument: "+arg);
|
||||
System.exit(1);
|
||||
} else {
|
||||
// Ok, anything not starting with "-" are queries
|
||||
if(stat==null)
|
||||
stat=conn.createStatement();
|
||||
|
||||
System.out.println("Executing "+arg);
|
||||
ResultSet rs = stat.executeQuery(arg);
|
||||
if(rs!=null) {
|
||||
if(outXML) {
|
||||
xrs.translate(rs,prop);
|
||||
xrs.close();
|
||||
} else if(outDTD) {
|
||||
// Output the DTD
|
||||
xrs.buildDTD(rs,prop);
|
||||
xrs.close();
|
||||
} else {
|
||||
// Normal resultset output
|
||||
int rc=0;
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int nc = rsmd.getColumnCount();
|
||||
boolean us=false;
|
||||
for(int c=0;c<nc;c++) {
|
||||
if(us)
|
||||
System.out.print("\t");
|
||||
System.out.print(rsmd.getColumnName(c+1));
|
||||
us=true;
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
while(rs.next() && (maxRows==0 || rc<maxRows)) {
|
||||
us=false;
|
||||
for(int c=0;c<nc;c++) {
|
||||
if(us)
|
||||
System.out.print("\t");
|
||||
System.out.print(rs.getString(c+1));
|
||||
us=true;
|
||||
}
|
||||
System.out.println();
|
||||
rc++;
|
||||
}
|
||||
|
||||
System.out.println("Returned "+rc+" rows.");
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
public void close() throws SQLException
|
||||
{
|
||||
if(conn!=null) {
|
||||
conn.close();
|
||||
System.out.println("Closed "+url);
|
||||
conn=null;
|
||||
stat=null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if(args.length==0) {
|
||||
System.out.println("Useage: java uk.org.retep.xml.test.XMLExport [args ...]\nwhere args are:\n"+
|
||||
"-Dclass.name JDBC Driver Class\n"+
|
||||
"-Jurl JDBC URL\n"+
|
||||
"-Mmax Maximum number of rows to process\n"+
|
||||
"-Ofilename Send all XML or DTD output to file\n"+
|
||||
"-Pkey=value Property passed on to XMLResultSet\n"+
|
||||
"-S[table] Write XML description of table. Whole DB if table left out.\n"+
|
||||
"-V Default: Write result to System.out\n"+
|
||||
"-X Write result in XML to System.out\n"+
|
||||
"-Y Write DTD describing result to System.out\n"+
|
||||
"\nAny other argument not starting with - is treated as an SQL Query\n"+
|
||||
"\nFor example:\n"+
|
||||
"To dump the table structure of a database into db.xml, use\n $ java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver -Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -Odb.xml -S\n"+
|
||||
"To dump the structure of a single table PRODUCTS and write into products.xml, use\n $ clear;java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver-Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -Oproducts.xml -SPRODUCT\n"+
|
||||
"To query a table and write the results into standard out as XML, use\n $ java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver -Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -M5 -PSKU=row -PIMAGE=attribute -X \"select sku,image,template from product\"\n"+
|
||||
"To query a table and write a DTD describing the ResultSet, use\n $ java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver -Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -M5 -PSKU=row -PIMAGE=attribute -Y \"select sku,image,template from product\"\n"
|
||||
);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
XMLExport XMLExport1 = new XMLExport(args);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user