diff options
| author | guest <guest@f059d3a0-6783-47b7-97ff-1fe0bbf25129> | 2008-09-23 21:29:27 +0000 |
|---|---|---|
| committer | guest <guest@f059d3a0-6783-47b7-97ff-1fe0bbf25129> | 2008-09-23 21:29:27 +0000 |
| commit | d6fa96b4cd67cf4fa18b5b9b6739f9bc2494a9f4 (patch) | |
| tree | 00aa9a27acb6b4c8d9868795a5295e9231f1eb20 | |
initial import
git-svn-id: http://manut.eu/svn/yalp/trunk@1 f059d3a0-6783-47b7-97ff-1fe0bbf25129
85 files changed, 16260 insertions, 0 deletions
diff --git a/ClientConfiguration.xml b/ClientConfiguration.xml new file mode 100644 index 0000000..7eff5e7 --- /dev/null +++ b/ClientConfiguration.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<java version="1.6.0_07" class="java.beans.XMLDecoder"> + <string>127.0.0.1</string> + <int>5002</int> + <int>5001</int> + <string>"/usr/bin/vlc"</string> +</java> diff --git a/ServerSettings.xml b/ServerSettings.xml new file mode 100644 index 0000000..fd0f623 --- /dev/null +++ b/ServerSettings.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<java version="1.6.0_07" class="java.beans.XMLDecoder"> + <string>jdbc:postgresql://localhost:5432/yalp</string> + <string>huhu</string> + <string>yalp</string> +</java> @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpPGSqlAuth.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..149a99f --- /dev/null +++ b/build.xml @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="yalp" default="all" basedir=".">
+ <property name="srcInterfaces" value="src/YalpInterfaces"/>
+
+ <property name="srcInputs" value="src/YalpInputs"/>
+ <property name="srcOutputs" value="src/YalpOutputs"/>
+ <property name="srcAuth" value="src/YalpAuth"/>
+ <property name="srcServer" value="src/YalpServer"/>
+ <property name="srcClients" value="src/YalpClients"/>
+
+ <property name="srcVlcTelnetOutput" value="${srcOutputs}/YalpVlcTelnetOutput"/>
+ <property name="srcPGSqlInput" value="${srcInputs}/YalpPGSqlInput"/>
+ <property name="srcPGSqlAuth" value="${srcAuth}/YalpPGSqlAuth"/>
+
+ <property name="srcSwtClient" value="${srcClients}/SwtClient"/>
+ <property name="srcSwtClientGUI" value="${srcSwtClient}/GUI"/>
+
+ <property name="src" value="src/"/>
+ <property name="doc" value="doc/"/>
+ <property name="sqldoc" value="${doc}/sql"/>
+ <property name="javadoc" value="${doc}/java"/>
+ <property name="build" value="build/"/>
+ <property name="lib" value="lib/"/>
+
+ <property name="serverLibs" value="lib/log4j-1.2.15.jar"/>
+ <property name="vlctelnetLibs" value="lib/commons-net-1.4.1.jar"/>
+ <property name="swtLibs" value="lib/swt.jar"/>
+ <property name="dbLibs" value="lib/postgresql-8.1-404.jdbc3.jar"/>
+
+ <property name="idlj" value="../idlj.sh"/>
+ <property name="psqldoc" value="./postgresql_autodoc/postgresql_autodoc"/>
+
+ <path id="project.class.path">
+ <pathelement location="{lib}"/>
+ <pathelement path="${java.class.path}"/>
+ <pathelement path="${additional.path}"/>
+ </path>
+
+ <target name="all" depends="vlctelnetoutput, pgsqlinput, pgsqlauth, server, swtclient" description="builds server and client">
+ <echo>Doing all</echo>
+ </target>
+
+ <target name="interfaces" description="Create stubs/skeletons from idl">
+ <exec dir="${src}" executable="${idlj}">
+ <arg value="yalp.idl"/>
+ </exec>
+ <javac srcdir="${srcInterfaces}" destdir="${build}"/>
+ </target>
+
+ <target name ="server" depends="interfaces" description="builds the Server">
+ <javac debug="true" srcdir="${srcServer}" destdir="${build}"/>
+ <jar destfile="yalpServer.jar" basedir="${build}">
+ <path id="project.class.path">
+ <pathelement location="${lib}"/>
+ <pathelement path="${java.class.path}"/>
+ <pathelement path="${additional.path}"/>
+ </path>
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Main-Class" value="YalpServer.YalpServer"/>
+ <attribute name="Class-Path" value="${serverLibs}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name ="outputs" description="builds output base files">
+ <javac debug="true" srcdir="${srcOutputs}" destdir="${build}"/>
+ </target>
+
+ <target name ="vlctelnetoutput" depends="interfaces, outputs" description="builds the vlctelnetoutput">
+ <javac debug="true" srcdir="${srcVlcTelnetOutput}" destdir="${build}"/>
+ <jar destfile="yalpVlcTelnetOutput.jar" basedir="${build}">
+ <path id="project.class.path">
+ <pathelement location="${lib}"/>
+ <pathelement path="${java.class.path}"/>
+ <pathelement path="${additional.path}"/>
+ </path>
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Main-Class" value="YalpOutputs.YalpVlcTelnetOutput.YalpVlcTelnetOutput"/>
+ <attribute name="Class-Path" value="${outputLibs}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name ="inputs" description="builds input base files">
+ <javac debug="true" srcdir="${srcInputs}" destdir="${build}"/>
+ </target>
+
+ <target name ="pgsqlinput" depends="interfaces, inputs" description="builds the pgsql input plugin">
+ <javac debug="true" srcdir="${srcPGSqlInput}" destdir="${build}"/>
+ <jar destfile="yalpPGSqlInput.jar" basedir="${build}">
+ <path id="project.class.path">
+ <pathelement location="${lib}"/>
+ <pathelement path="${java.class.path}"/>
+ <pathelement path="${additional.path}"/>
+ </path>
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Main-Class" value="YalpInputs.YalpPGSqlInput.YalpPGSqlInput"/>
+ <attribute name="Class-Path" value="${dbLibs}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name ="auth" description="builds auth base files">
+ <javac debug="true" srcdir="${srcAuth}" destdir="${build}"/>
+ </target>
+
+ <target name ="pgsqlauth" depends="interfaces, auth" description="builds the pgsql auth plugin">
+ <javac debug="true" srcdir="${srcPGSqlAuth}" destdir="${build}"/>
+ <jar destfile="yalpPGSqlAuth.jar" basedir="${build}">
+ <path id="project.class.path">
+ <pathelement location="${lib}"/>
+ <pathelement path="${java.class.path}"/>
+ <pathelement path="${additional.path}"/>
+ </path>
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Main-Class" value="YalpAuth.YalpPGSqlAuth.YalpPGSqlAuth"/>
+ <attribute name="Class-Path" value="${dbLibs}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name ="clients" depends="interfaces" description="builds the client bsae files">
+ <javac debug="true" srcdir="${srcClients}" destdir="${build}"/>
+ </target>
+
+ <target name ="swtclient" depends="clients" description="builds SWT GUI">
+ <javac debug="true" srcdir="${srcSwtClient}" destdir="${build}"/>
+ <jar destfile="yalpSWTClient.jar" basedir="${build}">
+ <path id="project.class.path">
+ <pathelement location="${lib}"/>
+ <pathelement path="${java.class.path}"/>
+ <pathelement path="${additional.path}"/>
+ </path>
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Main-Class" value="YalpClients.SwtClient.SwtClient"/>
+ <attribute name="Class-Path" value="${swtLibs}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="swtgui" depends="swtclient">
+ <javac debug="true" srcdir="${srcSwtGUI}" destdir="${build}">
+ <classpath refid="project.class.path"/>
+ </javac>
+ </target>
+
+ <target name="clean" depends="cleandoc" description="Removes previous build">
+ <delete verbose="true">
+ <fileset dir="${build}"/>
+ <fileset dir="${srcInterfaces}"/>
+ </delete>
+ </target>
+
+ <target name="runserver" depends="server" description="starts Server">
+ <java jar="server.jar" fork="true"/>
+ </target>
+
+ <target name="runclient" depends="swtclient" description="starts Client">
+ <java jar="client.jar" fork="true"/>
+ </target>
+
+ <target name="cleandoc" depends="cleansqldoc, cleanjavadoc"/>
+
+ <target name="cleansqldoc" description="Removes previous sqldoc">
+ <delete verbose="true">
+ <fileset dir="${sqldoc}"/>
+ </delete>
+ </target>
+
+ <target name="cleanjavadoc" description="Removes previous javadoc">
+ <delete verbose="true">
+ <fileset dir="${javadoc}"/>
+ </delete>
+ </target>
+
+ <target name="doc" depends="cleandoc" description="generates javadoc">
+ <javadoc packagenames="YalpAuth.*, YalpServer, YalpClients.*, YalpInterfaces, YalpOutputs.*, YalpInputs.*" sourcepath="src" author="true" version="true" use="true" destdir="${javadoc}"/>
+ <exec dir="." executable="${psqldoc}">
+ <arg line="-d yalp -f ${sqldoc}/yalp -h localhost -u yalp --password=yalp -l ./postgresql_autodoc"/>
+ </exec>
+ </target>
+
+</project>
diff --git a/client.policy b/client.policy new file mode 100644 index 0000000..9b5a629 --- /dev/null +++ b/client.policy @@ -0,0 +1,20 @@ +grant {
+ permission java.net.SocketPermission "*:80","connect,resolve";
+ permission java.util.PropertyPermission "swt.version", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+
+ permission java.util.PropertyPermission "org.eclipse.swt.internal.carbon.smallFonts", "read";
+ permission java.util.PropertyPermission "org.eclipse.swt.internal.carbon.noFocusRing", "read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-gtk-3139", "read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-pi-gtk-3139", "read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-pi-gtk", "read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-pi-carbon","read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-pi-carbon-3139" ,"read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-win32-3139" ,"read";
+ permission java.lang.RuntimePermission "loadLibrary.swt-carbon-3139" ,"read";
+ permission java.io.FilePermission "<<ALL FILES>>","read,write,execute";
+ permission java.io.FilePermission "C:\\Programme\\VideoLAN\\VLC\\vlc","execute";
+ permission java.io.FilePermission "/Applications/VLC.app/Contents/MacOS/VLC","execute";
+ permission java.net.SocketPermission "*:1024-","connect,resolve";
+};
diff --git a/client.sh b/client.sh new file mode 100755 index 0000000..e1d2711 --- /dev/null +++ b/client.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpSWTClient.jar -ORBInitialPort 1050 -ORBInitialHost localhost @@ -0,0 +1,3 @@ +#!/bin/bash +#/opt/sun-jdk-1.6.0.07/bin/idlj -fall $@ +/opt/ibm-java-i386-60/bin/idlj -fall $@ diff --git a/img/folder.gif b/img/folder.gif Binary files differnew file mode 100755 index 0000000..411fe64 --- /dev/null +++ b/img/folder.gif diff --git a/img/forward.gif b/img/forward.gif Binary files differnew file mode 100755 index 0000000..17cfe1d --- /dev/null +++ b/img/forward.gif diff --git a/img/pause.gif b/img/pause.gif Binary files differnew file mode 100755 index 0000000..28f71b5 --- /dev/null +++ b/img/pause.gif diff --git a/img/play.gif b/img/play.gif Binary files differnew file mode 100755 index 0000000..9cdf8a2 --- /dev/null +++ b/img/play.gif diff --git a/img/stop.gif b/img/stop.gif Binary files differnew file mode 100755 index 0000000..75e4ff7 --- /dev/null +++ b/img/stop.gif diff --git a/img/yalp.bmp b/img/yalp.bmp Binary files differnew file mode 100755 index 0000000..a9465d1 --- /dev/null +++ b/img/yalp.bmp diff --git a/img/yalp.gif b/img/yalp.gif Binary files differnew file mode 100755 index 0000000..b8c23fe --- /dev/null +++ b/img/yalp.gif diff --git a/img/yalp.ico b/img/yalp.ico Binary files differnew file mode 100755 index 0000000..414efa3 --- /dev/null +++ b/img/yalp.ico diff --git a/img/yalpLogo.gif b/img/yalpLogo.gif Binary files differnew file mode 100755 index 0000000..57ed766 --- /dev/null +++ b/img/yalpLogo.gif diff --git a/img/yalpV2.gif b/img/yalpV2.gif Binary files differnew file mode 100755 index 0000000..4640702 --- /dev/null +++ b/img/yalpV2.gif diff --git a/img/yalpV2_klein.gif b/img/yalpV2_klein.gif Binary files differnew file mode 100755 index 0000000..a9845d4 --- /dev/null +++ b/img/yalpV2_klein.gif diff --git a/img/yalpV2_mittel.gif b/img/yalpV2_mittel.gif Binary files differnew file mode 100755 index 0000000..9be65b7 --- /dev/null +++ b/img/yalpV2_mittel.gif diff --git a/img/yalpV2_original.gif b/img/yalpV2_original.gif Binary files differnew file mode 100755 index 0000000..3dcb582 --- /dev/null +++ b/img/yalpV2_original.gif diff --git a/img/yalp_klein.gif b/img/yalp_klein.gif Binary files differnew file mode 100755 index 0000000..e0fe9ab --- /dev/null +++ b/img/yalp_klein.gif diff --git a/input.sh b/input.sh new file mode 100755 index 0000000..b77419f --- /dev/null +++ b/input.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpPGSqlInput.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/lib/commons-net-1.4.1.jar b/lib/commons-net-1.4.1.jar Binary files differnew file mode 100755 index 0000000..9666a92 --- /dev/null +++ b/lib/commons-net-1.4.1.jar diff --git a/lib/id3-1.6.0d9.jar b/lib/id3-1.6.0d9.jar Binary files differnew file mode 100755 index 0000000..7da41c5 --- /dev/null +++ b/lib/id3-1.6.0d9.jar diff --git a/lib/jarbundler-1.4.jar b/lib/jarbundler-1.4.jar Binary files differnew file mode 100755 index 0000000..b74baa6 --- /dev/null +++ b/lib/jarbundler-1.4.jar diff --git a/lib/libswt-carbon-3139.jnilib b/lib/libswt-carbon-3139.jnilib Binary files differnew file mode 100755 index 0000000..cc04ee4 --- /dev/null +++ b/lib/libswt-carbon-3139.jnilib diff --git a/lib/libswt-pi-carbon-3139.jnilib b/lib/libswt-pi-carbon-3139.jnilib Binary files differnew file mode 100755 index 0000000..307d8eb --- /dev/null +++ b/lib/libswt-pi-carbon-3139.jnilib diff --git a/lib/libswt-webkit-carbon-3139.jnilib b/lib/libswt-webkit-carbon-3139.jnilib Binary files differnew file mode 100755 index 0000000..e95b2fd --- /dev/null +++ b/lib/libswt-webkit-carbon-3139.jnilib diff --git a/lib/log4j-1.2.15.jar b/lib/log4j-1.2.15.jar Binary files differnew file mode 100755 index 0000000..c930a6a --- /dev/null +++ b/lib/log4j-1.2.15.jar diff --git a/lib/postgresql-8.1-404.jdbc3.jar b/lib/postgresql-8.1-404.jdbc3.jar Binary files differnew file mode 100755 index 0000000..01c43bb --- /dev/null +++ b/lib/postgresql-8.1-404.jdbc3.jar diff --git a/lib/swt-win32-3139.dll b/lib/swt-win32-3139.dll Binary files differnew file mode 100755 index 0000000..720fa74 --- /dev/null +++ b/lib/swt-win32-3139.dll diff --git a/lib/swt.jar b/lib/swt.jar Binary files differnew file mode 100755 index 0000000..253f82f --- /dev/null +++ b/lib/swt.jar diff --git a/lib/yajil-0.3.3.jar b/lib/yajil-0.3.3.jar Binary files differnew file mode 100755 index 0000000..8dd5834 --- /dev/null +++ b/lib/yajil-0.3.3.jar diff --git a/log4j_server.conf b/log4j_server.conf new file mode 100644 index 0000000..79c355b --- /dev/null +++ b/log4j_server.conf @@ -0,0 +1,8 @@ +log4j.rootLogger=debug, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n + diff --git a/output.sh b/output.sh new file mode 100755 index 0000000..cdad4fd --- /dev/null +++ b/output.sh @@ -0,0 +1 @@ +java -Djava.library.path=./lib -jar yalpVlcTelnetOutput.jar -ORBInitialPort 1050 -ORBInitialHost localhost diff --git a/postgresql_autodoc/Makefile b/postgresql_autodoc/Makefile new file mode 100644 index 0000000..fdddc1a --- /dev/null +++ b/postgresql_autodoc/Makefile @@ -0,0 +1,103 @@ +# $Header: /cvsroot/autodoc/autodoc/Makefile,v 1.3 2006/05/16 18:57:24 rbt Exp $ + +TEMPLATES = dia.tmpl dot.tmpl html.tmpl neato.tmpl xml.tmpl zigzag.dia.tmpl +BINARY = postgresql_autodoc +CONFIGFILE = config.mk + +RELEASE_FILES = Makefile config.mk.in configure \ + configure.ac $(TEMPLATES) install-sh \ + postgresql_autodoc.pl + +cur-dir := $(shell basename ${PWD}) +REAL_RELEASE_FILES = $(addprefix $(cur-dir)/,$(RELEASE_FILES)) + +# Global dependencies +ALWAYS_DEPEND = Makefile configure $(CONFIGFILE) + + +#### +# Test to see if $(CONFIGFILE) has been generated. If so, include it. Otherwise we assume +# it will be created for us. +has_configmk := $(wildcard $(CONFIGFILE)) + +ifeq ($(has_configmk),$(CONFIGFILE)) +include $(CONFIGFILE) +endif + +#### +# ALL +.PHONY: all +all: $(ALWAYS_DEPEND) $(BINARY) + +#### +# Replace the /usr/bin/env perl with the supplied path +# chmod to make testing easier +$(BINARY): postgresql_autodoc.pl $(CONFIGFILE) + $(SED) -e "s,/usr/bin/env perl,$(PERL)," \ + -e "s,@@TEMPLATE-DIR@@,$(datadir)," \ + postgresql_autodoc.pl > $(BINARY) + -chmod +x $(BINARY) + +#### +# INSTALL Target +.PHONY: install uninstall +install: all $(ALWAYS_DEPEND) + $(INSTALL_SCRIPT) -d $(bindir) + $(INSTALL_SCRIPT) -d $(datadir) + $(INSTALL_SCRIPT) -m 755 $(BINARY) $(bindir) + for entry in $(TEMPLATES) ; \ + do $(INSTALL_SCRIPT) -m 644 $${entry} $(datadir) ; \ + done + +uninstall: + -$(RM) $(bindir)/$(BINARY) + for entry in $(TEMPLATES) ; \ + do $(RM) $(datadir)/$${entry} ; \ + done + -rmdir $(datadir) + -rmdir $(bindir) + +#### +# CLEAN / DISTRIBUTION-CLEAN / MAINTAINER-CLEAN Targets +.PHONY: clean +clean: $(ALWAYS_DEPEND) + $(RM) $(BINARY) + +.PHONY: distribution-clean distclean +distribution-clean distclean: clean + $(RM) $(CONFIGFILE) config.log config.status + $(RM) -r autom4te.cache + $(RM) $(patsubst %.tmpl,*.%,$(wildcard *.tmpl)) + +.PHONY: maintainer-clean +maintainer-clean: distribution-clean + $(RM) configure + +#### +# Build a release +# +# Clean +# Ensure configure is up to date +# Commit any pending elements +# Tar up the results +.PHONY: release +release: distribution-clean configure $(RELEASE_FILES) + @if [ -z ${VERSION} ] ; then \ + echo "-------------------------------------------"; \ + echo "VERSION needs to be specified for a release"; \ + echo "-------------------------------------------"; \ + false; \ + fi + cvs2cl + -cvs commit + cd ../ && tar -czvf postgresql_autodoc-${VERSION}.tar.gz $(REAL_RELEASE_FILES) + +#### +# Build and Run configure files when configure or a template is updated. +configure: configure.ac + autoconf + +# Fix my makefile, then execute myself +$(CONFIGFILE) : config.mk.in configure + ./configure + $(MAKE) $(MAKEFLAGS) diff --git a/postgresql_autodoc/config.log b/postgresql_autodoc/config.log new file mode 100644 index 0000000..5ac7ad9 --- /dev/null +++ b/postgresql_autodoc/config.log @@ -0,0 +1,164 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = tc4200 +uname -m = i686 +uname -r = 2.6.26 +uname -s = Linux +uname -v = #30 PREEMPT Mon Jul 14 10:58:29 CEST 2008 + +/usr/bin/uname -p = Intel(R) Pentium(R) M processor 1.73GHz +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/local/bin +PATH: /usr/bin +PATH: /bin +PATH: /opt/bin +PATH: /usr/i686-pc-linux-gnu/arm-gentoo-linux-uclibc/gcc-bin/4.1.2 +PATH: /usr/i686-pc-linux-gnu/arm-linux-uclibc/gcc-bin/4.1.2 +PATH: /usr/i686-pc-linux-gnu/gcc-bin/4.3.1 +PATH: /usr/i686-pc-linux-gnu/powerpc-fendt-linux-gnu/gcc-bin/4.2.2 +PATH: /opt/e17/bin +PATH: /usr/kde/3.5/bin +PATH: /usr/qt/3/bin +PATH: /usr/games/bin +PATH: /opt/bin +PATH: /opt/ACE_wrappers/bin +PATH: /opt/ACE_wrappers/TAO/orbsvcs/Naming_Service +PATH: /home/linutronix/scripts +PATH: /home/linutronix/scripts + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:1665: checking for a BSD-compatible install +configure:1721: result: /usr/bin/install -c +configure:1737: checking for sed +configure:1756: found /bin/sed +configure:1768: result: /bin/sed +configure:1824: checking for perl +configure:1843: found /usr/bin/perl +configure:1855: result: /usr/bin/perl +configure:1884: checking DBI +configure:1893: result: yes +configure:1884: checking DBD::Pg +configure:1893: result: yes +configure:1884: checking Fcntl +configure:1893: result: yes +configure:1884: checking HTML::Template +configure:1893: result: yes +configure:1884: checking Term::ReadKey +configure:1893: result: yes +configure:2031: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on tc4200 + +config.status:570: creating config.mk +config.status:705: WARNING: config.mk.in seems to ignore the --datarootdir setting + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_path_PERL=/usr/bin/perl +ac_cv_path_SED=/bin/sed +ac_cv_path_install='/usr/bin/install -c' + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +DEFS='-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\"' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LIBOBJS='' +LIBS='' +LTLIBOBJS='' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +PERL='/usr/bin/perl' +SED='/bin/sed' +SHELL='/bin/sh' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host_alias='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" + +configure: exit 0 diff --git a/postgresql_autodoc/config.mk b/postgresql_autodoc/config.mk new file mode 100644 index 0000000..73bd570 --- /dev/null +++ b/postgresql_autodoc/config.mk @@ -0,0 +1,13 @@ +SHELL = /bin/sh + + +# Configure replacements +INSTALL_SCRIPT = /usr/bin/install -c +PERL = /usr/bin/perl +SED = /bin/sed + +# installation directories +prefix = /usr/local +exec_prefix= ${prefix} +bindir = ${exec_prefix}/bin +datadir = ${prefix}/share/postgresql_autodoc diff --git a/postgresql_autodoc/config.mk.in b/postgresql_autodoc/config.mk.in new file mode 100644 index 0000000..ddcee1a --- /dev/null +++ b/postgresql_autodoc/config.mk.in @@ -0,0 +1,13 @@ +SHELL = /bin/sh +VPATH = @srcdir@ + +# Configure replacements +INSTALL_SCRIPT = @INSTALL@ +PERL = @PERL@ +SED = @SED@ + +# installation directories +prefix = @prefix@ +exec_prefix= @exec_prefix@ +bindir = @bindir@ +datadir = @datadir@/postgresql_autodoc diff --git a/postgresql_autodoc/config.status b/postgresql_autodoc/config.status new file mode 100755 index 0000000..5f5e3a1 --- /dev/null +++ b/postgresql_autodoc/config.status @@ -0,0 +1,761 @@ +#! /bin/sh +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/sh} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" config.mk" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to <bug-autoconf@gnu.org>." + +ac_cs_version="\ +config.status +configured by ./configure, generated by GNU Autoconf 2.61, + with options \"\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/manut/postgresql_autodoc' +srcdir='.' +INSTALL='/usr/bin/install -c' +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running CONFIG_SHELL=/bin/sh /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=/bin/sh + export CONFIG_SHELL + exec /bin/sh "./configure" $ac_configure_extra_args --no-create --no-recursion +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +cat >"$tmp/subs-1.sed" <<\CEOF +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +s,@SHELL@,|#_!!_#|/bin/sh,g +s,@PATH_SEPARATOR@,|#_!!_#|:,g +s,@PACKAGE_NAME@,|#_!!_#|,g +s,@PACKAGE_TARNAME@,|#_!!_#|,g +s,@PACKAGE_VERSION@,|#_!!_#|,g +s,@PACKAGE_STRING@,|#_!!_#|,g +s,@PACKAGE_BUGREPORT@,|#_!!_#|,g +s,@exec_prefix@,|#_!!_#|${prefix},g +s,@prefix@,|#_!!_#|/usr/local,g +s,@program_transform_name@,|#_!!_#|s\,x\,x\,,g +s,@bindir@,|#_!!_#|${exec_prefix}/bin,g +s,@sbindir@,|#_!!_#|${exec_prefix}/sbin,g +s,@libexecdir@,|#_!!_#|${exec_prefix}/libexec,g +s,@datarootdir@,|#_!!_#|${prefix}/share,g +s,@datadir@,|#_!!_#|${datarootdir},g +s,@sysconfdir@,|#_!!_#|${prefix}/etc,g +s,@sharedstatedir@,|#_!!_#|${prefix}/com,g +s,@localstatedir@,|#_!!_#|${prefix}/var,g +s,@includedir@,|#_!!_#|${prefix}/include,g +s,@oldincludedir@,|#_!!_#|/usr/include,g +s,@docdir@,|#_!!_#|${datarootdir}/doc/${PACKAGE},g +s,@infodir@,|#_!!_#|${datarootdir}/info,g +s,@htmldir@,|#_!!_#|${docdir},g +s,@dvidir@,|#_!!_#|${docdir},g +s,@pdfdir@,|#_!!_#|${docdir},g +s,@psdir@,|#_!!_#|${docdir},g +s,@libdir@,|#_!!_#|${exec_prefix}/lib,g +s,@localedir@,|#_!!_#|${datarootdir}/locale,g +s,@mandir@,|#_!!_#|${datarootdir}/man,g +s,@DEFS@,|#_!!_#|-DPACKAGE_NAME=\\"\\" -DPACKAGE_TARNAME=\\"\\" -DPACKAGE_VERSION=\\"\\" -DPACKAGE_STRING=\\"\\" -DPACKAGE_BUGREPORT=\\"\\",g +s,@ECHO_C@,|#_!!_#|,g +s,@ECHO_N@,|#_!!_#|-n,g +s,@ECHO_T@,|#_!!_#|,g +s,@LIBS@,|#_!!_#|,g +s,@build_alias@,|#_!!_#|,g +s,@host_alias@,|#_!!_#|,g +s,@target_alias@,|#_!!_#|,g +s,@INSTALL_PROGRAM@,|#_!!_#|${INSTALL},g +s,@INSTALL_SCRIPT@,|#_!!_#|${INSTALL},g +s,@INSTALL_DATA@,|#_!!_#|${INSTALL} -m 644,g +s,@SED@,|#_!!_#|/bin/sed,g +s,@PERL@,|#_!!_#|/usr/bin/perl,g +s,@LIBOBJS@,|#_!!_#|,g +s,@LTLIBOBJS@,|#_!!_#|,g +:end +s/|#_!!_#|//g +CEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } diff --git a/postgresql_autodoc/configure b/postgresql_autodoc/configure new file mode 100755 index 0000000..776cb9d --- /dev/null +++ b/postgresql_autodoc/configure @@ -0,0 +1,2907 @@ +#! /bin/sh +# From configure.ac Header: /cvsroot/autodoc/autodoc/configure.ac. +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="postgresql_autodoc.pl" +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +SED +PERL +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-perl-prefix Location of Perl + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +# Programs +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +for ac_prog in sed +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $SED in + [\\/]* | ?:[\\/]*) + ac_cv_path_SED="$SED" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/bin:/usr/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +SED=$ac_cv_path_SED +if test -n "$SED"; then + { echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$SED" && break +done + + +# Check for Perl + +# Check whether --with-perl-prefix was given. +if test "${with_perl_prefix+set}" = set; then + withval=$with_perl_prefix; PERLPATH=$withval +else + PERLPATH="" +fi + + +if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then + PERLPATH="$PWD/$PERLPATH" +fi + +PERL="" +if ( test -n "$PERLPATH" ); then + as_ac_File=`echo "ac_cv_file_"$PERLPATH/bin/perl"" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for \"$PERLPATH/bin/perl\"" >&5 +echo $ECHO_N "checking for \"$PERLPATH/bin/perl\"... $ECHO_C" >&6; } +if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r ""$PERLPATH/bin/perl""; then + eval "$as_ac_File=yes" +else + eval "$as_ac_File=no" +fi +fi +ac_res=`eval echo '${'$as_ac_File'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_File'}'` = yes; then + PERL="$PERLPATH/bin/perl" +fi + +else + for ac_prog in perl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$PERL" && break +done + +fi +if ( test -z "$PERL" ); then + { { echo "$as_me:$LINENO: error: \"Perl is required\"" >&5 +echo "$as_me: error: \"Perl is required\"" >&2;} + { (exit 1); exit 1; }; } +fi + + + +# Check that Perl Libraries are available: +# DBI +# DBD::Pg +# Fcntl +# HTML::Template +# Term::ReadKey +# +# Output of if test redirected to /dev/null to keep quiet +for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do + { echo "$as_me:$LINENO: checking ${module}" >&5 +echo $ECHO_N "checking ${module}... $ECHO_C" >&6; } + if ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: Perl module ${module} is required" >&5 +echo "$as_me: error: Perl module ${module} is required" >&2;} + { (exit 1); exit 1; }; } + else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + fi +done + + +ac_config_files="$ac_config_files config.mk" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to <bug-autoconf@gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +SED!$SED$ac_delim +PERL!$PERL$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 44; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/postgresql_autodoc/configure.ac b/postgresql_autodoc/configure.ac new file mode 100644 index 0000000..128a044 --- /dev/null +++ b/postgresql_autodoc/configure.ac @@ -0,0 +1,56 @@ +AC_PREREQ(2.53) +AC_REVISION($Header: /cvsroot/autodoc/autodoc/configure.ac,v 1.2 2007/01/02 13:53:19 rbt Exp $) +AC_INIT(postgresql_autodoc.pl) + + +# Programs +AC_PROG_INSTALL + +AC_PATH_PROGS([SED], [sed], , + [$PATH:/bin:/usr/bin]) + +# Check for Perl +AC_ARG_WITH(perl-prefix, + [ --with-perl-prefix Location of Perl], + PERLPATH=$withval, + PERLPATH="") + +if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then + PERLPATH="$PWD/$PERLPATH" +fi + +PERL="" +if ( test -n "$PERLPATH" ); then + AC_CHECK_FILE("$PERLPATH/bin/perl",PERL="$PERLPATH/bin/perl") +else + AC_PATH_PROGS([PERL], [perl], , + [$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin]) +fi +if ( test -z "$PERL" ); then + AC_MSG_ERROR("Perl is required") +fi +AC_SUBST(PERL) + + +# Check that Perl Libraries are available: +# DBI +# DBD::Pg +# Fcntl +# HTML::Template +# Term::ReadKey +# +# Output of if test redirected to /dev/null to keep quiet +for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do + AC_MSG_CHECKING(${module}) + if [ ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ]; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(Perl module ${module} is required) + else + AC_MSG_RESULT(yes) + fi +done + + +AC_OUTPUT([ +config.mk +]) diff --git a/postgresql_autodoc/dia.tmpl b/postgresql_autodoc/dia.tmpl new file mode 100644 index 0000000..88143e9 --- /dev/null +++ b/postgresql_autodoc/dia.tmpl @@ -0,0 +1,212 @@ +<?xml version="1.0" encoding="UTF-8"?> +<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/"> + <dia:layer name="Background" visible="true"> +<!-- TMPL_LOOP name="schemas" --> +<!-- TMPL_IF name="number_of_schemas" --> + <dia:group> +<!-- /TMPL_IF name="number_of_schemas" --> +<!-- TMPL_LOOP name="tables" --> + <dia:object type="UML - Class" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->"> + <dia:attribute name="obj_pos"> + <dia:point val="0,0"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="-0.05,-0.05;16.4,6.65"/> + </dia:attribute> + <dia:attribute name="elem_corner"> + <dia:point val="0,0"/> + </dia:attribute> + <dia:attribute name="elem_width"> + <dia:real val="16.350000000000001"/> + </dia:attribute> + <dia:attribute name="elem_height"> + <dia:real val="6.6000000000000005"/> + </dia:attribute> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table" -->#</dia:string> + </dia:attribute> +<!-- TMPL_IF name="number_of_schemas" --> + <dia:attribute name="stereotype"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="schema" -->#</dia:string> + </dia:attribute> +<!-- /TMPL_IF name="number_of_schemas" --> + <dia:attribute name="comment"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table_comment_dia" -->#</dia:string> + </dia:attribute> + <dia:attribute name="abstract"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="suppress_attributes"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="suppress_operations"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="visible_attributes"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="visible_comments"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="wrap_operations"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="wrap_after_char"> + <dia:int val="40"/> + </dia:attribute> + <dia:attribute name="line_color"> + <dia:color val="#000000"/> + </dia:attribute> + <dia:attribute name="fill_color"> + <dia:color val="#ffffff"/> + </dia:attribute> + <dia:attribute name="text_color"> + <dia:color val="#000000"/> + </dia:attribute> + <dia:attribute name="normal_font"> + <dia:font family="monospace" style="0" name="Courier"/> + </dia:attribute> + <dia:attribute name="abstract_font"> + <dia:font family="monospace" style="88" name="Courier"/> + </dia:attribute> + <dia:attribute name="polymorphic_font"> + <dia:font family="monospace" style="8" name="Courier"/> + </dia:attribute> + <dia:attribute name="classname_font"> + <dia:font family="sans" style="80" name="Helvetica"/> + </dia:attribute> + <dia:attribute name="abstract_classname_font"> + <dia:font family="sans" style="88" name="Helvetica"/> + </dia:attribute> + <dia:attribute name="comment_font"> + <dia:font family="sans" style="8" name="Helvetica"/> + </dia:attribute> + <dia:attribute name="font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="polymorphic_font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="abstract_font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="classname_font_height"> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="abstract_classname_font_height"> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="comment_font_height"> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="attributes"> +<!-- TMPL_LOOP name="columns" --> + <dia:composite type="umlattribute"> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_IF name="column_primary_key" -->PK<!-- TMPL_ELSE name="column_primary_key" --> <!-- /TMPL_IF name="column_primary_key" --><!-- TMPL_VAR ESCAPE="HTML" name="column" -->#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_type" -->#</dia:string> + </dia:attribute> + <dia:attribute name="value"> +<!-- TMPL_IF name="column_default_short" --> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_default_short" -->#</dia:string> +<!-- TMPL_ELSE name="column_default_short" --> + <dia:string/> +<!-- /TMPL_IF name="column_default_short" --> + </dia:attribute> + <dia:attribute name="visibility"> + <dia:enum val="3"/> + </dia:attribute> + <dia:attribute name="abstract"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="class_scope"> + <dia:boolean val="false"/> + </dia:attribute> + </dia:composite> +<!-- /TMPL_LOOP name="columns" --> + </dia:attribute> +<!-- TMPL_IF name="constraints" --> + <dia:attribute name="visible_operations"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="operations"> +<!-- TMPL_LOOP name="constraints" --> + <dia:composite type="umloperation"> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" -->#</dia:string> + </dia:attribute> + <dia:attribute name="visibility"> + <dia:enum val="3"/> + </dia:attribute> + <dia:attribute name="abstract"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="class_scope"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="parameters"> + <dia:composite type="umlparameter"> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_short" -->#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + <dia:string>##</dia:string> + </dia:attribute> + <dia:attribute name="value"> + <dia:string/> + </dia:attribute> + <dia:attribute name="kind"> + <dia:enum val="0"/> + </dia:attribute> + </dia:composite> + </dia:attribute> + </dia:composite> +<!-- /TMPL_LOOP name="constraints" --> + </dia:attribute> +<!-- TMPL_ELSE name="constraints" --> + <dia:attribute name="visible_operations"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="operations"/> +<!-- /TMPL_IF name="constraints" --> + <dia:attribute name="template"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="templates"/> + </dia:object> +<!-- /TMPL_LOOP name="tables" --> +<!-- TMPL_IF name="number_of_schemas" --> + </dia:group> +<!-- /TMPL_IF name="number_of_schemas" --> +<!-- /TMPL_LOOP name="schemas" --> +<!-- TMPL_LOOP name="fk_links" --> + <dia:object type="UML - Constraint" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->"> + <dia:attribute name="obj_pos"> + <dia:point val="0,3.5"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="-0.0515705,2.29861;25.1127,3.55157"/> + </dia:attribute> + <dia:attribute name="conn_endpoints"> + <dia:point val="0,3.5"/> + <dia:point val="25.05,2.7"/> + </dia:attribute> + <dia:attribute name="constraint"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="fk_link_name" -->#</dia:string> + </dia:attribute> + <dia:attribute name="text_pos"> + <dia:point val="12.525,3.1"/> + </dia:attribute> + <dia:attribute name="line_colour"> + <dia:color val="#000000"/> + </dia:attribute> + <dia:connections> + <dia:connection handle="0" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle0_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle0_connection_dia" -->"/> + <dia:connection handle="1" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle1_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle1_connection_dia" -->"/> + </dia:connections> + </dia:object> +<!-- /TMPL_LOOP name="fk_links" --> + </dia:layer> +</dia:diagram> diff --git a/postgresql_autodoc/dot.tmpl b/postgresql_autodoc/dot.tmpl new file mode 100644 index 0000000..1cb9ca6 --- /dev/null +++ b/postgresql_autodoc/dot.tmpl @@ -0,0 +1,19 @@ +digraph g { +graph [ +rankdir = "LR", +concentrate = true, +ratio = auto +]; +node [ +fontsize = "10", +shape = record +]; +edge [ +]; +<TMPL_LOOP name="schemas"><TMPL_LOOP name="tables"><TMPL_UNLESS name="view_definition"> +"<TMPL_IF name="number_of_schemas"><TMPL_VAR name="schema_dot">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="table_dot">" [shape = plaintext, label = < <TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR ><TD PORT="ltcol0"> </TD> <TD bgcolor="grey90" border="1" COLSPAN="4"> \N </TD> <TD PORT="rtcol0"></TD></TR> <TMPL_LOOP name="columns"> <TR><TD PORT="ltcol<TMPL_VAR name="column_number">" ></TD><TD align="left" > <TMPL_VAR name="column_dot"> </TD><TD align="left" > <TMPL_VAR name="column_type"> </TD><TD align="left" > <TMPL_LOOP name="column_constraints"><TMPL_IF NAME="column_primary_key">PK</TMPL_IF NAME="column_primary_key"></TMPL_LOOP name="column_constraints"> </TD><TD align="left" > <TMPL_LOOP name="column_constraints"><TMPL_IF NAME="column_fk"><TMPL_IF NAME="__first__">FK</TMPL_IF NAME="__first__"></TMPL_IF NAME="column_fk"></TMPL_LOOP name="column_constraints"> </TD><TD align="left" PORT="rtcol<TMPL_VAR name="column_number">"> </TD></TR></TMPL_LOOP name="columns"> </TABLE>> ]; +</TMPL_UNLESS name="view_definition"></TMPL_LOOP name="tables"></TMPL_LOOP name="schemas"> + +<TMPL_LOOP name="fk_links"> +"<TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle0_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle0_name">":rtcol<TMPL_VAR name="handle0_connection"> -> "<TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle1_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle1_name">":ltcol<TMPL_VAR name="handle1_connection"> [label="<TMPL_VAR name="fk_link_name_dot">"];</TMPL_LOOP name="fk_links"> +} diff --git a/postgresql_autodoc/html.tmpl b/postgresql_autodoc/html.tmpl new file mode 100644 index 0000000..4830b15 --- /dev/null +++ b/postgresql_autodoc/html.tmpl @@ -0,0 +1,308 @@ +<!-- $Header: /cvsroot/autodoc/autodoc/html.tmpl,v 1.4 2006/05/16 19:01:27 rbt Exp $ --> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> + +<html> + <head> + <title>Index for <!-- TMPL_VAR ESCAPE="HTML" name="database" --></title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <style type="text/css"> + BODY { + color: #000000; + background-color: #FFFFFF; + font-family: Helvetica, sans-serif; + } + + P { + margin-top: 5px; + margin-bottom: 5px; + } + + P.w3ref { + font-size: 8pt; + font-style: italic; + text-align: right; + } + + P.detail { + font-size: 10pt; + } + + .error { + color: #FFFFFF; + background-color: #FF0000; + } + + H1, H2, H3, H4, H5, H6 { + } + + OL { + list-style-type: upper-alpha; + } + + UL.topic { + list-style-type: upper-alpha; + } + + LI.topic { + font-weight : bold; + } + + HR { + color: #00FF00; + background-color: #808080; + } + + TABLE { + border-width: medium; + padding: 3px; + background-color: #000000; + width: 90%; + } + + CAPTION { + text-transform: capitalize; + font-weight : bold; + font-size: 14pt; + } + + TH { + color: #FFFFFF; + background-color: #000000; + text-align: left; + } + + TR { + color: #000000; + background-color: #000000; + vertical-align: top; + } + + TR.tr0 { + background-color: #F0F0F0; + } + + TR.tr1 { + background-color: #D8D8D8; + } + + TD { + font-size: 12pt; + } + + TD.col0 { + font-weight : bold; + width: 20%; + } + + TD.col1 { + font-style: italic; + width: 15%; + } + + TD.col2 { + font-size: 12px; + } + </style> + <link rel="stylesheet" type="text/css" media="all" href="all.css"> + <link rel="stylesheet" type="text/css" media="screen" href="screen.css"> + <link rel="stylesheet" type="text/css" media="print" href="print.css"> + <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + </head> + <body> + + <!-- Primary Index --> + <p><!-- TMPL_VAR ESCAPE="HTML" name="database_comment" --><br><br>Dumped on <!-- TMPL_VAR ESCAPE="HTML" name="dumped_on" --></p> +<h1><a name="index">Index of database - <!-- TMPL_VAR ESCAPE="HTML" name="database" --></a></h1> +<ul> + <!-- TMPL_LOOP name="schemas" --> + <li><a name="<!-- TMPL_VAR ESCAPE="HTML" name="schema_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a></li><ul> + <!-- TMPL_LOOP name="tables" --><li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="table_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="table" --></a></li><!-- /TMPL_LOOP name="tables" --> + <!-- TMPL_LOOP name="functions" --><li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="function_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="function" --></a></li><!-- /TMPL_LOOP name="functions" --> + </ul> + <!-- /TMPL_LOOP name="schemas" --> +</ul> + + <!-- Schema Creation --> + <!-- TMPL_LOOP name="schemas" --><!-- <!-- TMPL_VAR ESCAPE="HTML" name="schema" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" --> --> + + <!-- TMPL_IF name="number_of_schemas" --> + <hr> + <h1>Schema <!-- TMPL_VAR ESCAPE="HTML" name="schema" --></h1> + <!-- TMPL_IF name="schema_comment" --> + <p><!-- TMPL_VAR name="schema_comment" --></p> + <!-- /TMPL_IF name="schema_comment" --> + + <!-- /TMPL_IF name="number_of_schemas" --> + <!-- TMPL_LOOP name="tables" --> + <hr> + <h2><!-- TMPL_IF name="view_definition" -->View:<!-- TMPL_ELSE -->Table:<!-- /TMPL_IF --> + <!-- TMPL_IF name="number_of_schemas" --> + <a href="#<!-- TMPL_VAR ESCAPE="URL" name="schema_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>.<!-- /TMPL_IF name="number_of_schemas" --><a name="<!-- TMPL_VAR ESCAPE="URL" name="table_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="table" --></a> + </h2> + <!-- TMPL_IF name="table_comment" --> + <p><!-- TMPL_VAR ESCAPE="HTML" name="table_comment" --></p> + <!-- /TMPL_IF name="table_comment" --> + + + <table width="100%" cellspacing="0" cellpadding="3"> + <caption><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Structure</caption> + <tr> + <th>F-Key</th> + <th>Name</th> + <th>Type</th> + <th>Description</th> + </tr> + <!-- TMPL_LOOP name="columns" --> + <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- tmpl_else name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->"> + <td> + <!-- TMPL_LOOP name="column_constraints" --> + <!-- TMPL_IF name="column_fk" --> + <a href="#<!-- TMPL_VAR ESCAPE="URL" name="column_fk_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="column_fk_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="column_fk_table" -->.<!-- TMPL_VAR ESCAPE="HTML" name="column_fk_colnum" --><!-- TMPL_IF name="column_fk_keygroup" -->#<!-- TMPL_VAR name="column_fk_keygroup" --><!-- /TMPL_IF name="column_fk_keygroup" --></a> + <!-- /TMPL_IF name="column_fk" --> + <!-- /TMPL_LOOP name="column_constraints" --> + </td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="column" --></td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="column_type" --></td> + <td><i> + <!-- TMPL_LOOP name="column_constraints" --> + <!-- TMPL_IF name="column_primary_key" -->PRIMARY KEY + <!-- /TMPL_IF name="column_primary_key" --> + + <!-- TMPL_IF name="column_unique" --> + UNIQUE<!-- TMPL_IF name="column_unique_keygroup" -->#<!-- TMPL_VAR name="column_unique_keygroup" --><!-- /TMPL_IF name="column_unique_keygroup" --> + <!-- /TMPL_IF name="column_unique" --> + <!-- /TMPL_LOOP name="column_constraints" --> + + <!-- TMPL_IF name="column_constraint_notnull" -->NOT NULL<!-- /TMPL_IF name="column_constraint_notnull" --> + <!-- TMPL_IF name="column_default" -->DEFAULT <!-- TMPL_VAR ESCAPE="HTML" name="column_default" --><!-- /TMPL_IF name="column_default" --> + </i> + <!-- TMPL_IF name="column_comment" --><br><br><!-- TMPL_VAR ESCAPE="HTML" name="column_comment" --><!-- /TMPL_IF name="column_comment" --> + </td> + </tr> + <!-- /TMPL_LOOP name="columns" --> + </table> + + <!-- Inherits --> + <!-- TMPL_IF name="inherits" --> + <p>Table <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Inherits + <!-- TMPL_LOOP name="inherits" --> + <!-- TMPL_VAR name="index_name" --> <!-- TMPL_VAR name="index_definition" --> + <a href="#<!-- TMPL_VAR ESCAPE="URL" name="parent_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="parent_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="parent_table" --></a>, + <!-- /TMPL_LOOP name="inherits" --> + </p> + <!-- /TMPL_IF name="inherits" --> + + <!-- TMPL_UNLESS name="view_definition" --> + <!-- TMPL_IF name="stats_enabled" --> + <p> </p> + <table width="100%" cellspacing="0" cellpadding="3"> + <caption>Statistics</caption> + <tr> + <th>Total Space (disk usage)</th> + <th>Tuple Count</th> + <th>Active Space</th> + <th>Dead Space</th> + <th>Free Space</th> + </tr> + <tr class="tr0"> + <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_table_bytes" --></td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_tuple_count" --></td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_tuple_bytes" --></td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_dead_bytes" --></td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_free_bytes" --></td> + </tr> + </table> + <!-- /TMPL_IF name="stats_enabled" --> + <!-- /TMPL_UNLESS name="view_definition" --> + + <!-- Constraint List --> + <!-- TMPL_IF name="constraints" --> + <p> </p> + <table width="100%" cellspacing="0" cellpadding="3"> + <caption><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Constraints</caption> + <tr> + <th>Name</th> + <th>Constraint</th> + </tr> + <!-- TMPL_LOOP name="constraints" --> + <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- TMPL_ELSE name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->"> + <td><!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" --></td> + <td><!-- TMPL_VAR ESCAPE="HTML" name="constraint" --></td> + </tr> + <!-- /TMPL_LOOP name="constraints" --> + </table> + <!-- /TMPL_IF name="constraints" --> + + <!-- Foreign Key Discovery --> + <!-- TMPL_IF name="fk_schemas" --> + <p>Tables referencing this one via Foreign Key Constraints:</p> + <!-- TMPL_LOOP name="fk_schemas" --> + <ul> + <li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="fk_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table" --></a></li> + </ul> + <!-- /TMPL_LOOP name="fk_schemas" --> + <!-- /TMPL_IF name="fk_schemas" --> + + <!-- Indexes --> + <!-- TMPL_LOOP name="indexes" --> + <!-- TMPL_VAR name="index_name" --> <!-- TMPL_VAR name="index_definition" --> + <!-- /TMPL_LOOP name="indexes" --> + + <!-- View Definition --> + <!-- TMPL_IF name="view_definition" --> + <pre><!-- TMPL_VAR ESCAPE="HTML" name="view_definition" --></pre> + <!-- /TMPL_IF name="view_definition" --> + + <!-- List off permissions --> + <!-- TMPL_IF name="permissions" --> + <p> </p> + <table width="100%" cellspacing="0" cellpadding="3"> + <caption>Permissions which apply to <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --></caption> + <tr> + <th>User</th> + <th><center>Select</center></th> + <th><center>Insert</center></th> + <th><center>Update</center></th> + <th><center>Delete</center></th> + <th><center>Reference</center></th> + <th><center>Rule</center></th> + <th><center>Trigger</center></th> + </tr> + <!-- TMPL_LOOP name="permissions" --> + <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- tmpl_else name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->"> + <td><!-- TMPL_VAR ESCAPE="HTML" name="user" --></td> + <td><!-- TMPL_IF name="select" --><center>♦</center><!-- /TMPL_IF name="select" --></td> + <td><!-- TMPL_IF name="insert" --><center>♦</center><!-- /TMPL_IF name="insert" --></td> + <td><!-- TMPL_IF name="update" --><center>♦</center><!-- /TMPL_IF name="update" --></td> + <td><!-- TMPL_IF name="delete" --><center>♦</center><!-- /TMPL_IF name="delete" --></td> + <td><!-- TMPL_IF name="references" --><center>♦</center><!-- /TMPL_IF name="references" --></td> + <td><!-- TMPL_IF name="rule" --><center>♦</center><!-- /TMPL_IF name="rule" --></td> + <td><!-- TMPL_IF name="trigger" --><center>♦</center><!-- /TMPL_IF name="trigger" --></td> + </tr> + <!-- /TMPL_LOOP name="permissions" --> + </table> + <!-- /TMPL_IF name="permissions" --> + + <p> + <a href="#index">Index</a> - + <a href="#<!-- TMPL_VAR ESCAPE="URL" name="schema_sgmlid" -->">Schema <!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a> + </p> + <!-- /TMPL_LOOP name="tables" --> + + <!-- We've gone through the table structure, now lets take a look at user functions --> + <!-- TMPL_LOOP name="functions" --> + <hr> + <h2>Function: + <a href="#<!-- TMPL_VAR ESCAPE="HTML" name="schema_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>.<!-- /TMPL_IF name="number_of_schemas" --><a name="<!-- TMPL_VAR ESCAPE="URL" name="function_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="function" --></a> + </h2> +<h3>Returns: <!-- TMPL_VAR ESCAPE="HTML" name="function_returns" --></h3> +<h3>Language: <!-- TMPL_VAR ESCAPE="HTML" name="function_language" --></h3> + <!-- TMPL_IF name="function_comment" --><p><!-- TMPL_VAR ESCAPE="HTML" name="function_comment" --></p><!-- /TMPL_IF name="function_comment" --> + <pre><!-- TMPL_IF name="function_source" --><!-- TMPL_VAR ESCAPE="HTML" name="function_source" --><!-- /TMPL_IF name="function_source" --></pre> + <!-- /TMPL_LOOP name="functions" --> + +<!-- /TMPL_LOOP name="schemas" --> +<p class="w3ref">Generated by <a href="http://www.rbt.ca/autodoc/">PostgreSQL Autodoc</a></p> +<p class="w3ref"><a href="http://validator.w3.org/check/referer">W3C HTML 4.01 Strict</a></p> +</body></html> diff --git a/postgresql_autodoc/install-sh b/postgresql_autodoc/install-sh new file mode 100755 index 0000000..398a88e --- /dev/null +++ b/postgresql_autodoc/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/postgresql_autodoc/neato.tmpl b/postgresql_autodoc/neato.tmpl new file mode 100644 index 0000000..b21e067 --- /dev/null +++ b/postgresql_autodoc/neato.tmpl @@ -0,0 +1,22 @@ +digraph g { +node [ fontsize = "10", shape = record ]; +edge []; +<TMPL_LOOP name="schemas"><TMPL_LOOP name="tables"><TMPL_UNLESS +name="view_definition"> +"<TMPL_IF name="number_of_schemas"><TMPL_VAR +name="schema_dot">.</TMPL_IF name="number_of_schemas"><TMPL_VAR +name="table_dot">" [shape = record, label = "{<col0> \N| <TMPL_LOOP +name="columns"><TMPL_VAR name="column_dot">: <TMPL_VAR +name="column_type">\l</TMPL_LOOP name="columns">}" ]; +</TMPL_UNLESS name="view_definition"></TMPL_LOOP +name="tables"></TMPL_LOOP name="schemas"> +<TMPL_LOOP name="fk_links"> +"<TMPL_IF name="number_of_schemas"><TMPL_VAR +name="handle0_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR +name="handle0_name">" -> "<TMPL_IF name="number_of_schemas"><TMPL_VAR +name="handle1_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR +name="handle1_name">" [label="<TMPL_VAR +name="fk_link_name_dot">"];</TMPL_LOOP name="fk_links"> +} + + diff --git a/postgresql_autodoc/postgresql_autodoc b/postgresql_autodoc/postgresql_autodoc new file mode 100755 index 0000000..503a8c5 --- /dev/null +++ b/postgresql_autodoc/postgresql_autodoc @@ -0,0 +1,1907 @@ +#!/usr/bin/perl +# -- # -*- Perl -*-w +# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $ +# Imported 1.22 2002/02/08 17:09:48 into sourceforge + +# Postgres Auto-Doc Version 1.31 + +# License +# ------- +# Copyright (c) 2001-2007, Rod Taylor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# 3. Neither the name of the InQuent Technologies Inc. nor the names +# of its contributors may be used to endorse or promote products +# derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# About Project +# ------------- +# Various details about the project and related items can be found at +# the website +# +# http://www.rbt.ca/autodoc/ + +use strict; +use warnings; + +use DBI; +use Fcntl; + +# Allows file templates +use HTML::Template; + +# Allow reading a password from stdin +use Term::ReadKey; + +sub main($) { + my ($ARGV) = @_; + + my %db; + + # The templates path + # /usr/local/share/postgresql_autodoc will be replaced by make in the build phase + my $template_path = '/usr/local/share/postgresql_autodoc'; + + # Setup the default connection variables based on the environment + my $dbuser = $ENV{'PGUSER'}; + $dbuser ||= $ENV{'USER'}; + + my $database = $ENV{'PGDATABASE'}; + $database ||= $dbuser; + + my $dbhost = $ENV{'PGHOST'}; + $dbhost ||= ""; + + my $dbport = $ENV{'PGPORT'}; + $dbport ||= ""; + + # Determine whether we need a password to connect + my $needpass = 0; + + my $dbpass = ""; + my $output_filename_base = $database; + + # Tracking variables + my $dbisset = 0; + my $fileisset = 0; + + my $only_schema; + + my $table_out; + + my $wanted_output = undef; # means all types + + my $statistics = 0; + + # Fetch base and dirnames. Useful for Usage() + my $basename = $0; + my $dirname = $0; + $basename =~ s|^.*/([^/]+)$|$1|; + $dirname =~ s|^(.*)/[^/]+$|$1|; + + # If template_path isn't defined, lets set it ourselves + $template_path = $dirname if ( !defined($template_path) ); + + for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) { + ARGPARSE: for ( $ARGV[$i] ) { + + # Set the database + /^-d$/ && do { + $database = $ARGV[ ++$i ]; + $dbisset = 1; + if ( !$fileisset ) { + $output_filename_base = $database; + } + last; + }; + + # Set the user + /^-[uU]$/ && do { + $dbuser = $ARGV[ ++$i ]; + if ( !$dbisset ) { + $database = $dbuser; + if ( !$fileisset ) { + $output_filename_base = $database; + } + } + last; + }; + + # Set the hostname + /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; }; + + # Set the Port + /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; }; + + # Set the users password + /^--password=/ && do { + $dbpass = $ARGV[$i]; + $dbpass =~ s/^--password=//g; + last; + }; + + # Make sure we get a password before attempting to conenct + /^--password$/ && do { + $needpass = 1; + last; + }; + + # Set the base of the filename. The extensions pulled + # from the templates will be appended to this name + /^-f$/ && do { + $output_filename_base = $ARGV[ ++$i ]; + $fileisset = 1; + last; + }; + + # Set the template directory explicitly + /^(-l|--library)$/ && do { + $template_path = $ARGV[ ++$i ]; + last; + }; + + # Set the output type + /^(-t|--type)$/ && do { + $wanted_output = $ARGV[ ++$i ]; + last; + }; + + # User has requested a single schema dump and provided a pattern + /^(-s|--schema)$/ && do { + $only_schema = $ARGV[ ++$i ]; + last; + }; + + # One might dump a table's set (comma-separated) or just one + # If dumping a set of specific tables do NOT dump out the functions + # in this database. Generates noise in the output + # that most likely isn't wanted. Check for $table_out around the + # function gathering location. + /^--table=/ && do { + my $some_table = $ARGV[$i]; + $some_table =~ s/^--table=//g; + + my @tables_in = split( ',', $some_table ); + sub single_quote; + $table_out = join( ',', map( single_quote, @tables_in ) ); + + last; + }; + + # Check to see if Statistics have been requested + /^--statistics$/ && do { + $statistics = 1; + last; + }; + + # Help is wanted, redirect user to usage() + /^-\?$/ && do { usage( $basename, $database, $dbuser ); last; }; + /^--help$/ && do { usage( $basename, $database, $dbuser ); last; }; + } + } + + # If no arguments have been provided, connect to the database anyway but + # inform the user of what we're doing. + if ( $#ARGV <= 0 ) { + print <<Msg +No arguments set. Use '$basename --help' for help + +Connecting to database '$database' as user '$dbuser' +Msg + ; + } + + # If needpass has been set but no password was provided, prompt the user + # for a password. + if ( $needpass and not $dbpass ) { + print "Password: "; + ReadMode 'noecho'; + $dbpass = ReadLine 0; + chomp $dbpass; + ReadMode 'normal'; + print "\n"; + } + + # Database Connection + my $dsn = "dbi:Pg:dbname=$database"; + $dsn .= ";host=$dbhost" if ( "$dbhost" ne "" ); + $dsn .= ";port=$dbport" if ( "$dbport" ne "" ); + + info_collect( [ $dsn, $dbuser, $dbpass ], + \%db, $database, $only_schema, $statistics, $table_out ); + + # Write out *ALL* templates + write_using_templates( \%db, $database, $statistics, $template_path, + $output_filename_base, $wanted_output ); +} ## end sub main($) + +## +# info_collect +# +# Pull out all of the applicable information about a specific database +sub info_collect { + my ( $dbConnect, $db, $database, $only_schema, $statistics, $table_out ) = + @_; + + my $dbh = DBI->connect( @{$dbConnect} ) + or triggerError("Unable to connect due to: $DBI::errstr"); + + $dbh->do("set client_encoding to 'UTF-8'") + or triggerError("could not set client_encoding to UTF-8: $DBI::errstr"); + + my %struct; + $db->{$database}{'STRUCT'} = \%struct; + my $struct = $db->{$database}{'STRUCT'}; + + # PostgreSQL's version is used to determine what queries are required + # to retrieve a given information set. + if ( $dbh->{pg_server_version} < 70300 ) { + die("PostgreSQL 7.3 and later are supported"); + } + + # Ensure we only retrieve information for the requested schemas. + # + # system_schema -> The primary system schema for a database. + # Public is used for verions prior to 7.3 + # + # system_schema_list -> The list of schemas which we are not supposed + # to gather information for. + # TODO: Merge with system_schema in array form. + # + # schemapattern -> The schema the user provided as a command + # line option. + my $schemapattern = '^'; + my $system_schema = 'pg_catalog'; + my $system_schema_list = + 'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema'; + if ( defined($only_schema) ) { + $schemapattern = '^' . $only_schema . '$'; + } + + # + # List of queries which are used to gather information from the + # database. The queries differ based on version but should + # provide similar output. At some point it should be safe to remove + # support for older database versions. + # + + # Fetch the description of the database + my $sql_Database = q{ + SELECT pg_catalog.obj_description(oid, 'pg_database') as comment + FROM pg_catalog.pg_database + WHERE datname = '$database'; + }; + + # Pull out a list of tables, views and special structures. + my $sql_Tables = qq{ + SELECT nspname as namespace + , relname as tablename + , pg_catalog.pg_get_userbyid(relowner) AS tableowner + , relhasindex as hasindexes + , relhasrules as hasrules + , reltriggers as hastriggers + , pg_class.oid + , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description + , relacl + , CASE + WHEN relkind = 'r' THEN + 'table' + WHEN relkind = 's' THEN + 'special' + ELSE + 'view' + END as reltype + , CASE + WHEN relkind = 'v' THEN + pg_get_viewdef(pg_class.oid) + ELSE + NULL + END as view_definition + FROM pg_catalog.pg_class + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE relkind IN ('r', 's', 'v') + AND nspname !~ '$system_schema_list' + AND nspname ~ '$schemapattern' + }; + $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out); + + # - uses pg_class.oid + my $sql_Columns = q{ + SELECT attname as column_name + , attlen as column_length + , CASE + WHEN pg_type.typname = 'int4' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'serial' + WHEN pg_type.typname = 'int8' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'bigserial' + ELSE + pg_catalog.format_type(atttypid, atttypmod) + END as column_type + , CASE + WHEN attnotnull THEN + cast('NOT NULL' as text) + ELSE + cast('' as text) + END as column_null + , CASE + WHEN pg_type.typname IN ('int4', 'int8') + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + NULL + ELSE + adsrc + END as column_default + , pg_catalog.col_description(attrelid, attnum) as column_description + , attnum + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid) + LEFT JOIN pg_catalog.pg_attrdef ON ( attrelid = adrelid + AND attnum = adnum) + WHERE attnum > 0 + AND attisdropped IS FALSE + AND attrelid = ?; + }; + + my $sql_Table_Statistics; + if ( $statistics == 1 ) { + if ( $dbh->{pg_server_version} <= 70300 ) { + triggerError( + "Table statistics supported on PostgreSQL 7.4 and later.\n" + . "Remove --statistics flag and try again." ); + } + + $sql_Table_Statistics = q{ + SELECT table_len + , tuple_count + , tuple_len + , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent + , dead_tuple_count + , dead_tuple_len + , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent + , CAST(free_space AS numeric(20,2)) AS free_space + , CAST(free_percent AS numeric(20,2)) AS free_percent + FROM pgstattuple(CAST(? AS oid)); + }; + } + + my $sql_Indexes = q{ + SELECT schemaname + , tablename + , indexname + , substring( indexdef + FROM position('(' IN indexdef) + 1 + FOR length(indexdef) - position('(' IN indexdef) - 1 + ) AS indexdef + FROM pg_catalog.pg_indexes + WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE' + AND schemaname = ? + AND tablename = ?; + }; + + my $sql_Inheritance = qq{ + SELECT parnsp.nspname AS par_schemaname + , parcla.relname AS par_tablename + , chlnsp.nspname AS chl_schemaname + , chlcla.relname AS chl_tablename + FROM pg_catalog.pg_inherits + JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid) + JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace) + JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent) + JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace) + WHERE chlnsp.nspname = ? + AND chlcla.relname = ? + AND chlnsp.nspname ~ '$schemapattern' + AND parnsp.nspname ~ '$schemapattern'; + }; + + # Fetch the list of PRIMARY and UNIQUE keys + my $sql_Primary_Keys = q{ + SELECT conname AS constraint_name + , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition + , CASE + WHEN contype = 'p' THEN + 'PRIMARY KEY' + ELSE + 'UNIQUE' + END as constraint_type + FROM pg_catalog.pg_constraint AS c + JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid) + WHERE contype IN ('p', 'u') + AND deptype = 'i' + AND conrelid = ?; + }; + + # FOREIGN KEY fetch + # + # Don't return the constraint name if it was automatically generated by + # PostgreSQL. The $N (where N is an integer) is not a descriptive enough + # piece of information to be worth while including in the various outputs. + my $sql_Foreign_Keys = qq{ + SELECT pg_constraint.oid + , pg_namespace.nspname AS namespace + , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN '' + ELSE pg_constraint.conname + END AS constraint_name + , conkey AS constraint_key + , confkey AS constraint_fkey + , confrelid AS foreignrelid + FROM pg_catalog.pg_constraint + JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid) + JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid) + JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) + JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace) + WHERE contype = 'f' + AND conrelid = ? + AND pg_namespace.nspname ~ '$schemapattern' + AND pn.nspname ~ '$schemapattern'; + }; + + my $sql_Foreign_Key_Arg = q{ + SELECT attname AS attribute_name + , relname AS relation_name + , nspname AS namespace + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid) + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE attrelid = ? + AND attnum = ?; + }; + + # Fetch CHECK constraints + my $sql_Constraint; + if ( $dbh->{pg_server_version} >= 70400 ) { + $sql_Constraint = q{ + SELECT pg_get_constraintdef(oid) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + else { + $sql_Constraint = q{ + SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + + # Query for function information + my $sql_Function; + my $sql_FunctionArg; + if ( $dbh->{pg_server_version} >= 80000 ) { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , proargnames AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + else { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , NULL AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + + # Fetch schema information. + my $sql_Schema = qq{ + SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment + , nspname as namespace + FROM pg_catalog.pg_namespace + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern'; + }; + + my $sth_Columns = $dbh->prepare($sql_Columns); + my $sth_Constraint = $dbh->prepare($sql_Constraint); + my $sth_Database = $dbh->prepare($sql_Database); + my $sth_Foreign_Keys = $dbh->prepare($sql_Foreign_Keys); + my $sth_Foreign_Key_Arg = $dbh->prepare($sql_Foreign_Key_Arg); + my $sth_Function = $dbh->prepare($sql_Function); + my $sth_FunctionArg = $dbh->prepare($sql_FunctionArg); + my $sth_Indexes = $dbh->prepare($sql_Indexes); + my $sth_Inheritance = $dbh->prepare($sql_Inheritance); + my $sth_Primary_Keys = $dbh->prepare($sql_Primary_Keys); + my $sth_Schema = $dbh->prepare($sql_Schema); + my $sth_Tables = $dbh->prepare($sql_Tables); + my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics) + if ( $statistics == 1 ); + + # Fetch Database info + $sth_Database->execute(); + my $dbinfo = $sth_Database->fetchrow_hashref; + if ( defined($dbinfo) ) { + $db->{$database}{'COMMENT'} = $dbinfo->{'comment'}; + } + + # Fetch tables and all things bound to tables + $sth_Tables->execute(); + while ( my $tables = $sth_Tables->fetchrow_hashref ) { + my $reloid = $tables->{'oid'}; + my $relname = $tables->{'tablename'}; + + my $schema = $tables->{'namespace'}; + + EXPRESSIONFOUND: + + # Store permissions + my $acl = $tables->{'relacl'}; + + # Empty acl groups cause serious issues. + $acl ||= ''; + + # Strip array forming 'junk'. + $acl =~ s/^{//g; + $acl =~ s/}$//g; + $acl =~ s/"//g; + + # Foreach acl + foreach ( split( /\,/, $acl ) ) { + my ( $user, $raw_permissions ) = split( /=/, $_ ); + + if ( defined($raw_permissions) ) { + if ( $user eq '' ) { + $user = 'PUBLIC'; + } + + # The section after the / is the user who granted the permissions + my ( $permissions, $granting_user ) = + split( /\//, $raw_permissions ); + + # Break down permissions to individual flags + if ( $permissions =~ /a/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'INSERT'} = 1; + } + + if ( $permissions =~ /r/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'SELECT'} = 1; + } + + if ( $permissions =~ /w/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'UPDATE'} = 1; + } + + if ( $permissions =~ /d/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'DELETE'} = 1; + } + + if ( $permissions =~ /R/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'RULE'} = 1; + } + + if ( $permissions =~ /x/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'REFERENCES'} = 1; + } + + if ( $permissions =~ /t/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'TRIGGER'} = 1; + } + } + } + + # Primitive Stats, but only if requested + if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) { + $sth_Table_Statistics->execute($reloid); + + my $stats = $sth_Table_Statistics->fetchrow_hashref; + + $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} = + $stats->{'table_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} = + $stats->{'tuple_count'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} = + $stats->{'tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} = + $stats->{'dead_tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} = + $stats->{'free_space'}; + } + + # Store the relation type + $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'}; + + # Store table description + $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} = + $tables->{'table_description'}; + + # Store the view definition + $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} = + $tables->{'view_definition'}; + + # Store constraints + $sth_Constraint->execute($reloid); + while ( my $cols = $sth_Constraint->fetchrow_hashref ) { + my $constraint_name = $cols->{'constraint_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'} + {$constraint_name} = $cols->{'constraint_source'}; + } + + $sth_Columns->execute($reloid); + my $i = 1; + while ( my $cols = $sth_Columns->fetchrow_hashref ) { + my $column_name = $cols->{'column_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'ORDER'} = $cols->{'attnum'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'PRIMARY KEY'} = 0; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'FKTABLE'} = ''; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'TYPE'} = $cols->{'column_type'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'NULL'} = $cols->{'column_null'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DESCRIPTION'} = $cols->{'column_description'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DEFAULT'} = $cols->{'column_default'}; + } + + # Pull out both PRIMARY and UNIQUE keys based on the supplied query + # and the relation OID. + # + # Since there may be multiple UNIQUE indexes on a table, we append a + # number to the end of the the UNIQUE keyword which shows that they + # are a part of a related definition. I.e UNIQUE_1 goes with UNIQUE_1 + # + $sth_Primary_Keys->execute($reloid); + my $unqgroup = 0; + while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) { + my $index_type = $pricols->{'constraint_type'}; + my $con = $pricols->{'constraint_name'}; + my $indexdef = $pricols->{'constraint_definition'}; + + # Fetch the column list + my $column_list = $indexdef; + $column_list =~ s/.*\(([^)]+)\).*/$1/g; + + # Split our column list and deal with all PRIMARY KEY fields + my @collist = split( ',', $column_list ); + + # Store the column number in the indextype field. Anything > 0 + # indicates the column has this type of constraint applied to it. + my $column; + my $currentcol = $#collist + 1; + my $numcols = $#collist + 1; + + # Bump group number if there are two or more columns + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $unqgroup++; + } + + # Record the data to the structure. + while ( $column = pop(@collist) ) { + $column =~ s/\s$//; + $column =~ s/^\s//; + $column =~ s/^"//; + $column =~ s/"$//; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = $index_type; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $unqgroup; + } + } + } + + # FOREIGN KEYS like UNIQUE indexes can appear several times in + # a table in multi-column format. We use the same trick to + # record a numeric association to the foreign key reference. + $sth_Foreign_Keys->execute($reloid); + my $fkgroup = 0; + while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) { + my $column_oid = $forcols->{'oid'}; + my $con = $forcols->{'constraint_name'}; + + # Declare variables for dataload + my @keylist; + my @fkeylist; + my $fschema; + my $ftable; + + my $fkey = $forcols->{'constraint_fkey'}; + my $keys = $forcols->{'constraint_key'}; + my $frelid = $forcols->{'foreignrelid'}; + + # Since decent array support was not added until 7.4, and + # we want to support 7.3 as well, we parse the text version + # of the array by hand rather than combining this and + # Foreign_Key_Arg query into a single query. + + my @fkeyset; + if ( ref $fkey eq 'ARRAY' ) { + @fkeyset = @{$fkey}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $fkey =~ s/^{//g; + $fkey =~ s/}$//g; + $fkey =~ s/"//g; + @fkeyset = split( /,/, $fkey ); + } + + my @keyset; + if ( ref $keys eq 'ARRAY' ) { + @keyset = @{$keys}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $keys =~ s/^{//g; + $keys =~ s/}$//g; + $keys =~ s/"//g; + @keyset = split( /,/, $keys ); + } + + # Convert the list of column numbers into column names for the + # local side. + foreach my $k (@keyset) { + $sth_Foreign_Key_Arg->execute( $reloid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @keylist, $row->{'attribute_name'} ); + } + + # Convert the list of columns numbers into column names + # for the referenced side. Grab the table and namespace + # while we're here. + foreach my $k (@fkeyset) { + $sth_Foreign_Key_Arg->execute( $frelid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @fkeylist, $row->{'attribute_name'} ); + $fschema = $row->{'namespace'}; + $ftable = $row->{'relation_name'}; + } + + # Deal with common catalog issues. + die "FKEY $con Broken -- fix your PostgreSQL installation" + if $#keylist != $#fkeylist; + + # Load up the array based on the information discovered + # using the information retrieval methods above. + my $numcols = $#keylist + 1; + my $currentcol = $#keylist + 1; + + # Bump group number if there are two or more columns involved + if ( $numcols >= 2 ) { + $fkgroup++; + } + + # Record the foreign key to structure + while ( my $column = pop(@keylist) + and my $fkey = pop(@fkeylist) ) + { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = 'FOREIGN KEY'; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKTABLE'} = $ftable; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKSCHEMA'} = $fschema; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FK-COL NAME'} = $fkey; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $fkgroup; + } + } + } + + # Pull out index information + $sth_Indexes->execute( $schema, $relname ); + while ( my $idx = $sth_Indexes->fetchrow_hashref ) { + $struct->{$schema}{'TABLE'}{$relname}{'INDEX'} + { $idx->{'indexname'} } = $idx->{'indexdef'}; + } + + # Extract Inheritance information + $sth_Inheritance->execute( $schema, $relname ); + while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) { + my $parSch = $inherit->{'par_schemaname'}; + my $parTab = $inherit->{'par_tablename'}; + $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} = + 1; + } + } + + # Function Handling + $sth_Function->execute(); + while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out ) + { + my $functionname = $functions->{'function_name'} . '( '; + my $schema = $functions->{'namespace'}; + my $comment = $functions->{'comment'}; + my $functionargs = $functions->{'function_args'}; + my @types = split( ' ', $functionargs ); + my $count = 0; + + # Pre-setup argument names when available. + my $argnames = $functions->{'function_arg_names'}; + my @names; + + if ( defined($argnames) ) { + $argnames =~ s/{(.*)}/$1/; + @names = split( ',', $argnames ); + } + + # Setup full argument types -- including the name prefix + foreach my $type (@types) { + $sth_FunctionArg->execute($type); + + my $hash = $sth_FunctionArg->fetchrow_hashref; + + if ( $count > 0 ) { + $functionname .= ', '; + } + + if ( scalar(@names) > 0 ) { + $functionname .= $names[$count] . ' '; + } + + if ( $hash->{'namespace'} ne $system_schema ) { + $functionname .= $hash->{'namespace'} . '.'; + } + $functionname .= $hash->{'type_name'}; + + $count++; + } + $functionname .= ' )'; + + my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : ''; + $sth_FunctionArg->execute( $functions->{'return_type'} ); + my $rhash = $sth_FunctionArg->fetchrow_hashref; + $ret_type .= $rhash->{'type_name'}; + + $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment; + $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} = + $functions->{'source_code'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} = + $functions->{'language_name'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type; + } + + # Deal with the Schema + $sth_Schema->execute(); + while ( my $schema = $sth_Schema->fetchrow_hashref ) { + my $comment = $schema->{'comment'}; + my $namespace = $schema->{'namespace'}; + + $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment; + } + + $sth_Columns->finish(); + $sth_Constraint->finish(); + $sth_Database->finish(); + $sth_Foreign_Keys->finish(); + $sth_Foreign_Key_Arg->finish(); + $sth_Function->finish(); + $sth_FunctionArg->finish(); + $sth_Indexes->finish(); + $sth_Inheritance->finish(); + $sth_Primary_Keys->finish(); + $sth_Schema->finish(); + $sth_Tables->finish(); + $sth_Table_Statistics->finish() + if ( $statistics == 1 ); + + $dbh->disconnect; + +} ## end sub info_collect($$$$$) + +##### +# write_using_templates +# +# Generate structure that HTML::Template requires out of the +# $struct for table related information, and $struct for +# the schema and function information +sub write_using_templates($$$$$) { + my ( $db, $database, $statistics, $template_path, $output_filename_base, + $wanted_output ) + = @_; + my $struct = $db->{$database}{'STRUCT'}; + + my @schemas; + + # Start at 0, increment to 1 prior to use. + my $object_id = 0; + my %tableids; + foreach my $schema ( sort keys %{$struct} ) { + my @tables; + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + + # Column List + my @columns; + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + my $inferrednotnull = 0; + + # Have a shorter default for places that require it + my $shortdefault = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}; + $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g + if ( defined($shortdefault) ); + + # Deal with column constraints + my @colconstraints; + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'UNIQUE' ) + { + my $unq = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'}; + my $unqcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'COLNUM'}; + my $unqgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + + push @colconstraints, + { + column_unique => $unq, + column_unique_colnum => $unqcol, + column_unique_keygroup => $unqgroup, + }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' ) + { + $inferrednotnull = 1; + push @colconstraints, + { column_primary_key => 'PRIMARY KEY', }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKSCHEMA'}, + $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKTABLE'} ) + ); + + my $fkgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + my $fktable = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $fkcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + my $fkschema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + + push @colconstraints, + { + column_fk => 'FOREIGN KEY', + column_fk_colnum => $fkcol, + column_fk_keygroup => $fkgroup, + column_fk_schema => $fkschema, + column_fk_schema_dbk => docbook($fkschema), + column_fk_schema_dot => graphviz($fkschema), + column_fk_sgmlid => $fksgmlid, + column_fk_table => $fktable, + column_fk_table_dbk => docbook($fktable), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $colconstraints[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + + # Generate the Column array + push @columns, { + column => $column, + column_dbk => docbook($column), + column_dot => graphviz($column), + column_default => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}, + column_default_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'} + ), + column_default_short => $shortdefault, + column_default_short_dbk => docbook($shortdefault), + + column_comment => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'}, + column_comment_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'} + ), + + column_number => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'ORDER'}, + + column_type => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'}, + column_type_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + column_type_dot => graphviz( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + + column_constraints => \@colconstraints, + }; + + if ( $inferrednotnull == 0 ) { + $columns[-1]{"column_constraint_notnull"} = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'NULL'}; + } + } + + # Constraint List + my @constraints; + foreach my $constraint ( + sort + keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} } + ) + { + my $shortcon = + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}; + $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g; + push @constraints, + { + constraint => + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}, + constraint_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint} + ), + constraint_name => $constraint, + constraint_name_dbk => docbook($constraint), + constraint_short => $shortcon, + constraint_short_dbk => docbook($shortcon), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + }; + } + + # Index List + my @indexes; + foreach my $index ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } ) + { + push @indexes, + { + index_definition => + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}, + index_definition_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index} + ), + index_name => $index, + index_name_dbk => docbook($index), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + }; + } + + my @inherits; + foreach my $inhSch ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } ) + { + foreach my $inhTab ( + sort keys + %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} } + ) + { + push @inherits, + { + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + sgmlid => + sgml_safe_id( join( '.', $schema, 'table', $table ) ), + parent_sgmlid => sgml_safe_id( + join( '.', $inhSch, 'table', $inhTab ) + ), + parent_table => $inhTab, + parent_table_dbk => docbook($inhTab), + parent_table_dot => graphviz($inhTab), + parent_schema => $inhSch, + parent_schema_dbk => docbook($inhSch), + parent_schema_dot => graphviz($inhSch), + }; + } + } + + # Foreign Key Discovery + # + # $lastmatch is used to ensure that we only supply a result a + # single time and not once for each link found. Since the + # loops are sorted, we only need to track the last element, and + # not all supplied elements. + my @fk_schemas; + my $lastmatch = ''; + foreach my $fk_schema ( sort keys %{$struct} ) { + foreach + my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } ) + { + foreach my $fk_column ( + sort keys + %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} } + ) + { + foreach my $fk_con ( + sort keys %{ + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'} + } + ) + { + if ( $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'} + eq 'FOREIGN KEY' + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKTABLE'} eq $table + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKSCHEMA'} eq $schema + and $lastmatch ne "$fk_schema$fk_table" ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $fk_schema, + $struct->{$fk_schema}{'TABLE'} + {$fk_table}{'TYPE'}, + $fk_table ) + ); + push @fk_schemas, + { + fk_column_number => + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'ORDER'}, + fk_sgmlid => $fksgmlid, + fk_schema => $fk_schema, + fk_schema_dbk => docbook($fk_schema), + fk_schema_dot => graphviz($fk_schema), + fk_table => $fk_table, + fk_table_dbk => docbook($fk_table), + fk_table_dot => graphviz($fk_table), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_schemas[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + $lastmatch = "$fk_schema$fk_table"; + } + } + } + } + } + + # List off permissions + my @permissions; + foreach my $user ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } ) + { + push @permissions, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + user => $user, + user_dbk => docbook($user), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $permissions[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + foreach my $perm ( + keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} + {$perm} == 1 ) + { + $permissions[-1]{ lower($perm) } = 1; + } + } + + } + + # Increment and record the object ID + $tableids{"$schema$table"} = ++$object_id; + my $viewdef = sql_prettyprint( + $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} ); + + # Truncate comment for Dia + my $comment_dia = + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}; + $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g + if ( defined($comment_dia) ); + + push @tables, { + object_id => $object_id, + object_id_dbk => docbook($object_id), + + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + + # Statistics + stats_enabled => $statistics, + stats_dead_bytes => useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ), + stats_dead_bytes_dbk => docbook( + useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ) + ), + stats_free_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ), + stats_free_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ) + ), + stats_table_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ), + stats_table_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ) + ), + stats_tuple_count => + $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'}, + stats_tuple_count_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ), + stats_tuple_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ), + stats_tuple_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ) + ), + + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + table_sgmlid => sgml_safe_id( + join( '.', + $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $table ) + ), + table_comment => + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}, + table_comment_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ), + table_comment_dia => $comment_dia, + view_definition => $viewdef, + view_definition_dbk => docbook($viewdef), + columns => \@columns, + constraints => \@constraints, + fk_schemas => \@fk_schemas, + indexes => \@indexes, + inherits => \@inherits, + permissions => \@permissions, + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Dump out list of functions + my @functions; + foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) { + push @functions, + { + function => $function, + function_dbk => docbook($function), + function_sgmlid => + sgml_safe_id( join( '.', $schema, 'function', $function ) ), + function_comment => + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}, + function_comment_dbk => docbook( + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'} + ), + function_language => + uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ), + function_returns => + $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'}, + function_source => + $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'}, + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + push @schemas, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'}, + schema_comment_dbk => + docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ), + functions => \@functions, + tables => \@tables, + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Link the various components together via the template. + my @fk_links; + my @fkeys; + foreach my $schema ( sort keys %{$struct} ) { + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } + keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + + # To prevent a multi-column foreign key from appearing + # several times, we've opted + # to simply display the first column of any given key. + # Since column numbering always starts at 1 + # for foreign keys. + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' + && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'COLNUM'} == 1 ) + { + + # Pull out some of the longer keys + my $ref_table = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $ref_schema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + my $ref_column = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + + # Default values cause these elements to attach + # to the bottom in Dia + # If a KEYGROUP is not defined, it's a single column. + # Modify the ref_con and key_con variables to attach + # the to the columns connection point directly. + my $ref_con = 0; + my $key_con = 0; + my $keycon_offset = 0; + if ( + !defined( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'KEYGROUP'} + ) + ) + { + $ref_con = + $struct->{$ref_schema}{'TABLE'}{$ref_table} + {'COLUMN'}{$ref_column}{'ORDER'} || 0; + $key_con = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'ORDER'} || 0; + $keycon_offset = 1; + } + + # Bump object_id + $object_id++; + + push @fk_links, + { + fk_link_name => $con, + fk_link_name_dbk => docbook($con), + fk_link_name_dot => graphviz($con), + handle0_connection => $key_con, + handle0_connection_dbk => docbook($key_con), + handle0_connection_dia => 6 + ( $key_con * 2 ), + handle0_name => $table, + handle0_name_dbk => docbook($table), + handle0_schema => $schema, + handle0_to => $tableids{"$schema$table"}, + handle0_to_dbk => + docbook( $tableids{"$schema$table"} ), + handle1_connection => $ref_con, + handle1_connection_dbk => docbook($ref_con), + handle1_connection_dia => 6 + + ( $ref_con * 2 ) + + $keycon_offset, + handle1_name => $ref_table, + handle1_name_dbk => docbook($ref_table), + handle1_schema => $ref_schema, + handle1_to => $tableids{"$ref_schema$ref_table"}, + handle1_to_dbk => + docbook( $tableids{"$ref_schema$ref_table"} ), + object_id => $object_id, + object_id_dbk => docbook($object_id), + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_links[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + } + } + } + + # Make database level comment information + my @timestamp = localtime(); + my $dumped_on = sprintf( "%04d-%02d-%02d", + $timestamp[5] + 1900, + $timestamp[4] + 1, + $timestamp[3] ); + my $database_comment = $db->{$database}{'COMMENT'}; + + # Loop through each template found in the supplied path. + # Output the results of the template as <filename>.<extension> + # into the current working directory. + my @template_files = glob( $template_path . '/*.tmpl' ); + + # Ensure we've told the user if we don't find any files. + triggerError("Templates files not found in $template_path") + if ( $#template_files < 0 ); + + # Process all found templates. + foreach my $template_file (@template_files) { + ( my $file_extension = $template_file ) =~ + s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/; + next + if ( defined($wanted_output) && $file_extension ne $wanted_output ); + my $output_filename = "$output_filename_base.$file_extension"; + print "Producing $output_filename from $template_file\n"; + + my $template = HTML::Template->new( + filename => $template_file, + die_on_bad_params => 0, + global_vars => 0, + strict => 1, + loop_context_vars => 1 + ); + + $template->param( + database => $database, + database_dbk => docbook($database), + database_sgmlid => sgml_safe_id($database), + database_comment => $database_comment, + database_comment_dbk => docbook($database_comment), + dumped_on => $dumped_on, + dumped_on_dbk => docbook($dumped_on), + fk_links => \@fk_links, + schemas => \@schemas, + ); + + sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 ) + or die "Can't open $output_filename: $!"; + print FH $template->output(); + } +} ## end sub write_using_templates($$$$$) + +###### +# sgml_safe_id +# Safe SGML ID Character replacement +sub sgml_safe_id($) { + my $string = shift; + + # Lets use the keyword ARRAY in place of the square brackets + # to prevent duplicating a non-array equivelent + $string =~ s/\[\]/ARRAY-/g; + + # Brackets, spaces, commads, underscores are not valid 'id' characters + # replace with as few -'s as possible. + $string =~ s/[ "',)(_-]+/-/g; + + # Don't want a - at the end either. It looks silly. + $string =~ s/-$//g; + + return ($string); +} + +##### +# lower +# LowerCase the string +sub lower($) { + my $string = shift; + + $string =~ tr/A-Z/a-z/; + + return ($string); +} + +##### +# useUnits +# Tack on base 2 metric units +sub useUnits($) { + my ($value) = @_; + + return '' if ( !defined($value) ); + + my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' ); + my $loop = 0; + + while ( $value >= 1024 ) { + $loop++; + + $value = $value / 1024; + } + + return ( sprintf( "%.2f %s", $value, $units[$loop] ) ); +} + +##### +# docbook +# Docbook output is special in that we may or may not want to escape +# the characters inside the string depending on a string prefix. +sub docbook($) { + my $string = shift; + + if ( defined($string) ) { + if ( $string =~ /^\@DOCBOOK/ ) { + $string =~ s/^\@DOCBOOK//; + } + else { + $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&/g; + $string =~ s/</</g; + $string =~ s/>/>/g; + $string =~ s/'/'/g; + $string =~ s/"/"/g; + } + } + else { + + # Return an empty string when all else fails + $string = ''; + } + + return ($string); +} + +##### +# graphviz +# GraphViz output requires that special characters (like " and whitespace) must be preceeded +# by a \ when a part of a lable. +sub graphviz($) { + my $string = shift; + + # Ensure we don't return an least a empty string + $string = '' if ( !defined($string) ); + + $string =~ s/([\s"'])/\\$1/g; + + return ($string); +} + +##### +# sql_prettyprint +# Clean up SQL into something presentable +sub sql_prettyprint($) { + my $string = shift; + + # If nothing has been sent in, return an empty string + if ( !defined($string) ) { + return ''; + } + + # Initialize Result string + my $result = ''; + + # List of tokens to split on + my $tok = + "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN" + . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN" + . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]"; + + my $key = 0; + my $bracket = 0; + my $depth = 0; + my $indent = 6; + + # XXX: Split is wrong -- match would do + foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) { + my $format; + + # Skip junk tokens + if ( $elem =~ /^[\s]?$/ ) { + next; + } + + # NOTE: Should we drop leading spaces? + # $elem =~ s/^\s//; + + # Close brackets are special + # Bring depth in a level + if ( $elem =~ /\)/ ) { + $depth = $depth - $indent; + if ( $key == 1 or $bracket == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 0; + $bracket = 0; + } + + # Open brackets are special + # Bump depth out a level + elsif ( $elem =~ /\(/ ) { + if ( $key == 1 ) { + $format = "%s %s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + $depth = $depth + $indent; + $bracket = 1; + $key = 0; + } + + # Key element + # Token from our list -- format on left hand side of the equation + # when appropriate. + elsif ( $elem =~ /$tok/ ) { + if ( $key == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 1; + $bracket = 0; + } + + # Value + # Format for right hand side of the equation + else { + $format = "%s%s"; + + $key = 0; + } + + # Add the new format string to the result + $result = sprintf( $format, $result, $elem ); + } + + return $result; +} ## end sub sql_prettyprint($) + +## +# triggerError +# Print out a supplied error message and exit the script. +sub triggerError($) { + my ($error) = @_; + + # Test error + if ( !defined($error) || $error eq '' ) { + + # Suppress prototype checking in call to self + &triggerError("triggerError: Unknown error"); + } + printf( "\n\n%s\n", $error ); + + exit 2; +} + +##### +# usage +sub usage($$$) { + my ( $basename, $database, $dbuser ) = @_; + print <<USAGE +Usage: + $basename [options] [dbname [username]] + +Options: + -d <dbname> Specify database name to connect to (default: $database) + -f <file> Specify output file prefix (default: $database) + -h <host> Specify database server host (default: localhost) + -p <port> Specify database server port (default: 5432) + -u <username> Specify database username (default: $dbuser) + --password=<pw> Specify database password (default: blank) + --password Have $basename prompt for a password + + -l <path> Path to the templates (default: /usr/local/share/postgresql_autodoc) + -t <output> Type of output wanted (default: All in template library) + + -s <schema> Specify a specific schema to match. Technically this is a regular + expression but anything other than a specific name may have unusual + results. + --table=<args> Tables to export. Multiple tables may be provided using a + comma-separated list. + + --statistics In 7.4 and later, with the contrib module pgstattuple installed we + can gather statistics on the tables in the database + (average size, free space, disk space used, dead tuple counts, etc.) + This is disk intensive on large databases as all pages must be visited. +USAGE + ; + exit 1; +} + +sub single_quote { + my $attr = $_; + $attr =~ s/^\s+|\s+$//g; + return qq{'$attr'}; +} + +## +# Kick off execution of main() +main($ARGV); + diff --git a/postgresql_autodoc/postgresql_autodoc.pl b/postgresql_autodoc/postgresql_autodoc.pl new file mode 100755 index 0000000..fa8ac96 --- /dev/null +++ b/postgresql_autodoc/postgresql_autodoc.pl @@ -0,0 +1,1907 @@ +#!/usr/bin/env perl +# -- # -*- Perl -*-w +# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $ +# Imported 1.22 2002/02/08 17:09:48 into sourceforge + +# Postgres Auto-Doc Version 1.31 + +# License +# ------- +# Copyright (c) 2001-2007, Rod Taylor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# 3. Neither the name of the InQuent Technologies Inc. nor the names +# of its contributors may be used to endorse or promote products +# derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD +# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# About Project +# ------------- +# Various details about the project and related items can be found at +# the website +# +# http://www.rbt.ca/autodoc/ + +use strict; +use warnings; + +use DBI; +use Fcntl; + +# Allows file templates +use HTML::Template; + +# Allow reading a password from stdin +use Term::ReadKey; + +sub main($) { + my ($ARGV) = @_; + + my %db; + + # The templates path + # @@TEMPLATE-DIR@@ will be replaced by make in the build phase + my $template_path = '@@TEMPLATE-DIR@@'; + + # Setup the default connection variables based on the environment + my $dbuser = $ENV{'PGUSER'}; + $dbuser ||= $ENV{'USER'}; + + my $database = $ENV{'PGDATABASE'}; + $database ||= $dbuser; + + my $dbhost = $ENV{'PGHOST'}; + $dbhost ||= ""; + + my $dbport = $ENV{'PGPORT'}; + $dbport ||= ""; + + # Determine whether we need a password to connect + my $needpass = 0; + + my $dbpass = ""; + my $output_filename_base = $database; + + # Tracking variables + my $dbisset = 0; + my $fileisset = 0; + + my $only_schema; + + my $table_out; + + my $wanted_output = undef; # means all types + + my $statistics = 0; + + # Fetch base and dirnames. Useful for Usage() + my $basename = $0; + my $dirname = $0; + $basename =~ s|^.*/([^/]+)$|$1|; + $dirname =~ s|^(.*)/[^/]+$|$1|; + + # If template_path isn't defined, lets set it ourselves + $template_path = $dirname if ( !defined($template_path) ); + + for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) { + ARGPARSE: for ( $ARGV[$i] ) { + + # Set the database + /^-d$/ && do { + $database = $ARGV[ ++$i ]; + $dbisset = 1; + if ( !$fileisset ) { + $output_filename_base = $database; + } + last; + }; + + # Set the user + /^-[uU]$/ && do { + $dbuser = $ARGV[ ++$i ]; + if ( !$dbisset ) { + $database = $dbuser; + if ( !$fileisset ) { + $output_filename_base = $database; + } + } + last; + }; + + # Set the hostname + /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; }; + + # Set the Port + /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; }; + + # Set the users password + /^--password=/ && do { + $dbpass = $ARGV[$i]; + $dbpass =~ s/^--password=//g; + last; + }; + + # Make sure we get a password before attempting to conenct + /^--password$/ && do { + $needpass = 1; + last; + }; + + # Set the base of the filename. The extensions pulled + # from the templates will be appended to this name + /^-f$/ && do { + $output_filename_base = $ARGV[ ++$i ]; + $fileisset = 1; + last; + }; + + # Set the template directory explicitly + /^(-l|--library)$/ && do { + $template_path = $ARGV[ ++$i ]; + last; + }; + + # Set the output type + /^(-t|--type)$/ && do { + $wanted_output = $ARGV[ ++$i ]; + last; + }; + + # User has requested a single schema dump and provided a pattern + /^(-s|--schema)$/ && do { + $only_schema = $ARGV[ ++$i ]; + last; + }; + + # One might dump a table's set (comma-separated) or just one + # If dumping a set of specific tables do NOT dump out the functions + # in this database. Generates noise in the output + # that most likely isn't wanted. Check for $table_out around the + # function gathering location. + /^--table=/ && do { + my $some_table = $ARGV[$i]; + $some_table =~ s/^--table=//g; + + my @tables_in = split( ',', $some_table ); + sub single_quote; + $table_out = join( ',', map( single_quote, @tables_in ) ); + + last; + }; + + # Check to see if Statistics have been requested + /^--statistics$/ && do { + $statistics = 1; + last; + }; + + # Help is wanted, redirect user to usage() + /^-\?$/ && do { usage( $basename, $database, $dbuser ); last; }; + /^--help$/ && do { usage( $basename, $database, $dbuser ); last; }; + } + } + + # If no arguments have been provided, connect to the database anyway but + # inform the user of what we're doing. + if ( $#ARGV <= 0 ) { + print <<Msg +No arguments set. Use '$basename --help' for help + +Connecting to database '$database' as user '$dbuser' +Msg + ; + } + + # If needpass has been set but no password was provided, prompt the user + # for a password. + if ( $needpass and not $dbpass ) { + print "Password: "; + ReadMode 'noecho'; + $dbpass = ReadLine 0; + chomp $dbpass; + ReadMode 'normal'; + print "\n"; + } + + # Database Connection + my $dsn = "dbi:Pg:dbname=$database"; + $dsn .= ";host=$dbhost" if ( "$dbhost" ne "" ); + $dsn .= ";port=$dbport" if ( "$dbport" ne "" ); + + info_collect( [ $dsn, $dbuser, $dbpass ], + \%db, $database, $only_schema, $statistics, $table_out ); + + # Write out *ALL* templates + write_using_templates( \%db, $database, $statistics, $template_path, + $output_filename_base, $wanted_output ); +} ## end sub main($) + +## +# info_collect +# +# Pull out all of the applicable information about a specific database +sub info_collect { + my ( $dbConnect, $db, $database, $only_schema, $statistics, $table_out ) = + @_; + + my $dbh = DBI->connect( @{$dbConnect} ) + or triggerError("Unable to connect due to: $DBI::errstr"); + + $dbh->do("set client_encoding to 'UTF-8'") + or triggerError("could not set client_encoding to UTF-8: $DBI::errstr"); + + my %struct; + $db->{$database}{'STRUCT'} = \%struct; + my $struct = $db->{$database}{'STRUCT'}; + + # PostgreSQL's version is used to determine what queries are required + # to retrieve a given information set. + if ( $dbh->{pg_server_version} < 70300 ) { + die("PostgreSQL 7.3 and later are supported"); + } + + # Ensure we only retrieve information for the requested schemas. + # + # system_schema -> The primary system schema for a database. + # Public is used for verions prior to 7.3 + # + # system_schema_list -> The list of schemas which we are not supposed + # to gather information for. + # TODO: Merge with system_schema in array form. + # + # schemapattern -> The schema the user provided as a command + # line option. + my $schemapattern = '^'; + my $system_schema = 'pg_catalog'; + my $system_schema_list = + 'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema'; + if ( defined($only_schema) ) { + $schemapattern = '^' . $only_schema . '$'; + } + + # + # List of queries which are used to gather information from the + # database. The queries differ based on version but should + # provide similar output. At some point it should be safe to remove + # support for older database versions. + # + + # Fetch the description of the database + my $sql_Database = q{ + SELECT pg_catalog.obj_description(oid, 'pg_database') as comment + FROM pg_catalog.pg_database + WHERE datname = '$database'; + }; + + # Pull out a list of tables, views and special structures. + my $sql_Tables = qq{ + SELECT nspname as namespace + , relname as tablename + , pg_catalog.pg_get_userbyid(relowner) AS tableowner + , relhasindex as hasindexes + , relhasrules as hasrules + , reltriggers as hastriggers + , pg_class.oid + , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description + , relacl + , CASE + WHEN relkind = 'r' THEN + 'table' + WHEN relkind = 's' THEN + 'special' + ELSE + 'view' + END as reltype + , CASE + WHEN relkind = 'v' THEN + pg_get_viewdef(pg_class.oid) + ELSE + NULL + END as view_definition + FROM pg_catalog.pg_class + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE relkind IN ('r', 's', 'v') + AND nspname !~ '$system_schema_list' + AND nspname ~ '$schemapattern' + }; + $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out); + + # - uses pg_class.oid + my $sql_Columns = q{ + SELECT attname as column_name + , attlen as column_length + , CASE + WHEN pg_type.typname = 'int4' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'serial' + WHEN pg_type.typname = 'int8' + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + 'bigserial' + ELSE + pg_catalog.format_type(atttypid, atttypmod) + END as column_type + , CASE + WHEN attnotnull THEN + cast('NOT NULL' as text) + ELSE + cast('' as text) + END as column_null + , CASE + WHEN pg_type.typname IN ('int4', 'int8') + AND EXISTS (SELECT TRUE + FROM pg_catalog.pg_depend + JOIN pg_catalog.pg_class ON (pg_class.oid = objid) + WHERE refobjsubid = attnum + AND refobjid = attrelid + AND relkind = 'S') THEN + NULL + ELSE + adsrc + END as column_default + , pg_catalog.col_description(attrelid, attnum) as column_description + , attnum + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid) + LEFT JOIN pg_catalog.pg_attrdef ON ( attrelid = adrelid + AND attnum = adnum) + WHERE attnum > 0 + AND attisdropped IS FALSE + AND attrelid = ?; + }; + + my $sql_Table_Statistics; + if ( $statistics == 1 ) { + if ( $dbh->{pg_server_version} <= 70300 ) { + triggerError( + "Table statistics supported on PostgreSQL 7.4 and later.\n" + . "Remove --statistics flag and try again." ); + } + + $sql_Table_Statistics = q{ + SELECT table_len + , tuple_count + , tuple_len + , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent + , dead_tuple_count + , dead_tuple_len + , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent + , CAST(free_space AS numeric(20,2)) AS free_space + , CAST(free_percent AS numeric(20,2)) AS free_percent + FROM pgstattuple(CAST(? AS oid)); + }; + } + + my $sql_Indexes = q{ + SELECT schemaname + , tablename + , indexname + , substring( indexdef + FROM position('(' IN indexdef) + 1 + FOR length(indexdef) - position('(' IN indexdef) - 1 + ) AS indexdef + FROM pg_catalog.pg_indexes + WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE' + AND schemaname = ? + AND tablename = ?; + }; + + my $sql_Inheritance = qq{ + SELECT parnsp.nspname AS par_schemaname + , parcla.relname AS par_tablename + , chlnsp.nspname AS chl_schemaname + , chlcla.relname AS chl_tablename + FROM pg_catalog.pg_inherits + JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid) + JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace) + JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent) + JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace) + WHERE chlnsp.nspname = ? + AND chlcla.relname = ? + AND chlnsp.nspname ~ '$schemapattern' + AND parnsp.nspname ~ '$schemapattern'; + }; + + # Fetch the list of PRIMARY and UNIQUE keys + my $sql_Primary_Keys = q{ + SELECT conname AS constraint_name + , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition + , CASE + WHEN contype = 'p' THEN + 'PRIMARY KEY' + ELSE + 'UNIQUE' + END as constraint_type + FROM pg_catalog.pg_constraint AS c + JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid) + WHERE contype IN ('p', 'u') + AND deptype = 'i' + AND conrelid = ?; + }; + + # FOREIGN KEY fetch + # + # Don't return the constraint name if it was automatically generated by + # PostgreSQL. The $N (where N is an integer) is not a descriptive enough + # piece of information to be worth while including in the various outputs. + my $sql_Foreign_Keys = qq{ + SELECT pg_constraint.oid + , pg_namespace.nspname AS namespace + , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN '' + ELSE pg_constraint.conname + END AS constraint_name + , conkey AS constraint_key + , confkey AS constraint_fkey + , confrelid AS foreignrelid + FROM pg_catalog.pg_constraint + JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid) + JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid) + JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) + JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace) + WHERE contype = 'f' + AND conrelid = ? + AND pg_namespace.nspname ~ '$schemapattern' + AND pn.nspname ~ '$schemapattern'; + }; + + my $sql_Foreign_Key_Arg = q{ + SELECT attname AS attribute_name + , relname AS relation_name + , nspname AS namespace + FROM pg_catalog.pg_attribute + JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid) + JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid) + WHERE attrelid = ? + AND attnum = ?; + }; + + # Fetch CHECK constraints + my $sql_Constraint; + if ( $dbh->{pg_server_version} >= 70400 ) { + $sql_Constraint = q{ + SELECT pg_get_constraintdef(oid) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + else { + $sql_Constraint = q{ + SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + + # Query for function information + my $sql_Function; + my $sql_FunctionArg; + if ( $dbh->{pg_server_version} >= 80000 ) { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , proargnames AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + else { + $sql_Function = qq{ + SELECT proname AS function_name + , nspname AS namespace + , lanname AS language_name + , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment + , proargtypes AS function_args + , NULL AS function_arg_names + , prosrc AS source_code + , proretset AS returns_set + , prorettype AS return_type + FROM pg_catalog.pg_proc + JOIN pg_catalog.pg_language ON (pg_language.oid = prolang) + JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid) + JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid) + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern' + AND proname != 'plpgsql_call_handler'; + }; + + $sql_FunctionArg = q{ + SELECT nspname AS namespace + , replace(pg_catalog.format_type(pg_type.oid, typtypmod) + , nspname ||'.' + , '') AS type_name + FROM pg_catalog.pg_type + JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace) + WHERE pg_type.oid = ?; + }; + } + + # Fetch schema information. + my $sql_Schema = qq{ + SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment + , nspname as namespace + FROM pg_catalog.pg_namespace + WHERE pg_namespace.nspname !~ '$system_schema_list' + AND pg_namespace.nspname ~ '$schemapattern'; + }; + + my $sth_Columns = $dbh->prepare($sql_Columns); + my $sth_Constraint = $dbh->prepare($sql_Constraint); + my $sth_Database = $dbh->prepare($sql_Database); + my $sth_Foreign_Keys = $dbh->prepare($sql_Foreign_Keys); + my $sth_Foreign_Key_Arg = $dbh->prepare($sql_Foreign_Key_Arg); + my $sth_Function = $dbh->prepare($sql_Function); + my $sth_FunctionArg = $dbh->prepare($sql_FunctionArg); + my $sth_Indexes = $dbh->prepare($sql_Indexes); + my $sth_Inheritance = $dbh->prepare($sql_Inheritance); + my $sth_Primary_Keys = $dbh->prepare($sql_Primary_Keys); + my $sth_Schema = $dbh->prepare($sql_Schema); + my $sth_Tables = $dbh->prepare($sql_Tables); + my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics) + if ( $statistics == 1 ); + + # Fetch Database info + $sth_Database->execute(); + my $dbinfo = $sth_Database->fetchrow_hashref; + if ( defined($dbinfo) ) { + $db->{$database}{'COMMENT'} = $dbinfo->{'comment'}; + } + + # Fetch tables and all things bound to tables + $sth_Tables->execute(); + while ( my $tables = $sth_Tables->fetchrow_hashref ) { + my $reloid = $tables->{'oid'}; + my $relname = $tables->{'tablename'}; + + my $schema = $tables->{'namespace'}; + + EXPRESSIONFOUND: + + # Store permissions + my $acl = $tables->{'relacl'}; + + # Empty acl groups cause serious issues. + $acl ||= ''; + + # Strip array forming 'junk'. + $acl =~ s/^{//g; + $acl =~ s/}$//g; + $acl =~ s/"//g; + + # Foreach acl + foreach ( split( /\,/, $acl ) ) { + my ( $user, $raw_permissions ) = split( /=/, $_ ); + + if ( defined($raw_permissions) ) { + if ( $user eq '' ) { + $user = 'PUBLIC'; + } + + # The section after the / is the user who granted the permissions + my ( $permissions, $granting_user ) = + split( /\//, $raw_permissions ); + + # Break down permissions to individual flags + if ( $permissions =~ /a/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'INSERT'} = 1; + } + + if ( $permissions =~ /r/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'SELECT'} = 1; + } + + if ( $permissions =~ /w/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'UPDATE'} = 1; + } + + if ( $permissions =~ /d/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'DELETE'} = 1; + } + + if ( $permissions =~ /R/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'RULE'} = 1; + } + + if ( $permissions =~ /x/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'REFERENCES'} = 1; + } + + if ( $permissions =~ /t/ ) { + $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user} + {'TRIGGER'} = 1; + } + } + } + + # Primitive Stats, but only if requested + if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) { + $sth_Table_Statistics->execute($reloid); + + my $stats = $sth_Table_Statistics->fetchrow_hashref; + + $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} = + $stats->{'table_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} = + $stats->{'tuple_count'}; + $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} = + $stats->{'tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} = + $stats->{'dead_tuple_len'}; + $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} = + $stats->{'free_space'}; + } + + # Store the relation type + $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'}; + + # Store table description + $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} = + $tables->{'table_description'}; + + # Store the view definition + $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} = + $tables->{'view_definition'}; + + # Store constraints + $sth_Constraint->execute($reloid); + while ( my $cols = $sth_Constraint->fetchrow_hashref ) { + my $constraint_name = $cols->{'constraint_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'} + {$constraint_name} = $cols->{'constraint_source'}; + } + + $sth_Columns->execute($reloid); + my $i = 1; + while ( my $cols = $sth_Columns->fetchrow_hashref ) { + my $column_name = $cols->{'column_name'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'ORDER'} = $cols->{'attnum'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'PRIMARY KEY'} = 0; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'FKTABLE'} = ''; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'TYPE'} = $cols->{'column_type'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'NULL'} = $cols->{'column_null'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DESCRIPTION'} = $cols->{'column_description'}; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name} + {'DEFAULT'} = $cols->{'column_default'}; + } + + # Pull out both PRIMARY and UNIQUE keys based on the supplied query + # and the relation OID. + # + # Since there may be multiple UNIQUE indexes on a table, we append a + # number to the end of the the UNIQUE keyword which shows that they + # are a part of a related definition. I.e UNIQUE_1 goes with UNIQUE_1 + # + $sth_Primary_Keys->execute($reloid); + my $unqgroup = 0; + while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) { + my $index_type = $pricols->{'constraint_type'}; + my $con = $pricols->{'constraint_name'}; + my $indexdef = $pricols->{'constraint_definition'}; + + # Fetch the column list + my $column_list = $indexdef; + $column_list =~ s/.*\(([^)]+)\).*/$1/g; + + # Split our column list and deal with all PRIMARY KEY fields + my @collist = split( ',', $column_list ); + + # Store the column number in the indextype field. Anything > 0 + # indicates the column has this type of constraint applied to it. + my $column; + my $currentcol = $#collist + 1; + my $numcols = $#collist + 1; + + # Bump group number if there are two or more columns + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $unqgroup++; + } + + # Record the data to the structure. + while ( $column = pop(@collist) ) { + $column =~ s/\s$//; + $column =~ s/^\s//; + $column =~ s/^"//; + $column =~ s/"$//; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = $index_type; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $unqgroup; + } + } + } + + # FOREIGN KEYS like UNIQUE indexes can appear several times in + # a table in multi-column format. We use the same trick to + # record a numeric association to the foreign key reference. + $sth_Foreign_Keys->execute($reloid); + my $fkgroup = 0; + while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) { + my $column_oid = $forcols->{'oid'}; + my $con = $forcols->{'constraint_name'}; + + # Declare variables for dataload + my @keylist; + my @fkeylist; + my $fschema; + my $ftable; + + my $fkey = $forcols->{'constraint_fkey'}; + my $keys = $forcols->{'constraint_key'}; + my $frelid = $forcols->{'foreignrelid'}; + + # Since decent array support was not added until 7.4, and + # we want to support 7.3 as well, we parse the text version + # of the array by hand rather than combining this and + # Foreign_Key_Arg query into a single query. + + my @fkeyset; + if ( ref $fkey eq 'ARRAY' ) { + @fkeyset = @{$fkey}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $fkey =~ s/^{//g; + $fkey =~ s/}$//g; + $fkey =~ s/"//g; + @fkeyset = split( /,/, $fkey ); + } + + my @keyset; + if ( ref $keys eq 'ARRAY' ) { + @keyset = @{$keys}; + } + else { # DEPRECATED: DBD::Pg 1.49 and earlier + $keys =~ s/^{//g; + $keys =~ s/}$//g; + $keys =~ s/"//g; + @keyset = split( /,/, $keys ); + } + + # Convert the list of column numbers into column names for the + # local side. + foreach my $k (@keyset) { + $sth_Foreign_Key_Arg->execute( $reloid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @keylist, $row->{'attribute_name'} ); + } + + # Convert the list of columns numbers into column names + # for the referenced side. Grab the table and namespace + # while we're here. + foreach my $k (@fkeyset) { + $sth_Foreign_Key_Arg->execute( $frelid, $k ); + + my $row = $sth_Foreign_Key_Arg->fetchrow_hashref; + + push( @fkeylist, $row->{'attribute_name'} ); + $fschema = $row->{'namespace'}; + $ftable = $row->{'relation_name'}; + } + + # Deal with common catalog issues. + die "FKEY $con Broken -- fix your PostgreSQL installation" + if $#keylist != $#fkeylist; + + # Load up the array based on the information discovered + # using the information retrieval methods above. + my $numcols = $#keylist + 1; + my $currentcol = $#keylist + 1; + + # Bump group number if there are two or more columns involved + if ( $numcols >= 2 ) { + $fkgroup++; + } + + # Record the foreign key to structure + while ( my $column = pop(@keylist) + and my $fkey = pop(@fkeylist) ) + { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'TYPE'} = 'FOREIGN KEY'; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'COLNUM'} = $currentcol--; + + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKTABLE'} = $ftable; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FKSCHEMA'} = $fschema; + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'} + {$con}{'FK-COL NAME'} = $fkey; + + # Record group number only when a multi-column + # constraint is involved + if ( $numcols >= 2 ) { + $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'} = $fkgroup; + } + } + } + + # Pull out index information + $sth_Indexes->execute( $schema, $relname ); + while ( my $idx = $sth_Indexes->fetchrow_hashref ) { + $struct->{$schema}{'TABLE'}{$relname}{'INDEX'} + { $idx->{'indexname'} } = $idx->{'indexdef'}; + } + + # Extract Inheritance information + $sth_Inheritance->execute( $schema, $relname ); + while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) { + my $parSch = $inherit->{'par_schemaname'}; + my $parTab = $inherit->{'par_tablename'}; + $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} = + 1; + } + } + + # Function Handling + $sth_Function->execute(); + while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out ) + { + my $functionname = $functions->{'function_name'} . '( '; + my $schema = $functions->{'namespace'}; + my $comment = $functions->{'comment'}; + my $functionargs = $functions->{'function_args'}; + my @types = split( ' ', $functionargs ); + my $count = 0; + + # Pre-setup argument names when available. + my $argnames = $functions->{'function_arg_names'}; + my @names; + + if ( defined($argnames) ) { + $argnames =~ s/{(.*)}/$1/; + @names = split( ',', $argnames ); + } + + # Setup full argument types -- including the name prefix + foreach my $type (@types) { + $sth_FunctionArg->execute($type); + + my $hash = $sth_FunctionArg->fetchrow_hashref; + + if ( $count > 0 ) { + $functionname .= ', '; + } + + if ( scalar(@names) > 0 ) { + $functionname .= $names[$count] . ' '; + } + + if ( $hash->{'namespace'} ne $system_schema ) { + $functionname .= $hash->{'namespace'} . '.'; + } + $functionname .= $hash->{'type_name'}; + + $count++; + } + $functionname .= ' )'; + + my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : ''; + $sth_FunctionArg->execute( $functions->{'return_type'} ); + my $rhash = $sth_FunctionArg->fetchrow_hashref; + $ret_type .= $rhash->{'type_name'}; + + $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment; + $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} = + $functions->{'source_code'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} = + $functions->{'language_name'}; + $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type; + } + + # Deal with the Schema + $sth_Schema->execute(); + while ( my $schema = $sth_Schema->fetchrow_hashref ) { + my $comment = $schema->{'comment'}; + my $namespace = $schema->{'namespace'}; + + $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment; + } + + $sth_Columns->finish(); + $sth_Constraint->finish(); + $sth_Database->finish(); + $sth_Foreign_Keys->finish(); + $sth_Foreign_Key_Arg->finish(); + $sth_Function->finish(); + $sth_FunctionArg->finish(); + $sth_Indexes->finish(); + $sth_Inheritance->finish(); + $sth_Primary_Keys->finish(); + $sth_Schema->finish(); + $sth_Tables->finish(); + $sth_Table_Statistics->finish() + if ( $statistics == 1 ); + + $dbh->disconnect; + +} ## end sub info_collect($$$$$) + +##### +# write_using_templates +# +# Generate structure that HTML::Template requires out of the +# $struct for table related information, and $struct for +# the schema and function information +sub write_using_templates($$$$$) { + my ( $db, $database, $statistics, $template_path, $output_filename_base, + $wanted_output ) + = @_; + my $struct = $db->{$database}{'STRUCT'}; + + my @schemas; + + # Start at 0, increment to 1 prior to use. + my $object_id = 0; + my %tableids; + foreach my $schema ( sort keys %{$struct} ) { + my @tables; + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + + # Column List + my @columns; + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + my $inferrednotnull = 0; + + # Have a shorter default for places that require it + my $shortdefault = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}; + $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g + if ( defined($shortdefault) ); + + # Deal with column constraints + my @colconstraints; + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'UNIQUE' ) + { + my $unq = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'}; + my $unqcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'COLNUM'}; + my $unqgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + + push @colconstraints, + { + column_unique => $unq, + column_unique_colnum => $unqcol, + column_unique_keygroup => $unqgroup, + }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' ) + { + $inferrednotnull = 1; + push @colconstraints, + { column_primary_key => 'PRIMARY KEY', }; + } + elsif ( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKSCHEMA'}, + $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'FKTABLE'} ) + ); + + my $fkgroup = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'KEYGROUP'}; + my $fktable = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $fkcol = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + my $fkschema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + + push @colconstraints, + { + column_fk => 'FOREIGN KEY', + column_fk_colnum => $fkcol, + column_fk_keygroup => $fkgroup, + column_fk_schema => $fkschema, + column_fk_schema_dbk => docbook($fkschema), + column_fk_schema_dot => graphviz($fkschema), + column_fk_sgmlid => $fksgmlid, + column_fk_table => $fktable, + column_fk_table_dbk => docbook($fktable), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $colconstraints[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + + # Generate the Column array + push @columns, { + column => $column, + column_dbk => docbook($column), + column_dot => graphviz($column), + column_default => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'}, + column_default_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DEFAULT'} + ), + column_default_short => $shortdefault, + column_default_short_dbk => docbook($shortdefault), + + column_comment => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'}, + column_comment_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'DESCRIPTION'} + ), + + column_number => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'ORDER'}, + + column_type => + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'}, + column_type_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + column_type_dot => graphviz( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'TYPE'} + ), + + column_constraints => \@colconstraints, + }; + + if ( $inferrednotnull == 0 ) { + $columns[-1]{"column_constraint_notnull"} = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'NULL'}; + } + } + + # Constraint List + my @constraints; + foreach my $constraint ( + sort + keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} } + ) + { + my $shortcon = + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}; + $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g; + push @constraints, + { + constraint => + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint}, + constraint_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} + {$constraint} + ), + constraint_name => $constraint, + constraint_name_dbk => docbook($constraint), + constraint_short => $shortcon, + constraint_short_dbk => docbook($shortcon), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + }; + } + + # Index List + my @indexes; + foreach my $index ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } ) + { + push @indexes, + { + index_definition => + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}, + index_definition_dbk => docbook( + $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index} + ), + index_name => $index, + index_name_dbk => docbook($index), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + }; + } + + my @inherits; + foreach my $inhSch ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } ) + { + foreach my $inhTab ( + sort keys + %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} } + ) + { + push @inherits, + { + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + sgmlid => + sgml_safe_id( join( '.', $schema, 'table', $table ) ), + parent_sgmlid => sgml_safe_id( + join( '.', $inhSch, 'table', $inhTab ) + ), + parent_table => $inhTab, + parent_table_dbk => docbook($inhTab), + parent_table_dot => graphviz($inhTab), + parent_schema => $inhSch, + parent_schema_dbk => docbook($inhSch), + parent_schema_dot => graphviz($inhSch), + }; + } + } + + # Foreign Key Discovery + # + # $lastmatch is used to ensure that we only supply a result a + # single time and not once for each link found. Since the + # loops are sorted, we only need to track the last element, and + # not all supplied elements. + my @fk_schemas; + my $lastmatch = ''; + foreach my $fk_schema ( sort keys %{$struct} ) { + foreach + my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } ) + { + foreach my $fk_column ( + sort keys + %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} } + ) + { + foreach my $fk_con ( + sort keys %{ + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'} + } + ) + { + if ( $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'} + eq 'FOREIGN KEY' + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKTABLE'} eq $table + and $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'CON'}{$fk_con} + {'FKSCHEMA'} eq $schema + and $lastmatch ne "$fk_schema$fk_table" ) + { + my $fksgmlid = sgml_safe_id( + join( '.', + $fk_schema, + $struct->{$fk_schema}{'TABLE'} + {$fk_table}{'TYPE'}, + $fk_table ) + ); + push @fk_schemas, + { + fk_column_number => + $struct->{$fk_schema}{'TABLE'}{$fk_table} + {'COLUMN'}{$fk_column}{'ORDER'}, + fk_sgmlid => $fksgmlid, + fk_schema => $fk_schema, + fk_schema_dbk => docbook($fk_schema), + fk_schema_dot => graphviz($fk_schema), + fk_table => $fk_table, + fk_table_dbk => docbook($fk_table), + fk_table_dot => graphviz($fk_table), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_schemas[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + $lastmatch = "$fk_schema$fk_table"; + } + } + } + } + } + + # List off permissions + my @permissions; + foreach my $user ( + sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } ) + { + push @permissions, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + user => $user, + user_dbk => docbook($user), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $permissions[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + + foreach my $perm ( + keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} } + ) + { + if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} + {$perm} == 1 ) + { + $permissions[-1]{ lower($perm) } = 1; + } + } + + } + + # Increment and record the object ID + $tableids{"$schema$table"} = ++$object_id; + my $viewdef = sql_prettyprint( + $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} ); + + # Truncate comment for Dia + my $comment_dia = + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}; + $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g + if ( defined($comment_dia) ); + + push @tables, { + object_id => $object_id, + object_id_dbk => docbook($object_id), + + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + + # Statistics + stats_enabled => $statistics, + stats_dead_bytes => useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ), + stats_dead_bytes_dbk => docbook( + useUnits( + $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'} + ) + ), + stats_free_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ), + stats_free_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ) + ), + stats_table_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ), + stats_table_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ) + ), + stats_tuple_count => + $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'}, + stats_tuple_count_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ), + stats_tuple_bytes => + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ), + stats_tuple_bytes_dbk => docbook( + useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ) + ), + + table => $table, + table_dbk => docbook($table), + table_dot => graphviz($table), + table_sgmlid => sgml_safe_id( + join( '.', + $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'}, + $table ) + ), + table_comment => + $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'}, + table_comment_dbk => + docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ), + table_comment_dia => $comment_dia, + view_definition => $viewdef, + view_definition_dbk => docbook($viewdef), + columns => \@columns, + constraints => \@constraints, + fk_schemas => \@fk_schemas, + indexes => \@indexes, + inherits => \@inherits, + permissions => \@permissions, + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Dump out list of functions + my @functions; + foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) { + push @functions, + { + function => $function, + function_dbk => docbook($function), + function_sgmlid => + sgml_safe_id( join( '.', $schema, 'function', $function ) ), + function_comment => + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}, + function_comment_dbk => docbook( + $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'} + ), + function_language => + uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ), + function_returns => + $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'}, + function_source => + $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'}, + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + }; + + # only have the count if there is more than 1 schema + if ( scalar( keys %{$struct} ) > 1 ) { + $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + push @schemas, + { + schema => $schema, + schema_dbk => docbook($schema), + schema_dot => graphviz($schema), + schema_sgmlid => sgml_safe_id( $schema . ".schema" ), + schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'}, + schema_comment_dbk => + docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ), + functions => \@functions, + tables => \@tables, + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} ); + } + } + + # Link the various components together via the template. + my @fk_links; + my @fkeys; + foreach my $schema ( sort keys %{$struct} ) { + foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) { + foreach my $column ( + sort { + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a} + {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table} + {'COLUMN'}{$b}{'ORDER'} + } + keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} } + ) + { + foreach my $con ( + sort keys %{ + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'} + } + ) + { + + # To prevent a multi-column foreign key from appearing + # several times, we've opted + # to simply display the first column of any given key. + # Since column numbering always starts at 1 + # for foreign keys. + if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' + && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'COLNUM'} == 1 ) + { + + # Pull out some of the longer keys + my $ref_table = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKTABLE'}; + my $ref_schema = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FKSCHEMA'}; + my $ref_column = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column} + {'CON'}{$con}{'FK-COL NAME'}; + + # Default values cause these elements to attach + # to the bottom in Dia + # If a KEYGROUP is not defined, it's a single column. + # Modify the ref_con and key_con variables to attach + # the to the columns connection point directly. + my $ref_con = 0; + my $key_con = 0; + my $keycon_offset = 0; + if ( + !defined( + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'CON'}{$con}{'KEYGROUP'} + ) + ) + { + $ref_con = + $struct->{$ref_schema}{'TABLE'}{$ref_table} + {'COLUMN'}{$ref_column}{'ORDER'} || 0; + $key_con = + $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} + {$column}{'ORDER'} || 0; + $keycon_offset = 1; + } + + # Bump object_id + $object_id++; + + push @fk_links, + { + fk_link_name => $con, + fk_link_name_dbk => docbook($con), + fk_link_name_dot => graphviz($con), + handle0_connection => $key_con, + handle0_connection_dbk => docbook($key_con), + handle0_connection_dia => 6 + ( $key_con * 2 ), + handle0_name => $table, + handle0_name_dbk => docbook($table), + handle0_schema => $schema, + handle0_to => $tableids{"$schema$table"}, + handle0_to_dbk => + docbook( $tableids{"$schema$table"} ), + handle1_connection => $ref_con, + handle1_connection_dbk => docbook($ref_con), + handle1_connection_dia => 6 + + ( $ref_con * 2 ) + + $keycon_offset, + handle1_name => $ref_table, + handle1_name_dbk => docbook($ref_table), + handle1_schema => $ref_schema, + handle1_to => $tableids{"$ref_schema$ref_table"}, + handle1_to_dbk => + docbook( $tableids{"$ref_schema$ref_table"} ), + object_id => $object_id, + object_id_dbk => docbook($object_id), + }; + + # Build the array of schemas + if ( scalar( keys %{$struct} ) > 1 ) { + $fk_links[-1]{"number_of_schemas"} = + scalar( keys %{$struct} ); + } + } + } + } + } + } + + # Make database level comment information + my @timestamp = localtime(); + my $dumped_on = sprintf( "%04d-%02d-%02d", + $timestamp[5] + 1900, + $timestamp[4] + 1, + $timestamp[3] ); + my $database_comment = $db->{$database}{'COMMENT'}; + + # Loop through each template found in the supplied path. + # Output the results of the template as <filename>.<extension> + # into the current working directory. + my @template_files = glob( $template_path . '/*.tmpl' ); + + # Ensure we've told the user if we don't find any files. + triggerError("Templates files not found in $template_path") + if ( $#template_files < 0 ); + + # Process all found templates. + foreach my $template_file (@template_files) { + ( my $file_extension = $template_file ) =~ + s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/; + next + if ( defined($wanted_output) && $file_extension ne $wanted_output ); + my $output_filename = "$output_filename_base.$file_extension"; + print "Producing $output_filename from $template_file\n"; + + my $template = HTML::Template->new( + filename => $template_file, + die_on_bad_params => 0, + global_vars => 0, + strict => 1, + loop_context_vars => 1 + ); + + $template->param( + database => $database, + database_dbk => docbook($database), + database_sgmlid => sgml_safe_id($database), + database_comment => $database_comment, + database_comment_dbk => docbook($database_comment), + dumped_on => $dumped_on, + dumped_on_dbk => docbook($dumped_on), + fk_links => \@fk_links, + schemas => \@schemas, + ); + + sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 ) + or die "Can't open $output_filename: $!"; + print FH $template->output(); + } +} ## end sub write_using_templates($$$$$) + +###### +# sgml_safe_id +# Safe SGML ID Character replacement +sub sgml_safe_id($) { + my $string = shift; + + # Lets use the keyword ARRAY in place of the square brackets + # to prevent duplicating a non-array equivelent + $string =~ s/\[\]/ARRAY-/g; + + # Brackets, spaces, commads, underscores are not valid 'id' characters + # replace with as few -'s as possible. + $string =~ s/[ "',)(_-]+/-/g; + + # Don't want a - at the end either. It looks silly. + $string =~ s/-$//g; + + return ($string); +} + +##### +# lower +# LowerCase the string +sub lower($) { + my $string = shift; + + $string =~ tr/A-Z/a-z/; + + return ($string); +} + +##### +# useUnits +# Tack on base 2 metric units +sub useUnits($) { + my ($value) = @_; + + return '' if ( !defined($value) ); + + my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' ); + my $loop = 0; + + while ( $value >= 1024 ) { + $loop++; + + $value = $value / 1024; + } + + return ( sprintf( "%.2f %s", $value, $units[$loop] ) ); +} + +##### +# docbook +# Docbook output is special in that we may or may not want to escape +# the characters inside the string depending on a string prefix. +sub docbook($) { + my $string = shift; + + if ( defined($string) ) { + if ( $string =~ /^\@DOCBOOK/ ) { + $string =~ s/^\@DOCBOOK//; + } + else { + $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&/g; + $string =~ s/</</g; + $string =~ s/>/>/g; + $string =~ s/'/'/g; + $string =~ s/"/"/g; + } + } + else { + + # Return an empty string when all else fails + $string = ''; + } + + return ($string); +} + +##### +# graphviz +# GraphViz output requires that special characters (like " and whitespace) must be preceeded +# by a \ when a part of a lable. +sub graphviz($) { + my $string = shift; + + # Ensure we don't return an least a empty string + $string = '' if ( !defined($string) ); + + $string =~ s/([\s"'])/\\$1/g; + + return ($string); +} + +##### +# sql_prettyprint +# Clean up SQL into something presentable +sub sql_prettyprint($) { + my $string = shift; + + # If nothing has been sent in, return an empty string + if ( !defined($string) ) { + return ''; + } + + # Initialize Result string + my $result = ''; + + # List of tokens to split on + my $tok = + "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN" + . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN" + . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]"; + + my $key = 0; + my $bracket = 0; + my $depth = 0; + my $indent = 6; + + # XXX: Split is wrong -- match would do + foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) { + my $format; + + # Skip junk tokens + if ( $elem =~ /^[\s]?$/ ) { + next; + } + + # NOTE: Should we drop leading spaces? + # $elem =~ s/^\s//; + + # Close brackets are special + # Bring depth in a level + if ( $elem =~ /\)/ ) { + $depth = $depth - $indent; + if ( $key == 1 or $bracket == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 0; + $bracket = 0; + } + + # Open brackets are special + # Bump depth out a level + elsif ( $elem =~ /\(/ ) { + if ( $key == 1 ) { + $format = "%s %s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + $depth = $depth + $indent; + $bracket = 1; + $key = 0; + } + + # Key element + # Token from our list -- format on left hand side of the equation + # when appropriate. + elsif ( $elem =~ /$tok/ ) { + if ( $key == 1 ) { + $format = "%s%s"; + } + else { + $format = "%s\n%" . $depth . "s"; + } + + $key = 1; + $bracket = 0; + } + + # Value + # Format for right hand side of the equation + else { + $format = "%s%s"; + + $key = 0; + } + + # Add the new format string to the result + $result = sprintf( $format, $result, $elem ); + } + + return $result; +} ## end sub sql_prettyprint($) + +## +# triggerError +# Print out a supplied error message and exit the script. +sub triggerError($) { + my ($error) = @_; + + # Test error + if ( !defined($error) || $error eq '' ) { + + # Suppress prototype checking in call to self + &triggerError("triggerError: Unknown error"); + } + printf( "\n\n%s\n", $error ); + + exit 2; +} + +##### +# usage +sub usage($$$) { + my ( $basename, $database, $dbuser ) = @_; + print <<USAGE +Usage: + $basename [options] [dbname [username]] + +Options: + -d <dbname> Specify database name to connect to (default: $database) + -f <file> Specify output file prefix (default: $database) + -h <host> Specify database server host (default: localhost) + -p <port> Specify database server port (default: 5432) + -u <username> Specify database username (default: $dbuser) + --password=<pw> Specify database password (default: blank) + --password Have $basename prompt for a password + + -l <path> Path to the templates (default: @@TEMPLATE-DIR@@) + -t <output> Type of output wanted (default: All in template library) + + -s <schema> Specify a specific schema to match. Technically this is a regular + expression but anything other than a specific name may have unusual + results. + --table=<args> Tables to export. Multiple tables may be provided using a + comma-separated list. + + --statistics In 7.4 and later, with the contrib module pgstattuple installed we + can gather statistics on the tables in the database + (average size, free space, disk space used, dead tuple counts, etc.) + This is disk intensive on large databases as all pages must be visited. +USAGE + ; + exit 1; +} + +sub single_quote { + my $attr = $_; + $attr =~ s/^\s+|\s+$//g; + return qq{'$attr'}; +} + +## +# Kick off execution of main() +main($ARGV); + diff --git a/postgresql_autodoc/xml.tmpl b/postgresql_autodoc/xml.tmpl new file mode 100644 index 0000000..d589930 --- /dev/null +++ b/postgresql_autodoc/xml.tmpl @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- $Header: /cvsroot/autodoc/autodoc/xml.tmpl,v 1.2 2006/05/16 19:01:27 rbt Exp $ --> + +<book id="database.<!-- TMPL_VAR name="database_sgmlid" -->" xreflabel="<!-- TMPL_VAR name="database_dbk" --> database schema"><title><!-- TMPL_VAR name="database_dbk" --> Model</title> + +<!-- TMPL_IF name="database_comment" --> +<!-- TMPL_VAR name="database_comment_dbk" --> +<!-- /TMPL_IF name="database_comment" --> + +<!-- TMPL_LOOP name="schemas" --> + <chapter id="<!-- TMPL_VAR name="schema_sgmlid" -->" + xreflabel="<!-- TMPL_VAR name="schema_dbk" -->"> + <title>Schema <!-- TMPL_VAR name="schema_dbk" --></title> + <para><!-- TMPL_VAR name="schema_comment_dbk" --></para> + +<!-- TMPL_LOOP name="tables" --> + <section id="<!-- TMPL_VAR name="table_sgmlid" -->" + xreflabel="<!-- TMPL_VAR name="schema_dbk" -->.<!-- TMPL_VAR name="table_dbk" -->"> + <title id="<!-- TMPL_VAR name="table_sgmlid" -->-title"> + <!-- TMPL_IF name="view_definition" -->View: + <!-- TMPL_ELSE -->Table: + <!-- /TMPL_IF name="view_definition" --> + <structname><!-- TMPL_VAR name="table_dbk" --></structname> + </title> + +<!-- TMPL_IF name="table_comment" --> + <para> + <!-- TMPL_VAR name="table_comment_dbk" --> + </para> +<!-- /TMPL_IF name="table_comment" --> + + <para> + <variablelist> + <title> + Structure of <structname><!-- TMPL_VAR name="table_dbk" --></structname> + </title> + +<!-- TMPL_LOOP name="columns" --> + <varlistentry> + <term><structfield><!-- TMPL_VAR name="column_dbk" --></structfield></term> + <listitem><para> + <type><!-- TMPL_VAR name="column_type_dbk" --></type> +<!-- TMPL_LOOP name="column_constraints" --> +<!-- TMPL_IF name="column_primary_key" --> + <literal>PRIMARY KEY</literal> + +<!-- /TMPL_IF name="column_primary_key" --> + +<!-- TMPL_IF name="column_unique" --> + <literal>UNIQUE<!-- TMPL_IF name="column_unique_keygroup" -->#<!-- TMPL_VAR name="column_unique_keygroup" --><!-- /TMPL_IF name="column_unique_keygroup" --></literal> +<!-- /TMPL_IF name="column_unique" --> +<!-- /TMPL_LOOP name="column_constraints" --> + +<!-- TMPL_IF name="column_constraint_notnull" --> + <literal>NOT NULL</literal> +<!-- /TMPL_IF name="column_constraint_notnull" --> + +<!-- TMPL_IF name="column_default" --> + <literal>DEFAULT <!-- TMPL_VAR name="column_default_dbk" --></literal> +<!-- /TMPL_IF name="column_default" --> + +<!-- TMPL_LOOP name="column_constraints" --> +<!-- TMPL_IF name="column_fk" --> + <literal>REFERENCES</literal> <xref linkend="<!-- TMPL_VAR name="column_fk_sgmlid" -->"/> +<!-- /TMPL_IF name="column_fk" --> +<!-- /TMPL_LOOP name="column_constraints" --> + </para> +<!-- TMPL_IF name="column_comment" --> + <para> + <!-- TMPL_VAR name="column_comment_dbk" --> + </para> +<!-- /TMPL_IF name="column_comment" --> + </listitem> + </varlistentry> +<!-- /TMPL_LOOP name="columns" --> + </variablelist> + +<!-- TMPL_LOOP name="constraints" --> +<!-- TMPL_IF name="__FIRST__" --> + <variablelist> + <title>Constraints on <!-- TMPL_VAR name="table_dbk" --></title> +<!-- /TMPL_IF name="__FIRST__" --> + <varlistentry> + <term><!-- TMPL_VAR name="constraint_name_dbk" --></term> + <listitem><para><!-- TMPL_VAR name="constraint_dbk" --></para></listitem> + </varlistentry> +<!-- TMPL_IF name="__LAST__" --> + </variablelist> +<!-- /TMPL_IF name="__LAST__" --> +<!-- /TMPL_LOOP name="constraints" --> + +<!-- TMPL_LOOP name="indexes" --> +<!-- TMPL_IF name="__FIRST__" --> + <variablelist> + <title>Indexes on <!-- TMPL_VAR name="table_dbk" --></title> +<!-- /TMPL_IF name="__FIRST__" --> + <varlistentry> + <term><!-- TMPL_VAR name="index_name_dbk" --></term> + <listitem><para><!-- TMPL_VAR name="index_definition_dbk" --></para></listitem> + </varlistentry> +<!-- TMPL_IF name="__LAST__" --> + </variablelist> +<!-- /TMPL_IF name="__LAST__" --> +<!-- /TMPL_LOOP name="indexes" --> + +<!-- TMPL_LOOP name="fk_schemas" --> +<!-- TMPL_IF name="__FIRST__" --> + <itemizedlist> + <title> + Tables referencing <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema_dbk" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table_dbk" --> via Foreign Key Constraints + </title> +<!-- /TMPL_IF name="__FIRST__" --> + <listitem> + <para> + <xref linkend="<!-- TMPL_VAR name="fk_sgmlid" -->"/> + </para> + </listitem> +<!-- TMPL_IF name="__LAST__" --> + </itemizedlist> +<!-- /TMPL_IF name="__LAST__" --> +<!-- /TMPL_LOOP name="fk_schemas" --> + +<!-- TMPL_IF name="view_definition" --> + <figure> + <title>Definition of view <!-- TMPL_VAR name="table_dbk" --></title> + <programlisting><!-- TMPL_VAR name="view_definition_dbk" --></programlisting> + </figure> +<!-- /TMPL_IF name="view_definition" --> +<!-- TMPL_LOOP name="permissions" --> +<!-- TMPL_IF name="__FIRST__" --> + <variablelist> + <title>Permissions on <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR name="table_dbk" --></title> +<!-- /TMPL_IF name="__FIRST__" --> + <varlistentry> + <term><!-- TMPL_VAR name="user_dbk" --></term> + <listitem> + <para> + <simplelist type="inline"> +<!-- TMPL_IF name="select" --> + <member>Select</member> +<!-- /TMPL_IF name="select" --> +<!-- TMPL_IF name="insert" --> + <member>Insert</member> +<!-- /TMPL_IF name="insert" --> +<!-- TMPL_IF name="update" --> + <member>Update</member> +<!-- /TMPL_IF name="update" --> +<!-- TMPL_IF name="delete" --> + <member>Delete</member> +<!-- /TMPL_IF name="delete" --> +<!-- TMPL_IF name="rule" --> + <member>Rule</member> +<!-- /TMPL_IF name="rule" --> +<!-- TMPL_IF name="references" --> + <member>References</member> +<!-- /TMPL_IF name="references" --> +<!-- TMPL_IF name="trigger" --> + <member>Trigger</member> +<!-- /TMPL_IF name="trigger" --> + </simplelist> + </para> + </listitem> + </varlistentry> +<!-- TMPL_IF name="__LAST__" --> + </variablelist> +<!-- /TMPL_IF name="__LAST__" --> +<!-- /TMPL_LOOP name="permissions" --> + + </para> + </section> +<!-- /TMPL_LOOP name="tables" --> + +<!-- TMPL_LOOP name="functions" --> +<!-- Function <!-- TMPL_VAR NAME="function" --> --> + <section id="<!-- TMPL_VAR NAME="function_sgmlid" -->" + xreflabel="<!-- TMPL_VAR NAME="schema_dbk" --><!-- TMPL_VAR NAME="function_dbk"-->"> + <title id="<!-- TMPL_VAR NAME="function_sgmlid" -->-title"> + <!-- TMPL_VAR name="function_dbk" --> + </title> + <titleabbrev id="<!-- TMPL_VAR NAME="function_sgmlid" -->-titleabbrev"> + <!-- TMPL_VAR name="function_dbk" --> + </titleabbrev> + + <para> + <segmentedlist> + <title>Function Properties</title> + <?dbhtml list-presentation="list"?> + <segtitle>Language</segtitle> + <segtitle>Return Type</segtitle> + <seglistitem> + <seg><!-- TMPL_VAR ESCAPE="HTML" name="function_language" --></seg> + <seg><!-- TMPL_VAR ESCAPE="HTML" name="function_returns" --></seg> + </seglistitem> + </segmentedlist> + + <!-- TMPL_VAR name="function_comment_dbk" --> + <programlisting><!-- TMPL_IF name="function_source" --><!-- TMPL_VAR ESCAPE="HTML" name="function_source" --><!-- /TMPL_IF name="function_source" --></programlisting> + </para> + </section> +<!-- /TMPL_LOOP name="functions" --> + </chapter> +<!-- /TMPL_LOOP name="schemas" --> +</book> + diff --git a/postgresql_autodoc/zigzag.dia.tmpl b/postgresql_autodoc/zigzag.dia.tmpl new file mode 100644 index 0000000..2b9f952 --- /dev/null +++ b/postgresql_autodoc/zigzag.dia.tmpl @@ -0,0 +1,224 @@ +<?xml version="1.0" encoding="UTF-8"?> +<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/"> + <dia:layer name="Background" visible="true"> +<!-- TMPL_LOOP name="schemas" --> +<!-- TMPL_IF name="number_of_schemas" --> + <dia:group> +<!-- /TMPL_IF name="number_of_schemas" --> +<!-- TMPL_LOOP name="tables" --> + <dia:object type="UML - Class" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->"> + <dia:attribute name="obj_pos"> + <dia:point val="0,0"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="-0.05,-0.05;16.4,6.65"/> + </dia:attribute> + <dia:attribute name="elem_corner"> + <dia:point val="0,0"/> + </dia:attribute> + <dia:attribute name="elem_width"> + <dia:real val="16.350000000000001"/> + </dia:attribute> + <dia:attribute name="elem_height"> + <dia:real val="6.6000000000000005"/> + </dia:attribute> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table" -->#</dia:string> + </dia:attribute> +<!-- TMPL_IF name="number_of_schemas" --> + <dia:attribute name="stereotype"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="schema" -->#</dia:string> + </dia:attribute> +<!-- /TMPL_IF name="number_of_schemas" --> + <dia:attribute name="comment"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table_comment_dia" -->#</dia:string> + </dia:attribute> + <dia:attribute name="abstract"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="suppress_attributes"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="suppress_operations"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="visible_attributes"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="visible_comments"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="wrap_operations"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="wrap_after_char"> + <dia:int val="40"/> + </dia:attribute> + <dia:attribute name="line_color"> + <dia:color val="#000000"/> + </dia:attribute> + <dia:attribute name="fill_color"> + <dia:color val="#ffffff"/> + </dia:attribute> + <dia:attribute name="text_color"> + <dia:color val="#000000"/> + </dia:attribute> + <dia:attribute name="normal_font"> + <dia:font family="monospace" style="0" name="Courier"/> + </dia:attribute> + <dia:attribute name="abstract_font"> + <dia:font family="monospace" style="88" name="Courier"/> + </dia:attribute> + <dia:attribute name="polymorphic_font"> + <dia:font family="monospace" style="8" name="Courier"/> + </dia:attribute> + <dia:attribute name="classname_font"> + <dia:font family="sans" style="80" name="Helvetica"/> + </dia:attribute> + <dia:attribute name="abstract_classname_font"> + <dia:font family="sans" style="88" name="Helvetica"/> + </dia:attribute> + <dia:attribute name="comment_font"> + <dia:font family="sans" style="8" name="Helvetica"/> + </dia:attribute> + <dia:attribute name="font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="polymorphic_font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="abstract_font_height"> + <dia:real val="0.80000000000000004"/> + </dia:attribute> + <dia:attribute name="classname_font_height"> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="abstract_classname_font_height"> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="comment_font_height"> + <dia:real val="1"/> + </dia:attribute> + <dia:attribute name="attributes"> +<!-- TMPL_LOOP name="columns" --> + <dia:composite type="umlattribute"> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_IF name="column_primary_key" -->PK<!-- TMPL_ELSE name="column_primary_key" --> <!-- /TMPL_IF name="column_primary_key" --><!-- TMPL_VAR ESCAPE="HTML" name="column" -->#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_type" -->#</dia:string> + </dia:attribute> + <dia:attribute name="value"> +<!-- TMPL_IF name="column_default_short" --> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_default_short" -->#</dia:string> +<!-- TMPL_ELSE name="column_default_short" --> + <dia:string/> +<!-- /TMPL_IF name="column_default_short" --> + </dia:attribute> + <dia:attribute name="visibility"> + <dia:enum val="3"/> + </dia:attribute> + <dia:attribute name="abstract"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="class_scope"> + <dia:boolean val="false"/> + </dia:attribute> + </dia:composite> +<!-- /TMPL_LOOP name="columns" --> + </dia:attribute> +<!-- TMPL_IF name="constraints" --> + <dia:attribute name="visible_operations"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:attribute name="operations"> +<!-- TMPL_LOOP name="constraints" --> + <dia:composite type="umloperation"> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" -->#</dia:string> + </dia:attribute> + <dia:attribute name="visibility"> + <dia:enum val="3"/> + </dia:attribute> + <dia:attribute name="abstract"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="class_scope"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="parameters"> + <dia:composite type="umlparameter"> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_short" -->#</dia:string> + </dia:attribute> + <dia:attribute name="type"> + <dia:string>##</dia:string> + </dia:attribute> + <dia:attribute name="value"> + <dia:string/> + </dia:attribute> + <dia:attribute name="kind"> + <dia:enum val="0"/> + </dia:attribute> + </dia:composite> + </dia:attribute> + </dia:composite> +<!-- /TMPL_LOOP name="constraints" --> + </dia:attribute> +<!-- TMPL_ELSE name="constraints" --> + <dia:attribute name="visible_operations"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="operations"/> +<!-- /TMPL_IF name="constraints" --> + <dia:attribute name="template"> + <dia:boolean val="false"/> + </dia:attribute> + <dia:attribute name="templates"/> + </dia:object> +<!-- /TMPL_LOOP name="tables" --> +<!-- TMPL_IF name="number_of_schemas" --> + </dia:group> +<!-- /TMPL_IF name="number_of_schemas" --> +<!-- /TMPL_LOOP name="schemas" --> +<!-- TMPL_LOOP name="fk_links" --> + <dia:object type="UML - Dependency" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->"> + <dia:attribute name="obj_pos"> + <dia:point val="0,3.5"/> + </dia:attribute> + <dia:attribute name="obj_bb"> + <dia:rectangle val="-0.0515705,2.29861;25.1127,3.55157"/> + </dia:attribute> + <dia:attribute name="orth_points"> + <dia:point val="1.0,1.0"/> + <dia:point val="1.0,1.0"/> + <dia:point val="1.0,1.0"/> + </dia:attribute> + <dia:attribute name="orth_orient"> + <dia:enum val="1"/> + <dia:enum val="0"/> + </dia:attribute> + <dia:attribute name="orth_autoroute"> + <dia:boolean val="true"/> + </dia:attribute> + + <dia:attribute name="line_colour"> + <dia:color val="#000000"/> + </dia:attribute> + <dia:attribute name="name"> + <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="fk_link_name" -->#</dia:string> + </dia:attribute> + <dia:attribute name="stereotype"> + <dia:string>##</dia:string> + </dia:attribute> + <dia:attribute name="draw_arrow"> + <dia:boolean val="true"/> + </dia:attribute> + <dia:connections> + <dia:connection handle="0" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle0_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle0_connection_dia" -->"/> + <dia:connection handle="1" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle1_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle1_connection_dia" -->"/> + </dia:connections> + </dia:object> +<!-- /TMPL_LOOP name="fk_links" --> + </dia:layer> +</dia:diagram> diff --git a/removed-code/Browser.java b/removed-code/Browser.java new file mode 100644 index 0000000..daafa05 --- /dev/null +++ b/removed-code/Browser.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpClients.SwtClient.GUI; + +import YalpClients.*; +import YalpClients.SwtClient.*; + +import YalpInterfaces.*; + +import org.eclipse.swt.*; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +import java.util.LinkedList; + +/* + * Class Browser + * + * <em></em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006<br> + */ +public class Browser extends Composite{ + private Composite parentComposite; + private Display display1; + private Shell shell; + private Model model; + private LinkedList<String> alreadyBrowsed; + private Tree tree; + private Button add; + private Button cancel; + + Browser( Composite parent, + final Model model, + Display display, + Composite parentComposite, + int style ) + { + super(parent, style); + this.parentComposite=parentComposite; + this.alreadyBrowsed = new LinkedList<String>(); + this.model = model; + this.display1 = display; + this.shell = new Shell(this.display1,SWT.NONE); + this.setSize(300,400); + GridLayout gridLayout = new GridLayout(); + this.shell.setLayout(gridLayout); + gridLayout.numColumns = 2; + + GridData treeGrid = new GridData(); + treeGrid.horizontalSpan = 2; + treeGrid.widthHint = 300; + treeGrid.heightHint = 400; + treeGrid.grabExcessHorizontalSpace = true; + treeGrid.grabExcessVerticalSpace = true; + treeGrid.horizontalAlignment = SWT.FILL; + treeGrid.verticalAlignment = SWT.FILL; + + this.tree = new Tree(this.shell, SWT.SINGLE); + this.tree.setLayoutData(treeGrid); + + TreeItem tmp; + for(YalpFile aFile : model.getDir("/")){ + tmp = new TreeItem(this.tree, SWT.NULL); + tmp.setText(aFile.name); + if(aFile.isDir) tmp.setImage(new Image(display1, "folder.gif")); + else tmp.setImage(new Image(display1, "yalpV2_klein.gif")); + } + + this.tree.addSelectionListener ( + new SelectionAdapter() { + + public void widgetSelected(SelectionEvent e) { + String path = getPath(); + if(!alreadyBrowsed.contains(path)){ + alreadyBrowsed.add(path); + TreeItem tmp; + for(YalpFile aFile : model.getDir(path)){ + tmp = new TreeItem(tree.getSelection()[0],SWT.NULL); + tmp.setText(aFile.name); + if(aFile.isDir) tmp.setImage(new Image(display1, "folder.gif")); + else tmp.setImage(new Image(display1, "yalpV2_klein.gif")); + tmp.getParentItem().setExpanded(true); + } + } + } + } + ); + + GridData buttonGrid1 = new GridData(); + buttonGrid1.horizontalSpan = 1; + + this.add = new Button(this.shell, SWT.PUSH); + this.add.setText("Indicate"); + this.add.setLayoutData(buttonGrid1); + this.add.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + model.addDir(getPath()); + parentEnable(true); + shell.setVisible(false); + } + }); + + GridData buttonGrid2 = new GridData(); + buttonGrid2.horizontalSpan = 1; + buttonGrid2.horizontalAlignment = SWT.END; + + this.cancel = new Button(this.shell, SWT.PUSH); + this.cancel.setText("Cancel"); + this.cancel.setLayoutData(buttonGrid2); + this.cancel.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + parentEnable(true); + shell.setVisible(false); + } + }); + } + + public void show(){ + parentEnable(false); + Point size=this.getSize(); + Rectangle parentRec=((Shell)this.parentComposite).getBounds(); + Rectangle thisRec=this.shell.computeTrim(parentRec.x+(parentRec.width/2)-(size.x/2),parentRec.y+(parentRec.height/2)-(size.y/2),size.x,size.y); + shell.setBounds(thisRec); + shell.open(); + while(!shell.isDisposed()){ + if(!this.display1.readAndDispatch()) this.display1.sleep(); + } + this.display1.dispose(); + } + + private String getPath(){ + TreeItem actualItem = tree.getSelection()[0]; + String path = "/"+tree.getSelection()[0].getText(); + while(actualItem.getParentItem() != null){ + actualItem = actualItem.getParentItem(); + path = "/" + actualItem.getText() + path; + } + return path; + } + private void parentEnable(boolean bool){ + parentComposite.setEnabled(bool); + } +} diff --git a/removed-code/Client.java b/removed-code/Client.java new file mode 100755 index 0000000..a945f48 --- /dev/null +++ b/removed-code/Client.java @@ -0,0 +1,48 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient;
+import YalpClients.SwtClient.GUI.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/*
+ * Class Client
+ *
+ * <em>Instances Model, LoadDialog and StartDialog</em>
+ *
+ * @author Volker Dahnke
+ *
+ * @version 1 02-04-2006<br>
+ */
+ public class Client implements Runnable{
+
+/*
+ * enables the Class to be loaded dynamicly.
+ * Instances Model, LoadDialog and StartDialog.
+ */
+
+ public void run () {
+
+ LoadDialog load = new LoadDialog(
+ new Shell(Display.getDefault(),SWT.NONE), SWT.NONE);
+
+ load.show();
+ final Model model = new Model();
+ load.close();
+
+ StartDialog start =
+ new StartDialog(new Shell(Display.getDefault(),SWT.MIN),model, SWT.NONE);
+
+ start.show();
+ }
+}
diff --git a/server.policy b/server.policy new file mode 100644 index 0000000..e07e45d --- /dev/null +++ b/server.policy @@ -0,0 +1,8 @@ +grant {
+ permission java.io.FilePermission "<<ALL FILES>>","execute, read, write";
+ permission java.io.FilePermission "C:\\Programme\\VideoLAN\\VLC\\vlc","execute";
+ permission java.io.FilePermission "/Applications/VLC.app/Contents/MacOS/VLC","execute";
+ permission java.net.SocketPermission "*:1024-","connect,accept,resolve";
+ permission java.util.PropertyPermission "id3.default_language", "read";
+ permission java.util.PropertyPermission "id3.default_encoding", "read";
+};
diff --git a/server.sh b/server.sh new file mode 100755 index 0000000..585302a --- /dev/null +++ b/server.sh @@ -0,0 +1,4 @@ +/opt/sun-jdk-1.6.0.07/bin/orbd -ORBInitialPort 1050 & +sleep 2 +java -Djava.library.path=./lib -jar yalpServer.jar -ORBInitialPort 1050 -ORBInitialHost localhost +killall -9 orbd diff --git a/src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java b/src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java new file mode 100644 index 0000000..5ff92c7 --- /dev/null +++ b/src/YalpAuth/YalpPGSqlAuth/DatabaseDefines.java @@ -0,0 +1,65 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+package YalpAuth.YalpPGSqlAuth;
+
+/*
+ * Class DatabaseDefines
+ *
+ * <em></em>
+ *
+ * @author Manuel Traut
+ *
+ * @version 0.1 28-08-2008<br>
+ *
+ */
+
+public class DatabaseDefines {
+
+ public String dbConnection="jdbc:postgresql://10.0.3.20:5432/yalp_user";
+ public String dbUser="yalp";
+ public String dbPasswd="huhu";
+
+/*
+ * set string for dbConnection
+ * @param dbConnection
+ * "jdbc:postgresql://<serverIP>:<portOfDB>/<dataBaseName>";
+ */
+ public void setDBConnection(String dbConnection){
+ this.dbConnection = dbConnection;
+ }
+
+/*
+ * set userName for db Edit
+ * @param dbUser
+ */
+ public void setDBUser(String dbUser){
+ this.dbUser = dbUser;
+ }
+
+/*
+ * set string for db Password
+ * @param DBPasswd
+ */
+ public void setDBPasswd(String DBPasswd){
+ this.dbPasswd = DBPasswd;
+ }
+
+ public String getDBConnection(){
+ return this.dbConnection;
+ }
+
+ public String getDBUser(){
+ return this.dbUser;
+ }
+
+ public String getDBPasswd(){
+ return this.dbPasswd;
+ }
+}
diff --git a/src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java b/src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java new file mode 100644 index 0000000..b87bce3 --- /dev/null +++ b/src/YalpAuth/YalpPGSqlAuth/YalpAuthInterfaceImpl.java @@ -0,0 +1,137 @@ +package YalpAuth.YalpPGSqlAuth; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.*; +import java.sql.*; + +import YalpInterfaces.*; + +public class YalpAuthInterfaceImpl { + private String db; + private String dbuser; + private String dbpasswd; + private Statement stat; + private Connection con; + +/* + * Constructor establishes connection to Database Server + * + * @param db + * jdbc Connection to database + * @param dbYalpUser + * userName for database + * @param dbPasswd + * password for database + */ + public YalpAuthInterfaceImpl(String db, String dbYalpUser, String dbPasswd) { + try{ + this.dbuser = dbYalpUser; + this.dbpasswd = dbPasswd; + Class.forName("org.postgresql.Driver"); + con = DriverManager.getConnection(db,dbuser,dbpasswd); + System.out.println("YalpAuth: PGSQL connection established"); + this.stat= con.createStatement(); + } catch (SQLException e) { + System.out.println("Exception in DbConnection Constructor: "+e); + } catch (ClassNotFoundException e) { + System.out.println("Exception in DbConnection Constructor: "+e); + } + } + +/* + * checks if user exists in yalpYalpUser Database and what rights he has + * + * @param username + * username to check + * @param passwd + * password to check + * + * @return enum privilege level + */ + public int userVerify(String username,String passwd) { + try{ + ResultSet result=stat.executeQuery("select * from \"user\" where \"username\" = '"+username+"' and \"passwd\" = '"+passwd+"';"); + + if (result.next()){ + if (result.getBoolean(5)==true){ + return 2; + }else return 1; + }else return 0; + }catch (SQLException e){ + System.out.println("Exception in DbConnection.userVerify: "+e); + return 0; + } + } + +/* + * returns an ArrayList with all yalpYalpUsers and Admins + * + * @return ArrayList<YalpUser> + * list with all YalpYalpUsers and Admins + */ + public void getUser(UsersHolder list, YalpErrorHolder err) { + try { + ArrayList<YalpUser> resultList =new ArrayList<YalpUser>(); + YalpUser actUser = new YalpUser(); + String query = "select * from \"user\"order by \"id\";"; + Statement stat= con.createStatement(); + ResultSet result=stat.executeQuery(query); + + while(result.next()) + { + /* t.b.d. - create YalpUser according to new database design */ + // result.getInt(1),result.getString(2),result.getString(3),result.getString(4),result.getBoolean(5))) + resultList.add( actUser ); + } + YalpUser[] u = new YalpUser[1]; + list = new UsersHolder(resultList.toArray(u)); + } catch (SQLException e) { + YalpError error = new YalpError(); + error.code = YalpErrorCode.ERROR_SQL; + error.descr = e.toString(); + error.level = YalpErrorLevel.ERROR_LEVEL_ERROR; + err = new YalpErrorHolder(error); + } + } + +/* + * submits changes to yalpYalpUserDatabase + * + * @param change + * describes the change to commit + * @return int + * -1 if failed + */ + public void changeUser(YalpUser usr, String passwd, Action todo, + YalpError err) { + + /* t.b.d. alter to new db design + try{ + String sql; + switch (todo.type){ + // if updateType is UPDATE + case Action._UPDATE: + sql="update \"user\" set \"username\"='"+usr.name+"', \"passwd\"='"+change.passwd+"', \"realname\"='"+change.realname+"', \"admin\"="+change.admin+" where \"id\"= "+change.id+" ;"; + break; + // if updateType is INSERT INTO + case Action._INSERT: + sql="insert into \"user\" values(nextval('userId'), '"+usr+"','"+change.passwd+"','"+change.realname+"',"+change.admin+");"; + break; + // if updateType is DELETE + case Action._DELETE: + sql="delete from \"user\" where \"id\"= "+change.id+" ;"; + break; + default: + //errorhandling + } + // perform operation on table an return number of updated rows + System.out.println(sql); + return stat.executeUpdate(sql); + }catch(SQLException e){ + System.out.println("Exception in DbConnection.changeYalpUser: "+e); + } + */ + } +} diff --git a/src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java b/src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java new file mode 100644 index 0000000..53ddde1 --- /dev/null +++ b/src/YalpAuth/YalpPGSqlAuth/YalpPGSqlAuth.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpAuth.YalpPGSqlAuth; + +import YalpInterfaces.*; + +/* + * Class YalpPGSqlAuth + * + * <em>Implements functionality of the DBConnectionInterface</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006<br> + */ + +public class YalpPGSqlAuth { + private YalpAuthInterfaceImpl con; + private DatabaseDefines config; + + public static void main(String[] args) + { + System.out.println("YalpPGSqlAuth\n"); + } +} diff --git a/src/YalpClients/ClientConfiguration.java b/src/YalpClients/ClientConfiguration.java new file mode 100755 index 0000000..7e39e78 --- /dev/null +++ b/src/YalpClients/ClientConfiguration.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ +package YalpClients; + +/* + * Class ClientSettings + * + * <em>handles Settings of the yalpClient</em> + * + * @author Manuel Traut, Volker Dahnke + * + * @version 0.1 18-03-2006<br> + * + * @see client + */ + +public class ClientConfiguration{ + static final long serialVersionUID = 0; + public String serverIP = "localhost"; + public Integer classServerPort = 5002; + public Integer registryPort = 5001; + public String vlcCommand = "vlc"; + +/* + * sets IP of yalp Server to connect to + * + * @param serverIP + * ip of yalpServer + */ + public void setserverIP(String serverIP){ + this.serverIP = serverIP; + } + +/* + * sets Port of yalp ClassServer to get Client-classFiles from + * + * @param classServerPort + * port of classServer + */ + public void setclassServerPort(int classServerPort){ + this.classServerPort = classServerPort; + } + +/* + * sets Port where RMI Registry can be found + * + * @param registryPort + * port of RMI Registry + */ + public void setregistryPort(int registryPort){ + this.registryPort = registryPort; + } + +/* + * sets Command how vlcPlayer on Client can be started + * on some hardware it can be useful, to commit not only: + * <path to vlc installation>/<name of vlc executable> + * but also path, executable and <params> like --alsadev hw0,0 + * @param vlcCommand + * for a perfectly running vlc on the client + */ + public void setvlcCommand(String vlcCommand){ + this.vlcCommand = vlcCommand; + } + +/* + * returns the ip of the yalpServer + * + * @return String + * ip of yalpServer + */ + public String getserverIP(){ + return this.serverIP; + } + +/* + * returns port of the yalpClassServer + * + * @return int + * port of yalpClassServer + */ + public int getclassServerPort(){ + return this.classServerPort; + } + +/* + * returns port of RMI Registry + * + * @return int + * Port of RMI Registry + */ + public int getregistryPort(){ + return this.registryPort; + } + +/* + * returns command to start vlc Player on client + * + * @return String + * Command + */ + public String getvlcCommand(){ + return this.vlcCommand; + } + +} diff --git a/src/YalpClients/SwtClient/GUI/GUI.java b/src/YalpClients/SwtClient/GUI/GUI.java new file mode 100644 index 0000000..4c0e474 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/GUI.java @@ -0,0 +1,2101 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient.GUI;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.events.*;
+import java.util.*;
+
+import YalpInterfaces.*;
+import YalpClients.SwtClient.*;
+
+/*
+ *
+ * Class GUI
+ *
+ * <em></em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 1 02-04-2006<br>
+ *
+ */
+public class GUI extends org.eclipse.swt.widgets.Composite {
+
+ public Model model;
+ public Composite resultComposite;
+ public Composite playlistComposite;
+ public Composite bottemComposite;
+ public Table resultTable1;
+ public Table resultTable2;
+ public Composite composite1;
+ public Composite changeComposite;
+ public Table UserTable;
+ public Composite composite3;
+
+ private AccessRights userKind;
+ private StyledText styledText1;
+ private CTabFolder cTabFolder1;
+ private CTabItem tab1;
+ private Composite container1;
+ private Composite topComposite;
+ private Group find;
+ private Group logo;
+ private CTabItem tab2;
+ private Composite container2;
+ private Group group1;
+ private Group group2;
+ private CLabel authorLabel;
+ private CLabel titleLabel;
+ private CLabel streamLabel2;
+ private CLabel actualStreamLabel2;
+ private CLabel actualStreamLabel1;
+ private CLabel streamLabel1;
+ private CLabel data2;
+ private CLabel data1;
+ private Button shutdown;
+ private TableColumn ip;
+ private TableColumn userName;
+ public Table iptable;
+ private Composite composite4;
+
+ private Button submitButton;
+ private CLabel adminAddLabel;
+ private CLabel passwdAddLable;
+ private CLabel usernameAddLable;
+ private CLabel realnameAddLabel;
+ private CCombo adminAdd;
+ private Text realnameAdd;
+ private Text passwdAdd;
+ private Text usernameAdd;
+ private Group tab3group5;
+ private Button next;
+ private Button stop;
+ private Button play;
+ private CLabel cLabel2;
+ private Button save;
+ private Text userTableId;
+ private Text passwd;
+ private Text username;
+ private Text userTableName;
+ private CLabel adminLabel;
+ private CCombo adminCombo;
+ private CLabel nameLable;
+ private CLabel passwdLable;
+ private CLabel usernameLable;
+ private CLabel idLable;
+ private Group tab3group4;
+ private Button delete;
+ private Button add1;
+ private Group tab3Group3;
+ private Group tab3Group2;
+ private Group tab3Group1;
+ private Composite container3;
+ private Button deleteButton;
+ private Button addButton;
+ private StyledText status;
+ private Button saveButton;
+ private Text id;
+ private CLabel idLabel;
+ private CLabel cLabel1;
+ private CLabel nameLabel;
+ private CLabel pathLabel;
+ private CLabel lastEditLable;
+ private CLabel ownerIdLabel;
+ private CLabel resolutionLabel;
+ private CLabel vBitrateLabel;
+ private CLabel aBitrateLabel;
+ private CLabel durationLabel;
+ private CLabel yearLabel;
+ private CLabel categoryLabel;
+ private CLabel albumLabel;
+ private CCombo type;
+ private Text name;
+ private Text path;
+ private Text lastEdit;
+ private Text ownerId;
+ private Text resolution;
+ private Text vBitrate;
+ private Text aBitrate;
+ private Text duration;
+ private Text year;
+ private Text category;
+ private Text album;
+ private Text author;
+ private Text title;
+ private Composite composite2;
+ private Table playlistTable;
+ private Button add2;
+ private Button del;
+ private Boolean isNotPlaying=true;
+ private Boolean paused =true;
+ private CTabItem tab3;
+ private Composite parent;
+ private Display display;
+ final Image pauseImage=new Image(this.getDisplay(),"img/pause.gif");
+ final Image playImage=new Image(this.getDisplay(),"img/play.gif");
+ final Image forwardImage=new Image(this.getDisplay(),"img/forward.gif");
+ {
+ //Register as a resource user - SWTResourceManager will
+ //handle the obtaining and disposing of resources
+ SWTResourceManager.registerResourceUser(this);
+ }
+
+ public GUI( Composite parent, Display display, Model model,
+ AccessRights userKind, int style ) {
+
+ super(parent, style);
+
+ this.parent = parent;
+ this.display = display;
+ this.model = model;
+ this.userKind = userKind;
+
+ initGUI();
+ }
+
+ private void initGUI() {
+ try {
+ this.setSize(800, 600);
+ this.setBackground(SWTResourceManager.getColor(192, 192, 192));
+ GridLayout thisLayout = new GridLayout(1, true);
+ thisLayout.marginWidth = 5;
+ thisLayout.marginHeight = 5;
+ thisLayout.numColumns = 1;
+ thisLayout.makeColumnsEqualWidth = true;
+ thisLayout.horizontalSpacing = 5;
+ thisLayout.verticalSpacing = 5;
+ this.setLayout(thisLayout);
+
+ {
+ if (this.userKind.value() == AccessRights._USER){
+ cTabFolder1 = new CTabFolder(this, SWT.NONE);
+ GridData cTabFolder1LData = new GridData();
+ cTabFolder1LData.widthHint = 787;
+ cTabFolder1LData.heightHint = 568;
+ cTabFolder1.setLayoutData(cTabFolder1LData);
+ {
+ tab1 = new CTabItem(cTabFolder1,SWT.NONE);
+ tab1.setText("Find");
+ {
+ container1 = new Composite(cTabFolder1,SWT.NONE);
+ tab1.setControl(container1);
+ RowLayout container1Layout = new RowLayout(org.eclipse.swt.SWT.HORIZONTAL);
+ container1.setLayout(container1Layout);
+ {
+ topComposite = new Composite(container1,SWT.NONE);
+ GridLayout topCompositeLayout = new GridLayout();
+ topCompositeLayout.makeColumnsEqualWidth = true;
+ topCompositeLayout.numColumns = 2;
+ topCompositeLayout.verticalSpacing = 2;
+ topCompositeLayout.horizontalSpacing = 5;
+ topComposite.setLayout(topCompositeLayout);
+ RowData topCompositeLData = new RowData();
+ topCompositeLData.width = 783;
+ topCompositeLData.height = 566;
+ topComposite.setLayoutData(topCompositeLData);
+ {
+ find = new Group(topComposite,SWT.NONE);
+ this.find(find,resultComposite,playlistComposite,bottemComposite,1);
+ }
+ {
+ logo = new Group(topComposite,SWT.NONE);
+ this.logo(logo);
+ }
+ {
+ resultComposite = new Composite(topComposite,SWT.NONE);
+ resultTable1 = new Table(resultComposite,SWT.MULTI|SWT.FULL_SELECTION);
+ resultTable1.setToolTipText("Medias");
+ resultTable1.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ add2.setEnabled(true);
+ }
+ });
+ this.resultTable(resultComposite,resultTable1,1);
+ }
+ {
+ playlistComposite = new Composite(topComposite,SWT.NONE);
+ FormLayout playlistCompositeLayout = new FormLayout();
+ playlistComposite.setLayout(playlistCompositeLayout);
+ GridData playlistCompositeLData = new GridData();
+ playlistCompositeLData.heightHint = 390;
+ playlistCompositeLData.horizontalAlignment = GridData.FILL;
+ playlistComposite.setLayoutData(playlistCompositeLData);
+ playlistComposite.setVisible(false);
+ playlistComposite.setSize(238, 390);
+ {
+ next = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData nextLData = new FormData();
+ nextLData.width = 45;
+ nextLData.height = 21;
+ nextLData.left = new FormAttachment(0, 1000, 185);
+ nextLData.top = new FormAttachment(0, 1000, 365);
+ next.setLayoutData(nextLData);
+ next.setEnabled(false);
+ next.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ next.setToolTipText("play next Title");
+ next.setImage(forwardImage);
+ next.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ model.next();
+ }
+ });
+ }
+ {
+ stop = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData stopLData = new FormData();
+ stopLData.width = 35;
+ stopLData.height = 21;
+ stopLData.left = new FormAttachment(0, 1000, 91);
+ stopLData.top = new FormAttachment(0, 1000, 365);
+ stop.setLayoutData(stopLData);
+ stop.setImage(new Image(this.getDisplay(),"img/stop.gif"));
+ stop.setEnabled(false);
+ stop.setToolTipText("stop");
+ stop.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if (model.stop()){
+ play.setEnabled(true);
+ next.setEnabled(false);
+ stop.setEnabled(false);
+ play.setImage(playImage);
+ play.setToolTipText("play");
+ isNotPlaying=true;
+ }
+
+ }
+ });
+ }
+ {
+ play = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData playLData = new FormData();
+ playLData.width = 35;
+ playLData.height = 21;
+ playLData.left = new FormAttachment(0, 1000, 50);
+ playLData.top = new FormAttachment(0, 1000, 365);
+ play.setLayoutData(playLData);
+ play.setImage(playImage);
+ play.setEnabled(false);
+ play.setToolTipText("play");
+ play.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ stop.setEnabled(true);
+ if (playlistTable.getItemCount()>1)next.setEnabled(true);
+ del.setEnabled(false);
+ //add2.setEnabled(false);
+ if (isNotPlaying){
+ play.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_WAIT));
+ if(model.play()){
+ play.setImage(pauseImage);
+ play.setToolTipText("pause");
+ play.setCursor(SWTResourceManager.getCursor(SWT.NONE));
+ isNotPlaying= false;
+ }else;
+ }else{
+ if(model.pause()){
+ if (paused){
+ play.setImage(playImage);
+ play.setToolTipText("play");
+ paused=false;
+ }else{
+ play.setImage(pauseImage);
+ play.setToolTipText("pause");
+ paused=true;
+ }
+ }else;
+ }
+
+ }
+ });
+ }
+ {
+ add2 = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData addLData = new FormData();
+ addLData.width = 25;
+ addLData.height = 21;
+ addLData.left = new FormAttachment(0, 1000, 2);
+ addLData.top = new FormAttachment(0, 1000, 160);
+ add2.setLayoutData(addLData);
+ add2.setText(">>");
+ add2.setEnabled(false);
+ add2.setToolTipText("add to Playlist");
+ add2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ add2.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if (System.getProperty("os.name")== "Mac OS X"){
+ for (int i=resultTable1.getSelectionCount()-1;i>=0;i--){
+ int id=new Integer(resultTable1.getSelection()[i].getText(0)).intValue();
+ System.out.println(resultTable1.getSelection()[i].getText(1));
+ model.add2PlayList(id);
+ }
+ }else{
+ for (int i=0;i<resultTable1.getSelectionCount();i++){
+ int id=new Integer(resultTable1.getSelection()[i].getText(0)).intValue();
+ System.out.println(resultTable1.getSelection()[i].getText(1));
+ model.add2PlayList(id);
+ }
+ }
+ while(playlistTable.getItemCount()!=0){
+ playlistTable.remove(0);
+ }
+ ArrayList<Media> playlist=model.getToPlaylist();
+ for(int i=0;i<playlist.size();i++){
+ Media result=playlist.get(i);
+ TableItem item = new TableItem(playlistTable,SWT.NONE);
+ item.setText(0,result.name);
+ item.setText(1,result.duration);
+ }
+ play.setEnabled(true);
+ if (playlistTable.getItemCount()>1&& !isNotPlaying)next.setEnabled(true);
+ }
+ });
+ }
+ {
+ del = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData delLData = new FormData();
+ delLData.width = 25;
+ delLData.height = 21;
+ delLData.left = new FormAttachment(0, 1000, 2);
+ delLData.top = new FormAttachment(0, 1000, 200);
+ del.setLayoutData(delLData);
+ del.setEnabled(false);
+ del.setToolTipText("del from Playlist");
+ del.setText("<<");
+ del.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ del.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ for (int i=playlistTable.getSelectionCount()-1;i>=0;i--){
+ int pos = playlistTable.getSelectionIndices()[i];
+ model.removeFromPlayList(pos);
+ }
+
+ del.setEnabled(false);
+ while(playlistTable.getItemCount()!=0){
+ playlistTable.remove(0);
+ }
+ ArrayList<Media> playlist=model.getToPlaylist();
+ for(int i=0;i<playlist.size();i++){
+ Media result=playlist.get(i);
+ TableItem item = new TableItem(playlistTable,SWT.NONE);
+ item.setText(0,result.name);
+ item.setText(1,result.duration);
+ }
+ if (playlistTable.getItemCount()==0)play.setEnabled(false);
+ }
+ });
+ }
+ {
+ playlistTable = new Table(playlistComposite,SWT.MULTI|SWT.FULL_SELECTION);
+ playlistTable.setHeaderVisible(true);
+ FormData playlistTableLData = new FormData();
+ playlistTableLData.width = 184;
+ playlistTableLData.height = 330;
+ playlistTableLData.top = new FormAttachment(24, 1000, 0);
+ playlistTableLData.left = new FormAttachment(0, 1000, 38);
+ playlistTable.setLayoutData(playlistTableLData);
+ playlistTable.setToolTipText("Playlist");
+ playlistTable.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if (isNotPlaying)del.setEnabled(true);
+ }
+ });
+ TableColumn title = new TableColumn(playlistTable,SWT.LEFT);
+ title.setText("Title");
+ title.setWidth(120);
+ title.setMoveable(true);
+ TableColumn duration = new TableColumn(playlistTable,SWT.RIGHT);
+ duration.setText("Duration");
+ duration.setWidth(80);
+ duration.setMoveable(true);
+ }
+ }
+ }
+ /*{
+ bottemComposite = new Composite(container1,SWT.NONE);
+ bottemComposite.setVisible(false);
+ GridLayout bottemCompositeLayout = new GridLayout();
+ bottemCompositeLayout.makeColumnsEqualWidth = true;
+ bottemCompositeLayout.verticalSpacing = 2;
+ bottemCompositeLayout.horizontalSpacing = 5;
+ bottemComposite.setLayout(bottemCompositeLayout);
+ RowData bottemCompositeLData = new RowData();
+ bottemCompositeLData.width = 777;
+ bottemCompositeLData.height = 68;
+ bottemComposite.setLayoutData(bottemCompositeLData);
+ {
+ styledText1 = new StyledText(bottemComposite,SWT.NONE);
+ GridData styledText1LData = new GridData();
+ styledText1LData.widthHint = 765;
+ styledText1LData.heightHint = 55;
+ styledText1.setLayoutData(styledText1LData);
+ styledText1.setText("styledText1");
+ styledText1.setSize(765, 55);
+ }
+ }*/
+ }
+ }
+ {
+ tab2 = new CTabItem(cTabFolder1,SWT.NONE);
+ tab2.setText("Change");
+ {
+ container2 = new Composite(cTabFolder1,SWT.NONE);
+ GridLayout container2Layout = new GridLayout();
+ container2Layout.makeColumnsEqualWidth = true;
+ container2.setLayout(container2Layout);
+ tab2.setControl(container2);
+ container2.setVisible(false);
+ {
+ composite2 = new Composite(container2,SWT.NONE);
+ GridLayout composite2Layout = new GridLayout();
+ composite2Layout.makeColumnsEqualWidth = true;
+ composite2Layout.numColumns=2;
+ composite2.setLayout(composite2Layout);
+ GridData composite2LData = new GridData();
+ composite2LData.widthHint = 780;
+ composite2LData.heightHint = 497;
+ composite2.setLayoutData(composite2LData);
+ {
+ group1 = new Group(composite2,SWT.NONE);
+ this.find(group1,group2,composite1,changeComposite,2);
+ }
+ {
+ group2 = new Group(composite2,SWT.NONE);
+ this.logo(group2);
+ }
+ {
+ composite1 = new Composite(composite2,SWT.NONE);
+ {
+ resultTable2 = new Table(composite1,SWT.MULTI|SWT.FULL_SELECTION);
+ resultTable2.setToolTipText("Medias");
+ resultTable2.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if(resultTable2.getSelectionCount()<2){
+ int identity =new Integer(resultTable2.getSelection()[0].getText()).intValue();
+ Media result = model.getMediaWithId(identity,2);
+ if (result!=null){
+ id.setText(new Integer(result.id).toString());
+ title.setText(result.name);
+ /* t.b.d. parse from string props
+ author.setText(result.author);
+ album.setText(result.album);
+ category.setText(result.category);
+ year.setText(result.year);
+ */
+ duration.setText(result.duration);
+ /*
+ aBitrate.setText(new Integer(result.aBitrate).toString());
+ vBitrate.setText(new Integer(result.vBitrate).toString());
+ resolution.setText(result.resolution);
+ */
+ ownerId.setText(result.owner.name);
+ lastEdit.setText(result.lastEdit);
+ path.setText(result.path);
+ name.setText(result.name);
+ String _type = model.getTypeName(result.type);
+ type.setText(_type);
+ changeComposite.setVisible(true);
+ deleteButton.setVisible(true);
+ }
+ }else changeComposite.setVisible(false);
+ }
+ });
+ this.resultTable(composite1,resultTable2,2);
+ }
+ }
+ {
+ changeComposite = new Composite(composite2,SWT.NONE);
+ FormLayout changeCompositeLayout = new FormLayout();
+ changeComposite.setLayout(changeCompositeLayout);
+ GridData changeCompositeLData = new GridData();
+ changeCompositeLData.widthHint = 238;
+ changeCompositeLData.heightHint = 357;
+ changeCompositeLData.verticalAlignment = GridData.BEGINNING;
+ changeComposite.setLayoutData(changeCompositeLData);
+ changeComposite.setVisible(false);
+ {
+ saveButton = new Button(changeComposite,SWT.PUSH | SWT.CENTER);
+ saveButton.setText("Save");
+ FormData saveButtonLData = new FormData();
+ saveButtonLData.width = 40;
+ saveButtonLData.height = 21;
+ saveButtonLData.left = new FormAttachment(0, 1000, 30);
+ saveButtonLData.top = new FormAttachment(0, 1000, 315);
+ saveButton.setLayoutData(saveButtonLData);
+ saveButton.setToolTipText("save Changes");
+ saveButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ saveButtonWidgetSelected(evt);
+ }
+ });
+ }
+ {
+ id = new Text(changeComposite,SWT.NONE);
+ FormData idLData = new FormData();
+ idLData.width = 124;
+ idLData.height = 14;
+ idLData.left = new FormAttachment(0, 1000, 100);
+ idLData.top = new FormAttachment(0, 1000, 10);
+ id.setLayoutData(idLData);
+ id.setEditable(false);
+ }
+ {
+ idLabel = new CLabel(changeComposite,SWT.NONE);
+ idLabel.setText("Id:");
+ FormData idLabelLData = new FormData();
+ idLabelLData.width = 60;
+ idLabelLData.height = 21;
+ idLabelLData.left = new FormAttachment(0, 1000, 20);
+ idLabelLData.top = new FormAttachment(0, 1000, 5);
+ idLabel.setLayoutData(idLabelLData);
+ }
+ {
+ cLabel1 = new CLabel(changeComposite,SWT.NONE);
+ cLabel1.setText("Type:");
+ FormData cLabel1LData = new FormData();
+ cLabel1LData.width = 60;
+ cLabel1LData.height = 21;
+ cLabel1LData.left = new FormAttachment(0, 1000, 20);
+ cLabel1LData.top = new FormAttachment(0, 1000, 285);
+ cLabel1.setLayoutData(cLabel1LData);
+ }
+ {
+ nameLabel = new CLabel(changeComposite,SWT.NONE);
+ nameLabel.setText("Name:");
+ FormData nameLabelLData = new FormData();
+ nameLabelLData.width = 60;
+ nameLabelLData.height = 21;
+ nameLabelLData.left = new FormAttachment(0, 1000, 20);
+ nameLabelLData.top = new FormAttachment(0, 1000, 265);
+ nameLabel.setLayoutData(nameLabelLData);
+ }
+ {
+ pathLabel = new CLabel(changeComposite,SWT.NONE);
+ pathLabel.setText("Path:");
+ FormData pathLabelLData = new FormData();
+ pathLabelLData.width = 60;
+ pathLabelLData.height = 21;
+ pathLabelLData.left = new FormAttachment(0, 1000, 20);
+ pathLabelLData.top = new FormAttachment(0, 1000, 245);
+ pathLabel.setLayoutData(pathLabelLData);
+ }
+ {
+ lastEditLable = new CLabel(changeComposite,SWT.NONE);
+ lastEditLable.setText("Last Edit:");
+ FormData lastEditLableLData = new FormData();
+ lastEditLableLData.width = 60;
+ lastEditLableLData.height = 21;
+ lastEditLableLData.left = new FormAttachment(0, 1000, 20);
+ lastEditLableLData.top = new FormAttachment(0, 1000, 225);
+ lastEditLable.setLayoutData(lastEditLableLData);
+ }
+ {
+ ownerIdLabel = new CLabel(changeComposite,SWT.NONE);
+ ownerIdLabel.setText("Owner:");
+ FormData ownerIdLabelLData = new FormData();
+ ownerIdLabelLData.width = 60;
+ ownerIdLabelLData.height = 21;
+ ownerIdLabelLData.left = new FormAttachment(0, 1000, 20);
+ ownerIdLabelLData.top = new FormAttachment(0, 1000, 205);
+ ownerIdLabel.setLayoutData(ownerIdLabelLData);
+ }
+ {
+ resolutionLabel = new CLabel(changeComposite,SWT.NONE);
+ resolutionLabel.setText("Resolution:");
+ FormData resolutionLabelLData = new FormData();
+ resolutionLabelLData.width = 60;
+ resolutionLabelLData.height = 21;
+ resolutionLabelLData.left = new FormAttachment(0, 1000, 20);
+ resolutionLabelLData.top = new FormAttachment(0, 1000, 185);
+ resolutionLabel.setLayoutData(resolutionLabelLData);
+ }
+ {
+ vBitrateLabel = new CLabel(changeComposite,SWT.NONE);
+ vBitrateLabel.setText("V-Bitrate:");
+ FormData vBitrateLabelLData = new FormData();
+ vBitrateLabelLData.width = 60;
+ vBitrateLabelLData.height = 21;
+ vBitrateLabelLData.left = new FormAttachment(0, 1000, 20);
+ vBitrateLabelLData.top = new FormAttachment(0, 1000, 165);
+ vBitrateLabel.setLayoutData(vBitrateLabelLData);
+ }
+ {
+ aBitrateLabel = new CLabel(changeComposite,SWT.NONE);
+ aBitrateLabel.setText("A-Bitrate:");
+ FormData aBitrateLabelLData = new FormData();
+ aBitrateLabelLData.width = 60;
+ aBitrateLabelLData.height = 21;
+ aBitrateLabelLData.left = new FormAttachment(0, 1000, 20);
+ aBitrateLabelLData.top = new FormAttachment(0, 1000, 145);
+ aBitrateLabel.setLayoutData(aBitrateLabelLData);
+ }
+ {
+ durationLabel = new CLabel(changeComposite,SWT.NONE);
+ durationLabel.setText("Duration:");
+ FormData durationLabelLData = new FormData();
+ durationLabelLData.width = 60;
+ durationLabelLData.height = 21;
+ durationLabelLData.left = new FormAttachment(0, 1000, 20);
+ durationLabelLData.top = new FormAttachment(0, 1000, 125);
+ durationLabel.setLayoutData(durationLabelLData);
+ }
+ {
+ yearLabel = new CLabel(changeComposite,SWT.NONE);
+ yearLabel.setText("Year:");
+ FormData yearLabelLData = new FormData();
+ yearLabelLData.width = 60;
+ yearLabelLData.height = 21;
+ yearLabelLData.left = new FormAttachment(0, 1000, 20);
+ yearLabelLData.top = new FormAttachment(0, 1000, 105);
+ yearLabel.setLayoutData(yearLabelLData);
+ }
+ {
+ categoryLabel = new CLabel(changeComposite,SWT.NONE);
+ categoryLabel.setText("Category:");
+ FormData categoryLabelLData = new FormData();
+ categoryLabelLData.width = 60;
+ categoryLabelLData.height = 21;
+ categoryLabelLData.left = new FormAttachment(0, 1000, 20);
+ categoryLabelLData.top = new FormAttachment(0, 1000, 85);
+ categoryLabel.setLayoutData(categoryLabelLData);
+ }
+ {
+ albumLabel = new CLabel(changeComposite,SWT.NONE);
+ albumLabel.setText("Album");
+ FormData albumLabelLData = new FormData();
+ albumLabelLData.width = 60;
+ albumLabelLData.height = 21;
+ albumLabelLData.left = new FormAttachment(0, 1000, 20);
+ albumLabelLData.top = new FormAttachment(0, 1000, 65);
+ albumLabel.setLayoutData(albumLabelLData);
+ }
+ {
+ authorLabel = new CLabel(changeComposite,SWT.NONE);
+ authorLabel.setText("Author:");
+ FormData authorLabelLData = new FormData();
+ authorLabelLData.width = 60;
+ authorLabelLData.height = 21;
+ authorLabelLData.left = new FormAttachment(0, 1000, 20);
+ authorLabelLData.top = new FormAttachment(0, 1000, 45);
+ authorLabel.setLayoutData(authorLabelLData);
+ }
+ {
+ titleLabel = new CLabel(changeComposite,SWT.NONE);
+ titleLabel.setText("Title:");
+ FormData cLabel1LData1 = new FormData();
+ cLabel1LData1.width = 60;
+ cLabel1LData1.height = 21;
+ cLabel1LData1.left = new FormAttachment(0, 1000, 20);
+ cLabel1LData1.top = new FormAttachment(0, 1000, 25);
+ titleLabel.setLayoutData(cLabel1LData1);
+ }
+ {
+ type = new CCombo(changeComposite,SWT.NONE);
+ FormData typeLData = new FormData();
+ typeLData.width = 111;
+ typeLData.height = 16;
+ typeLData.left = new FormAttachment(0, 1000, 100);
+ typeLData.top = new FormAttachment(0, 1000, 290);
+ type.setLayoutData(typeLData);
+ type.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
+ {
+ type.add("audio");
+ type.add("video");
+ }
+ }
+ {
+ name = new Text(changeComposite,SWT.NONE);
+ FormData nameLData = new FormData();
+ nameLData.width = 124;
+ nameLData.height = 14;
+ nameLData.left = new FormAttachment(0, 1000, 100);
+ nameLData.top = new FormAttachment(0, 1000, 270);
+ name.setLayoutData(nameLData);
+ name.setEditable(false);
+ }
+ {
+ path = new Text(changeComposite,SWT.NONE);
+ FormData pathLData = new FormData();
+ pathLData.width = 124;
+ pathLData.height = 14;
+ pathLData.left = new FormAttachment(0, 1000, 100);
+ pathLData.top = new FormAttachment(0, 1000, 250);
+ path.setLayoutData(pathLData);
+ path.setEditable(false);
+ }
+ {
+ lastEdit = new Text(changeComposite,SWT.NONE);
+ FormData lastEditLData = new FormData();
+ lastEditLData.width = 124;
+ lastEditLData.height = 14;
+ lastEditLData.left = new FormAttachment(0, 1000, 100);
+ lastEditLData.top = new FormAttachment(0, 1000, 230);
+ lastEdit.setLayoutData(lastEditLData);
+ lastEdit.setEditable(false);
+ }
+ {
+ ownerId = new Text(changeComposite,SWT.NONE);
+ FormData ownerIdLData = new FormData();
+ ownerIdLData.width = 124;
+ ownerIdLData.height = 14;
+ ownerIdLData.left = new FormAttachment(0, 1000, 100);
+ ownerIdLData.top = new FormAttachment(0, 1000, 210);
+ ownerId.setLayoutData(ownerIdLData);
+ ownerId.setEditable(false);
+ }
+ {
+ resolution = new Text(changeComposite,SWT.NONE);
+ FormData resolutionLData = new FormData();
+ resolutionLData.width = 124;
+ resolutionLData.height = 14;
+ resolutionLData.left = new FormAttachment(0, 1000, 100);
+ resolutionLData.top = new FormAttachment(0, 1000, 190);
+ resolution.setLayoutData(resolutionLData);
+ }
+ {
+ vBitrate = new Text(changeComposite,SWT.NONE);
+ FormData vBitrateLData = new FormData();
+ vBitrateLData.width = 124;
+ vBitrateLData.height = 14;
+ vBitrateLData.left = new FormAttachment(0, 1000, 100);
+ vBitrateLData.top = new FormAttachment(0, 1000, 170);
+ vBitrate.setLayoutData(vBitrateLData);
+ }
+ {
+ aBitrate = new Text(changeComposite,SWT.NONE);
+ FormData aBitrateLData = new FormData();
+ aBitrateLData.width = 124;
+ aBitrateLData.height = 14;
+ aBitrateLData.left = new FormAttachment(0, 1000, 100);
+ aBitrateLData.top = new FormAttachment(0, 1000, 150);
+ aBitrate.setLayoutData(aBitrateLData);
+ }
+ {
+ duration = new Text(changeComposite,SWT.NONE);
+ FormData durationLData = new FormData();
+ durationLData.width = 124;
+ durationLData.height = 14;
+ durationLData.left = new FormAttachment(0, 1000, 100);
+ durationLData.top = new FormAttachment(0, 1000, 130);
+ duration.setLayoutData(durationLData);
+ }
+ {
+ year = new Text(changeComposite,SWT.NONE);
+ FormData yearLData = new FormData();
+ yearLData.width = 124;
+ yearLData.height = 14;
+ yearLData.left = new FormAttachment(0, 1000, 100);
+ yearLData.top = new FormAttachment(0, 1000, 110);
+ year.setLayoutData(yearLData);
+ }
+ {
+ category = new Text(changeComposite,SWT.NONE);
+ FormData categoryLData = new FormData();
+ categoryLData.width = 124;
+ categoryLData.height = 14;
+ categoryLData.left = new FormAttachment(0, 1000, 100);
+ categoryLData.top = new FormAttachment(0, 1000, 90);
+ category.setLayoutData(categoryLData);
+ category.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_WAIT));
+ }
+ {
+ album = new Text(changeComposite,SWT.NONE);
+ FormData albumLData = new FormData();
+ albumLData.width = 124;
+ albumLData.height = 14;
+ albumLData.left = new FormAttachment(0, 1000, 100);
+ albumLData.top = new FormAttachment(0, 1000, 70);
+ album.setLayoutData(albumLData);
+ }
+ {
+ author = new Text(changeComposite,SWT.NONE);
+ FormData authorLData = new FormData();
+ authorLData.width = 124;
+ authorLData.height = 14;
+ authorLData.left = new FormAttachment(0, 1000, 100);
+ authorLData.top = new FormAttachment(0, 1000, 50);
+ author.setLayoutData(authorLData);
+ }
+ {
+ title = new Text(changeComposite,SWT.NONE);
+ FormData titleLData = new FormData();
+ titleLData.width = 124;
+ titleLData.height = 13;
+ titleLData.top = new FormAttachment(0, 1000, 30);
+ titleLData.left = new FormAttachment(0, 1000, 100);
+ title.setLayoutData(titleLData);
+ }
+ }
+ }
+ {
+ composite3 = new Composite(container2,SWT.NONE);
+ FormLayout composite3Layout = new FormLayout();
+ composite3.setLayout(composite3Layout);
+ GridData composite3LData = new GridData();
+ composite3LData.widthHint = 777;
+ composite3LData.heightHint = 58;
+ composite3.setLayoutData(composite3LData);
+ {
+ deleteButton = new Button(composite3,SWT.PUSH | SWT.CENTER);
+ deleteButton.setText("Delete");
+ deleteButton.setVisible(false);
+ FormData deleteButtonLData = new FormData();
+ deleteButtonLData.width = 150;
+ deleteButtonLData.height = 30;
+ deleteButtonLData.left = new FormAttachment(0, 1000, 470);
+ deleteButtonLData.top = new FormAttachment(0, 1000, 15);
+ deleteButton.setLayoutData(deleteButtonLData);
+ deleteButton.setToolTipText("delete File from Database");
+ deleteButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ deleteButtonWidgetSelected(evt);
+ }
+ });
+ }
+ {
+ addButton = new Button(composite3,SWT.PUSH | SWT.CENTER);
+ addButton.setText("Add");
+ FormData addButtonLData = new FormData();
+ addButtonLData.width = 150;
+ addButtonLData.height = 30;
+ addButtonLData.left = new FormAttachment(0, 1000, 160);
+ addButtonLData.top = new FormAttachment(0, 1000, 15);
+ addButton.setLayoutData(addButtonLData);
+ addButton.setToolTipText("add new Files to Database");
+ addButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ addButtonWidgetSelected(evt);
+ }
+ });
+ }
+ }
+ }
+ }
+ {
+ tab3 = new CTabItem(cTabFolder1,SWT.NONE);
+ tab3.setText("Server");
+ {
+ container3 = new Composite(cTabFolder1,SWT.NONE);
+ GridLayout container3Layout = new GridLayout();
+ container3Layout.makeColumnsEqualWidth = true;
+ container3Layout.numColumns=2;
+ container3Layout.verticalSpacing = 0;
+ container3Layout.horizontalSpacing = 5;
+ container3.setLayout(container3Layout);
+ tab3.setControl(container3);
+ {
+ tab3Group1 = new Group(container3,SWT.NONE);
+ FormLayout tab3Group1Layout = new FormLayout();
+ tab3Group1.setLayout(tab3Group1Layout);
+ GridData tab3Group1LData = new GridData();
+ tab3Group1LData.widthHint = 500;
+ tab3Group1LData.heightHint = 129;
+ tab3Group1LData.horizontalAlignment = GridData.CENTER;
+ tab3Group1.setLayoutData(tab3Group1LData);
+ {
+ composite4 = new Composite(tab3Group1, SWT.NONE);
+ FormLayout composite4Layout = new FormLayout();
+ composite4.setLayout(composite4Layout);
+ FormData composite4LData = new FormData();
+ composite4LData.width = 504;
+ composite4LData.height = 140;
+ composite4LData.left = new FormAttachment(0, 1000, -3);
+ composite4LData.top = new FormAttachment(0, 1000, -6);
+ composite4.setLayoutData(composite4LData);
+ {
+ actualStreamLabel2 = new CLabel(
+ composite4,
+ SWT.NONE);
+ FormData actualStreamLabel2LData = new FormData();
+ actualStreamLabel2LData.width = 98;
+ actualStreamLabel2LData.height = 21;
+ actualStreamLabel2LData.left = new FormAttachment(0, 1000, 180);
+ actualStreamLabel2LData.top = new FormAttachment(0, 1000, 65);
+ actualStreamLabel2.setLayoutData(actualStreamLabel2LData);
+ actualStreamLabel2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ }
+ {
+ actualStreamLabel1 = new CLabel(
+ composite4,
+ SWT.NONE);
+ actualStreamLabel1.setText("Actual Number of Streams:");
+ FormData actualStreamLabel1LData = new FormData();
+ actualStreamLabel1LData.width = 160;
+ actualStreamLabel1LData.height = 21;
+ actualStreamLabel1LData.left = new FormAttachment(0, 1000, 14);
+ actualStreamLabel1LData.top = new FormAttachment(0, 1000, 65);
+ actualStreamLabel1.setLayoutData(actualStreamLabel1LData);
+ actualStreamLabel1.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ }
+ {
+ streamLabel2 = new CLabel(
+ composite4,
+ SWT.None);
+ FormData streamLabel2LData = new FormData();
+ streamLabel2LData.width = 98;
+ streamLabel2LData.height = 21;
+ streamLabel2LData.left = new FormAttachment(0, 1000, 180);
+ streamLabel2LData.top = new FormAttachment(0, 1000, 40);
+ streamLabel2.setLayoutData(streamLabel2LData);
+ streamLabel2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ }
+ {
+ streamLabel1 = new CLabel(
+ composite4,
+ SWT.NONE);
+ streamLabel1.setText("Total Number of Streams:");
+ FormData streamLabel1LData = new FormData();
+ streamLabel1LData.width = 150;
+ streamLabel1LData.height = 21;
+ streamLabel1LData.left = new FormAttachment(0, 1000, 14);
+ streamLabel1LData.top = new FormAttachment(0, 1000, 40);
+ streamLabel1.setLayoutData(streamLabel1LData);
+ streamLabel1.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ }
+ {
+ data2 = new CLabel(composite4, SWT.NONE);
+ FormData data2LData = new FormData();
+ data2LData.width = 98;
+ data2LData.height = 21;
+ data2LData.left = new FormAttachment(0, 1000, 180);
+ data2LData.top = new FormAttachment(0, 1000, 15);
+ data2.setLayoutData(data2LData);
+ data2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ }
+ {
+ data1 = new CLabel(composite4, SWT.NONE);
+ data1.setText("Total Data in Database:");
+ FormData data1LData = new FormData();
+ data1LData.width = 150;
+ data1LData.height = 21;
+ data1LData.left = new FormAttachment(0, 1000, 14);
+ data1LData.top = new FormAttachment(0, 1000, 15);
+ data1.setLayoutData(data1LData);
+ data1.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ }
+ {
+ shutdown = new Button(composite4, SWT.PUSH
+ | SWT.CENTER);
+ shutdown.setText("Shutdown");
+ FormData shutdownLData = new FormData();
+ shutdownLData.width = 77;
+ shutdownLData.height = 21;
+ shutdownLData.left = new FormAttachment(0, 1000, 35);
+ shutdownLData.top = new FormAttachment(0, 1000, 105);
+ shutdown.setLayoutData(shutdownLData);
+ shutdown.setToolTipText("Server shutdown");
+ shutdown.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ model.serverShutdown();
+ }
+ });
+ }
+ {
+ iptable = new Table(composite4, SWT.SINGLE);
+ FormData iptableLData = new FormData();
+ iptableLData.width = 173;
+ iptableLData.height = 110;
+ iptableLData.left = new FormAttachment(0, 1000, 308);
+ iptableLData.top = new FormAttachment(0, 1000, 7);
+ iptable.setLayoutData(iptableLData);
+ iptable.setHeaderVisible(true);
+ iptable.setToolTipText("User online");
+ {
+ userName = new TableColumn(
+ iptable,
+ SWT.CENTER);
+ userName.setText("Username");
+ userName.setWidth(70);
+ }
+ {
+ ip = new TableColumn(iptable, SWT.BEGINNING);
+ ip.setText("Ip");
+ ip.setWidth(119);
+ }
+ final int time = 1000;
+ final Runnable timer = new Runnable() {
+ public void run() {
+ refillIpTable();
+ data2.setText("not supported in yalp2");
+ streamLabel2.setText( /*new Integer(model.getAllStreamNum()).toString() */ "not supported in yalp2");
+ display.timerExec(time, this);
+ actualStreamLabel2.setText( /*new Integer(model.getActualStreamNum()).toString()*/ "not supported in yalp2");
+ }
+ };
+ display.timerExec(time, timer);
+ }
+ }
+ }
+ {
+ tab3Group2 = new Group(container3,SWT.NONE);
+ this.logo(tab3Group2);
+ }
+ {
+ tab3Group3 = new Group(container3,SWT.NONE);
+ FormLayout tab3Group3Layout = new FormLayout();
+ tab3Group3.setLayout(tab3Group3Layout);
+ GridData tab3Group3LData = new GridData();
+ tab3Group3LData.widthHint = 500;
+ tab3Group3LData.heightHint = 284;
+ tab3Group3LData.horizontalAlignment = GridData.CENTER;
+ tab3Group3.setLayoutData(tab3Group3LData);
+ tab3Group3.setText("User Management");
+ {
+ delete = new Button(tab3Group3,SWT.PUSH | SWT.CENTER);
+ delete.setText("Delete");
+ FormData deleteLData = new FormData();
+ deleteLData.width = 45;
+ deleteLData.height = 21;
+ deleteLData.left = new FormAttachment(0, 1000, 447);
+ deleteLData.top = new FormAttachment(0, 1000, 254);
+ delete.setLayoutData(deleteLData);
+ delete.setToolTipText("delete User");
+ delete.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ YalpUser toChange = new YalpUser();
+ toChange.id = new Integer(userTableId.getText()).intValue();
+ toChange.name = username.getText();
+ model.changeUser(toChange, passwd.getText(), Action.DELETE);
+ while(UserTable.getItemCount()!=0){
+ UserTable.remove(0);
+ }
+ ArrayList<YalpUser> resultList = model.getUser();
+ for (int i = 0; i < resultList.size(); i++) {
+ TableItem item;
+ YalpUser result = resultList.get(i);
+ item = new TableItem(UserTable,SWT.NONE);
+ item.setText(0,new Integer(result.id).toString());
+ item.setText(1,result.name);
+ // item.setText(2,result.password);
+ item.setText(3,result.realName);
+ item.setText(4,model.accessRightsName(result.level));
+ }
+ tab3group4.setVisible(false);
+ }
+ });
+ }
+ {
+ add1 = new Button(tab3Group3,SWT.PUSH | SWT.CENTER);
+ add1.setText("Add");
+ FormData addLData = new FormData();
+ addLData.width = 45;
+ addLData.height = 21;
+ addLData.left = new FormAttachment(0, 1000, 7);
+ addLData.top = new FormAttachment(0, 1000, 254);
+ add1.setLayoutData(addLData);
+ add1.setToolTipText("add new User ");
+ add1.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ tab3group5.setVisible(true);
+ }
+ });
+ }
+ {
+ UserTable = new Table(tab3Group3,SWT.SINGLE|SWT.FULL_SELECTION);
+ FormData UserTableLData = new FormData();
+ UserTableLData.width = 467;
+ UserTableLData.height = 224;
+ UserTableLData.left = new FormAttachment(11, 1000, 0);
+ UserTableLData.right = new FormAttachment(988, 1000, 0);
+ UserTableLData.top = new FormAttachment(19, 1000, 0);
+ UserTableLData.bottom = new FormAttachment(864, 1000, 0);
+ UserTable.setLayoutData(UserTableLData);
+ UserTable.setHeaderVisible(true);
+ UserTable.setToolTipText("registrated User");
+ UserTable.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ userTableId.setText(UserTable.getSelection()[0].getText(0));
+ username.setText(UserTable.getSelection()[0].getText(1));
+ passwd.setText(UserTable.getSelection()[0].getText(2));
+ userTableName.setText(UserTable.getSelection()[0].getText(3));
+ adminCombo.setText(UserTable.getSelection()[0].getText(4));
+ tab3group4.setVisible(true);
+ }
+ });
+ {
+ TableColumn id = new TableColumn(UserTable,SWT.BEGINNING);
+ id.setText("ID");
+ id.setWidth(45);
+ id.setMoveable(true);
+ id.addListener(SWT.Selection, new SortListener(this,UserTable,0,5));
+ TableColumn userName = new TableColumn(UserTable,SWT.BEGINNING);
+ userName.setMoveable(true);
+ userName.setText("Username");
+ userName.setWidth(120);
+ userName.addListener(SWT.Selection, new SortListener(this,UserTable,1,5));
+ TableColumn passwd = new TableColumn(UserTable,SWT.BEGINNING);
+ passwd.setMoveable(true);
+ passwd.setText("Password");
+ passwd.setWidth(120);
+ passwd.addListener(SWT.Selection, new SortListener(this,UserTable,2,5));
+ TableColumn name = new TableColumn(UserTable,SWT.BEGINNING);
+ name.setMoveable(true);
+ name.setText("Name");
+ name.setWidth(130);
+ name.addListener(SWT.Selection, new SortListener(this,UserTable,3,5));
+ TableColumn admin = new TableColumn(UserTable,SWT.BEGINNING);
+ admin.setMoveable(true);
+ admin.setText("Admin");
+ admin.setWidth(74);
+ admin.addListener(SWT.Selection, new SortListener(this,UserTable,4,5));
+ //TableColumn huhu=new TableColumn(UserTable,SWT.BEGINNING);
+ //huhu.dispose();
+ ArrayList<YalpUser> resultList = model.getUser();
+ for (int i = 0; i < resultList.size(); i++) {
+ TableItem item;
+ YalpUser result = resultList.get(i);
+ item = new TableItem(UserTable,SWT.NONE);
+ item.setText(0,new Integer(result.id).toString());
+ item.setText(1,result.name);
+ //item.setText(2,result.passwd);
+ item.setText(3,result.realName);
+ item.setText(4,model.accessRightsName(result.level));
+ }
+ }
+ }
+ }
+ {
+ tab3group4 = new Group(container3,SWT.NONE);
+ FormLayout tab3group4Layout = new FormLayout();
+ tab3group4.setLayout(tab3group4Layout);
+ tab3group4.setText("Edit User");
+ GridData tab3group4LData = new GridData();
+ tab3group4LData.widthHint = 256;
+ tab3group4LData.heightHint = 284;
+ tab3group4.setLayoutData(tab3group4LData);
+ tab3group4.setVisible(false);
+ {
+ save = new Button(tab3group4,SWT.PUSH | SWT.CENTER);
+ save.setText("save");
+ FormData saveLData = new FormData();
+ saveLData.width = 45;
+ saveLData.height = 21;
+ saveLData.left = new FormAttachment(0, 1000, 42);
+ saveLData.top = new FormAttachment(0, 1000, 157);
+ save.setLayoutData(saveLData);
+ save.setToolTipText("save Changes");
+ save.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ YalpUser toChange = new YalpUser();
+ toChange.id = new Integer(userTableId.getText()).intValue();
+ toChange.name = username.getText();
+ model.changeUser(toChange, passwd.getText(), Action.EDIT);
+ while(UserTable.getItemCount()!=0){
+ UserTable.remove(0);
+ }
+ ArrayList<YalpUser> resultList = model.getUser();
+ for (int i = 0; i < resultList.size(); i++) {
+ TableItem item;
+ YalpUser result = resultList.get(i);
+ item = new TableItem(UserTable,SWT.NONE);
+ item.setText(0,new Integer(result.id).toString());
+ item.setText(1,result.name);
+ //item.setText(2,result.passwd);
+ item.setText(3,result.realName);
+ item.setText(4,model.accessRightsName(result.level));
+ }
+ tab3group4.setVisible(false);
+ }
+ });
+ }
+ {
+ userTableName = new Text(tab3group4,SWT.NONE);
+ FormData text2LData = new FormData();
+ text2LData.width = 94;
+ text2LData.height = 14;
+ text2LData.left = new FormAttachment(0, 1000, 117);
+ text2LData.top = new FormAttachment(0, 1000, 112);
+ userTableName .setLayoutData(text2LData);
+ }
+ {
+ passwd = new Text(tab3group4,SWT.NONE);
+ FormData passwdLData = new FormData();
+ passwdLData.width = 94;
+ passwdLData.height = 14;
+ passwdLData.left = new FormAttachment(0, 1000, 117);
+ passwdLData.top = new FormAttachment(0, 1000, 92);
+ passwd.setLayoutData(passwdLData);
+ }
+ {
+ username = new Text(tab3group4,SWT.NONE);
+ FormData usernameLData = new FormData();
+ usernameLData.width = 94;
+ usernameLData.height = 14;
+ usernameLData.left = new FormAttachment(0, 1000, 117);
+ usernameLData.top = new FormAttachment(0, 1000, 72);
+ username.setLayoutData(usernameLData);
+ }
+ {
+ userTableId = new Text(tab3group4,SWT.NONE);
+ FormData text1LData = new FormData();
+ text1LData.width = 94;
+ text1LData.height = 14;
+ text1LData.left = new FormAttachment(0, 1000, 117);
+ text1LData.top = new FormAttachment(0, 1000, 52);
+ userTableId.setLayoutData(text1LData);
+ userTableId.setEditable(false);
+ }
+ {
+ adminLabel = new CLabel(tab3group4,SWT.NONE);
+ adminLabel.setText("Admin:");
+ FormData adminLabelLData = new FormData();
+ adminLabelLData.width = 42;
+ adminLabelLData.height = 21;
+ adminLabelLData.left = new FormAttachment(0, 1000, 27);
+ adminLabelLData.top = new FormAttachment(0, 1000, 127);
+ adminLabel.setLayoutData(adminLabelLData);
+ }
+ {
+ idLable = new CLabel(tab3group4,SWT.NONE);
+ idLable.setText("Id:");
+ FormData idLableLData = new FormData();
+ idLableLData.width = 20;
+ idLableLData.height = 21;
+ idLableLData.left = new FormAttachment(107, 1000, 0);
+ idLableLData.right = new FormAttachment(185, 1000, 0);
+ idLableLData.top = new FormAttachment(167, 1000, 0);
+ idLableLData.bottom = new FormAttachment(241, 1000, 0);
+ idLable.setLayoutData(idLableLData);
+ }
+ {
+ usernameLable = new CLabel(tab3group4,SWT.NONE);
+ usernameLable.setText("Username:");
+ FormData usernameLableLData = new FormData();
+ usernameLableLData.width = 58;
+ usernameLableLData.height = 21;
+ usernameLableLData.left = new FormAttachment(107, 1000, 0);
+ usernameLableLData.right = new FormAttachment(333, 1000, 0);
+ usernameLableLData.top = new FormAttachment(237, 1000, 0);
+ usernameLableLData.bottom = new FormAttachment(311, 1000, 0);
+ usernameLable.setLayoutData(usernameLableLData);
+ }
+ {
+ passwdLable = new CLabel(tab3group4,SWT.NONE);
+ passwdLable.setText("Password:");
+ FormData passwdLableLData = new FormData();
+ passwdLableLData.width = 56;
+ passwdLableLData.height = 21;
+ passwdLableLData.left = new FormAttachment(107, 1000, 0);
+ passwdLableLData.right = new FormAttachment(326, 1000, 0);
+ passwdLableLData.top = new FormAttachment(308, 1000, 0);
+ passwdLableLData.bottom = new FormAttachment(382, 1000, 0);
+ passwdLable.setLayoutData(passwdLableLData);
+ }
+ {
+ nameLable = new CLabel(tab3group4,SWT.NONE);
+ nameLable.setText("Name:");
+ FormData nameLableLData = new FormData();
+ nameLableLData.width = 37;
+ nameLableLData.height = 21;
+ nameLableLData.left = new FormAttachment(107, 1000, 0);
+ nameLableLData.right = new FormAttachment(251, 1000, 0);
+ nameLableLData.top = new FormAttachment(378, 1000, 0);
+ nameLableLData.bottom = new FormAttachment(452, 1000, 0);
+ nameLable.setLayoutData(nameLableLData);
+ }
+ {
+ adminCombo = new CCombo(tab3group4,SWT.NONE);
+ FormData adminComboLData = new FormData();
+ adminComboLData.width = 81;
+ adminComboLData.height = 16;
+ adminComboLData.left = new FormAttachment(458, 1000, 0);
+ adminComboLData.right = new FormAttachment(849, 1000, 0);
+ adminComboLData.top = new FormAttachment(466, 1000, 0);
+ adminComboLData.bottom = new FormAttachment(522, 1000, 0);
+ adminCombo.setLayoutData(adminComboLData);
+ {
+ adminCombo.add("true");
+ adminCombo.add("false");
+ }
+ }
+ }
+ tab3group5 = new Group(container3,SWT.NONE);
+ FormLayout tab3group5Layout = new FormLayout();
+ tab3group5.setLayout(tab3group5Layout);
+ GridData tab3group5LData = new GridData();
+ tab3group5LData.widthHint = 500;
+ tab3group5LData.heightHint = 99;
+ tab3group5.setLayoutData(tab3group5LData);
+ tab3group5.setText("Add User");
+ tab3group5.setVisible(false);
+ {
+ submitButton = new Button(tab3group5,SWT.PUSH | SWT.CENTER);
+ submitButton.setText("Submit");
+ FormData submitButtonLData = new FormData();
+ submitButtonLData.width = 50;
+ submitButtonLData.height = 21;
+ submitButtonLData.left = new FormAttachment(0, 1000, 382);
+ submitButtonLData.top = new FormAttachment(0, 1000, 52);
+ submitButton.setLayoutData(submitButtonLData);
+ submitButton.setToolTipText("add User");
+ submitButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ System.out.println("submit");
+ YalpUser toChange = new YalpUser();
+ toChange.id = 100;
+ toChange.name = usernameAdd.getText();
+ toChange.realName = realnameAdd.getText();
+ model.changeUser(toChange, passwdAdd.getText(), Action.CREATE);
+ while(UserTable.getItemCount()!=0){
+ UserTable.remove(0);
+ }
+ ArrayList<YalpUser> resultList = model.getUser();
+ for (int i = 0; i < resultList.size(); i++) {
+ TableItem item;
+ YalpUser result = resultList.get(i);
+ item = new TableItem(UserTable,SWT.NONE);
+ item.setText(0,new Integer(result.id).toString());
+ item.setText(1,result.name);
+ //item.setText(2,result.passwd);
+ item.setText(3,result.realName);
+ item.setText(4,model.accessRightsName(result.level));
+ }
+ }
+ });
+ }
+ {
+ adminAddLabel = new CLabel(tab3group5,SWT.NONE);
+ adminAddLabel.setText("Admin:");
+ FormData adminAddLabelLData = new FormData();
+ adminAddLabelLData.width = 40;
+ adminAddLabelLData.height = 21;
+ adminAddLabelLData.left = new FormAttachment(0, 1000, 291);
+ adminAddLabelLData.top = new FormAttachment(0, 1000, 17);
+ adminAddLabel.setLayoutData(adminAddLabelLData);
+ }
+ {
+ passwdAddLable = new CLabel(tab3group5,SWT.NONE);
+ passwdAddLable.setText("Password:");
+ FormData passwdAddLableLData = new FormData();
+ passwdAddLableLData.width = 60;
+ passwdAddLableLData.height = 21;
+ passwdAddLableLData.left = new FormAttachment(0, 1000, 17);
+ passwdAddLableLData.top = new FormAttachment(0, 1000, 57);
+ passwdAddLable.setLayoutData(passwdAddLableLData);
+ }
+ {
+ usernameAddLable = new CLabel(tab3group5,SWT.NONE);
+ usernameAddLable.setText("Username:");
+ FormData usernameAddLableLData = new FormData();
+ usernameAddLableLData.width = 60;
+ usernameAddLableLData.height = 21;
+ usernameAddLableLData.left = new FormAttachment(0, 1000, 17);
+ usernameAddLableLData.top = new FormAttachment(0, 1000, 37);
+ usernameAddLable.setLayoutData(usernameAddLableLData);
+ }
+ {
+ realnameAddLabel = new CLabel(tab3group5,SWT.NONE);
+ realnameAddLabel.setText("Name:");
+ FormData realnameAddLabelLData = new FormData();
+ realnameAddLabelLData.width = 60;
+ realnameAddLabelLData.height = 21;
+ realnameAddLabelLData.left = new FormAttachment(0, 1000, 17);
+ realnameAddLabelLData.top = new FormAttachment(0, 1000, 17);
+ realnameAddLabel.setLayoutData(realnameAddLabelLData);
+ }
+ {
+ adminAdd = new CCombo(tab3group5,SWT.NONE);
+ FormData adminAddLData = new FormData();
+ adminAddLData.width = 65;
+ adminAddLData.height = 12;
+ adminAddLData.left = new FormAttachment(0, 1000, 347);
+ adminAddLData.top = new FormAttachment(0, 1000, 22);
+ adminAdd.setLayoutData(adminAddLData);
+ adminAdd.setText("false");
+ {
+ adminAdd.add("false");
+ adminAdd.add("true");
+ }
+ }
+ {
+ realnameAdd = new Text(tab3group5,SWT.NONE);
+ FormData realnameAddLData = new FormData();
+ realnameAddLData.width = 174;
+ realnameAddLData.height = 14;
+ realnameAddLData.left = new FormAttachment(0, 1000, 82);
+ realnameAddLData.top = new FormAttachment(0, 1000, 22);
+ realnameAdd.setLayoutData(realnameAddLData);
+ }
+ {
+ usernameAdd = new Text(tab3group5,SWT.NONE);
+ FormData usernameAddLData = new FormData();
+ usernameAddLData.width = 174;
+ usernameAddLData.height = 13;
+ usernameAddLData.left = new FormAttachment(165, 1000, 0);
+ usernameAddLData.right = new FormAttachment(525, 1000, 0);
+ usernameAddLData.top = new FormAttachment(429, 1000, 0);
+ usernameAddLData.bottom = new FormAttachment(560, 1000, 0);
+ usernameAdd.setLayoutData(usernameAddLData);
+ }
+ {
+ FormData PasswdAddLData = new FormData();
+ PasswdAddLData.width = 174;
+ PasswdAddLData.height = 13;
+ PasswdAddLData.left = new FormAttachment(165, 1000, 0);
+ PasswdAddLData.right = new FormAttachment(525, 1000, 0);
+ PasswdAddLData.top = new FormAttachment(631, 1000, 0);
+ PasswdAddLData.bottom = new FormAttachment(762, 1000, 0);
+ passwdAdd = new Text(tab3group5,SWT.NONE);
+ passwdAdd.setLayoutData(PasswdAddLData);
+ }
+ }
+ }
+ cTabFolder1.setSelection(0);
+ }
+ else{
+ GridData testLData = new GridData();
+ testLData.widthHint = 792;
+ testLData.heightHint = 590;
+ Composite simpelUser = new Composite(this, SWT.NONE);
+ RowLayout testLayout = new RowLayout(org.eclipse.swt.SWT.HORIZONTAL);
+ simpelUser.setLayout(testLayout);
+ simpelUser.setLayoutData(testLData);
+ {
+ topComposite = new Composite(simpelUser,SWT.NONE);
+ GridLayout topCompositeLayout = new GridLayout();
+ topCompositeLayout.makeColumnsEqualWidth = true;
+ topCompositeLayout.numColumns = 2;
+ topCompositeLayout.verticalSpacing = 2;
+ topCompositeLayout.horizontalSpacing = 5;
+ topComposite.setLayout(topCompositeLayout);
+ RowData topCompositeLData = new RowData();
+ topCompositeLData.width = 783;
+ topCompositeLData.height = 566;
+ topComposite.setLayoutData(topCompositeLData);
+ {
+ find = new Group(topComposite,SWT.NONE);
+ this.find(find,resultComposite,playlistComposite,bottemComposite,1);
+ }
+ {
+ logo = new Group(topComposite,SWT.NONE);
+ this.logo(logo);
+ }
+ {
+ resultComposite = new Composite(topComposite,SWT.NONE);
+ resultTable1 = new Table(resultComposite,SWT.MULTI|SWT.FULL_SELECTION);
+ resultTable1.setToolTipText("Medias");
+ resultTable1.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ add2.setEnabled(true);
+ }
+ });
+ this.resultTable(resultComposite,resultTable1,1);
+ }
+ {
+ playlistComposite = new Composite(topComposite,SWT.NONE);
+ FormLayout playlistCompositeLayout = new FormLayout();
+ playlistComposite.setLayout(playlistCompositeLayout);
+ GridData playlistCompositeLData = new GridData();
+ playlistCompositeLData.heightHint = 390;
+ playlistCompositeLData.horizontalAlignment = GridData.FILL;
+ playlistComposite.setLayoutData(playlistCompositeLData);
+ playlistComposite.setVisible(false);
+ playlistComposite.setSize(238, 390);
+ {
+ next = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData nextLData = new FormData();
+ nextLData.width = 45;
+ nextLData.height = 21;
+ nextLData.left = new FormAttachment(0, 1000, 185);
+ nextLData.top = new FormAttachment(0, 1000, 365);
+ next.setLayoutData(nextLData);
+ next.setEnabled(false);
+ next.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ next.setToolTipText("play next Title");
+ next.setImage(forwardImage);
+ next.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ model.next();
+ }
+ });
+ }
+ {
+ stop = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData stopLData = new FormData();
+ stopLData.width = 35;
+ stopLData.height = 21;
+ stopLData.left = new FormAttachment(0, 1000, 91);
+ stopLData.top = new FormAttachment(0, 1000, 365);
+ stop.setLayoutData(stopLData);
+ stop.setImage(new Image(this.getDisplay(),"img/stop.gif"));
+ stop.setEnabled(false);
+ stop.setToolTipText("stop");
+ stop.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if (model.stop()){
+ play.setEnabled(true);
+ next.setEnabled(false);
+ stop.setEnabled(false);
+ play.setImage(playImage);
+ play.setToolTipText("play");
+ isNotPlaying=true;
+ }
+
+ }
+ });
+ }
+ {
+ play = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData playLData = new FormData();
+ playLData.width = 35;
+ playLData.height = 21;
+ playLData.left = new FormAttachment(0, 1000, 50);
+ playLData.top = new FormAttachment(0, 1000, 365);
+ play.setLayoutData(playLData);
+ play.setImage(playImage);
+ play.setEnabled(false);
+ play.setToolTipText("play");
+ play.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ stop.setEnabled(true);
+ if (playlistTable.getItemCount()>1)next.setEnabled(true);
+ del.setEnabled(false);
+ //add2.setEnabled(false);
+ if (isNotPlaying){
+ play.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_WAIT));
+ if(model.play()){
+ play.setImage(pauseImage);
+ play.setToolTipText("pause");
+ play.setCursor(SWTResourceManager.getCursor(SWT.NONE));
+ isNotPlaying= false;
+ }else;
+ }else{
+ if(model.pause()){
+ if (paused){
+ play.setImage(playImage);
+ play.setToolTipText("play");
+ paused=false;
+ }else{
+ play.setImage(pauseImage);
+ play.setToolTipText("pause");
+ paused=true;
+ }
+ }else;
+ }
+
+ }
+ });
+ }
+ {
+ add2 = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData addLData = new FormData();
+ addLData.width = 25;
+ addLData.height = 21;
+ addLData.left = new FormAttachment(0, 1000, 2);
+ addLData.top = new FormAttachment(0, 1000, 160);
+ add2.setLayoutData(addLData);
+ add2.setText(">>");
+ add2.setEnabled(false);
+ add2.setToolTipText("add to Playlist");
+ add2.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ add2.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if (System.getProperty("os.name")== "Mac OS X"){
+ for (int i=resultTable1.getSelectionCount()-1;i>=0;i--){
+ int id=new Integer(resultTable1.getSelection()[i].getText(0)).intValue();
+ System.out.println(resultTable1.getSelection()[i].getText(1));
+ model.add2PlayList(id);
+ }
+ }else{
+ for (int i=0;i<resultTable1.getSelectionCount();i++){
+ int id=new Integer(resultTable1.getSelection()[i].getText(0)).intValue();
+ System.out.println(resultTable1.getSelection()[i].getText(1));
+ model.add2PlayList(id);
+ }
+ }
+ while(playlistTable.getItemCount()!=0){
+ playlistTable.remove(0);
+ }
+ ArrayList<Media> playlist=model.getToPlaylist();
+ for(int i=0;i<playlist.size();i++){
+ Media result=playlist.get(i);
+ TableItem item = new TableItem(playlistTable,SWT.NONE);
+ item.setText(0,result.name);
+ item.setText(1,result.duration);
+ }
+ play.setEnabled(true);
+ if (playlistTable.getItemCount()>1&& !isNotPlaying)next.setEnabled(true);
+ }
+ });
+ }
+ {
+ del = new Button(playlistComposite,SWT.PUSH | SWT.CENTER);
+ FormData delLData = new FormData();
+ delLData.width = 25;
+ delLData.height = 21;
+ delLData.left = new FormAttachment(0, 1000, 2);
+ delLData.top = new FormAttachment(0, 1000, 200);
+ del.setLayoutData(delLData);
+ del.setEnabled(false);
+ del.setToolTipText("del from Playlist");
+ del.setText("<<");
+ del.setFont(SWTResourceManager.getFont("Times", 8, 1, false, false));
+ del.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ for (int i=playlistTable.getSelectionCount()-1;i>=0;i--){
+ int pos = playlistTable.getSelectionIndices()[i];
+ model.removeFromPlayList(pos);
+ }
+
+ del.setEnabled(false);
+ while(playlistTable.getItemCount()!=0){
+ playlistTable.remove(0);
+ }
+ ArrayList<Media> playlist=model.getToPlaylist();
+ for(int i=0;i<playlist.size();i++){
+ Media result=playlist.get(i);
+ TableItem item = new TableItem(playlistTable,SWT.NONE);
+ item.setText(0,result.name);
+ item.setText(1,result.duration);
+ }
+ if (playlistTable.getItemCount()==0)play.setEnabled(false);
+ }
+ });
+ }
+ {
+ playlistTable = new Table(playlistComposite,SWT.MULTI|SWT.FULL_SELECTION);
+ playlistTable.setHeaderVisible(true);
+ FormData playlistTableLData = new FormData();
+ playlistTableLData.width = 184;
+ playlistTableLData.height = 330;
+ playlistTableLData.top = new FormAttachment(24, 1000, 0);
+ playlistTableLData.left = new FormAttachment(0, 1000, 38);
+ playlistTable.setLayoutData(playlistTableLData);
+ playlistTable.setToolTipText("Playlist");
+ playlistTable.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ if (isNotPlaying)del.setEnabled(true);
+ }
+ });
+ TableColumn title = new TableColumn(playlistTable,SWT.LEFT);
+ title.setText("Title");
+ title.setWidth(120);
+ title.setMoveable(true);
+ TableColumn duration = new TableColumn(playlistTable,SWT.RIGHT);
+ duration.setText("Duration");
+ duration.setWidth(80);
+ duration.setMoveable(true);
+ }
+ }
+ }
+ }
+ }
+ this.layout();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ //TODO:start find
+ private void find(Group find,Composite resultComposite, Composite playlistComposite,Composite bottemComposite,int _tab){
+ final Text searchField = new Text(find,SWT.NONE);
+ final Button findButton = new Button(find,SWT.PUSH | SWT.CENTER);
+ final Button allCheckBox = new Button(find,SWT.RADIO | SWT.LEFT);
+ final Button videoCheckBox = new Button(find,SWT.RADIO | SWT.LEFT);
+ final Button audioCheckBox = new Button(find,SWT.RADIO | SWT.LEFT);
+ final CLabel returnNum= new CLabel(find, SWT.NONE);
+ final int tab=_tab;
+ {
+ cLabel2 = new CLabel(find, SWT.NONE);
+ if (tab==1)cLabel2.setText("find and stream mutimedia files");
+ else cLabel2.setText("find and manage mutimedia files");
+ FormData cLabel2LData = new FormData();
+ cLabel2LData.width = 250;
+ cLabel2LData.height = 21;
+ cLabel2LData.left = new FormAttachment(0,1000,46);
+ cLabel2LData.top = new FormAttachment(0,1000,13);
+ cLabel2.setLayoutData(cLabel2LData);
+ }
+ {
+
+ FormData allCheckBoxLData = new FormData();
+ allCheckBoxLData.left = new FormAttachment(0, 1000, 95);
+ allCheckBoxLData.top = new FormAttachment(0, 1000, 98);
+ allCheckBoxLData.width = 56;
+ allCheckBoxLData.height = 14;
+ allCheckBox.setLayoutData(allCheckBoxLData);
+ allCheckBox.setText("All");
+ allCheckBox.setSelection(true);
+ allCheckBox.setToolTipText("Find Audio and Video Files");
+ allCheckBox.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character == SWT.CR) {
+ searchPressed(
+ searchField,
+ videoCheckBox,
+ audioCheckBox,
+ returnNum,
+ tab);
+ }
+ }
+ });
+ }
+ {
+
+ FormData audioCheckBoxLData = new FormData();
+ audioCheckBoxLData.left = new FormAttachment(0, 1000, 195);
+ audioCheckBoxLData.top = new FormAttachment(0, 1000, 98);
+ audioCheckBoxLData.width = 56;
+ audioCheckBoxLData.height = 14;
+ audioCheckBox.setLayoutData(audioCheckBoxLData);
+ audioCheckBox.setText("Audio");
+ audioCheckBox.setToolTipText("Find Audio Files");
+ audioCheckBox
+ .addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character == SWT.CR) {
+ searchPressed(
+ searchField,
+ videoCheckBox,
+ audioCheckBox,
+ returnNum,
+ tab);
+ }
+ }
+ });
+ }
+ {
+
+ FormData videoCheckBoxLData = new FormData();
+ videoCheckBoxLData.left = new FormAttachment(0, 1000, 296);
+ videoCheckBoxLData.top = new FormAttachment(0, 1000, 98);
+ videoCheckBoxLData.width = 56;
+ videoCheckBoxLData.height = 14;
+ videoCheckBox.setLayoutData(videoCheckBoxLData);
+ videoCheckBox.setText("Video");
+ videoCheckBox.setToolTipText("Find Video Files");
+ videoCheckBox
+ .addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character == SWT.CR) {
+ searchPressed(
+ searchField,
+ videoCheckBox,
+ audioCheckBox,
+ returnNum,
+ tab);
+ }
+ }
+ });
+ }
+
+
+ FormLayout findLayout = new FormLayout();
+ find.setLayout(findLayout);
+ GridData findLData = new GridData();
+ findLData.widthHint = 497;
+ findLData.heightHint = 130;
+ find.setLayoutData(findLData);
+ find.setSize(497, 104);
+ find.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character==SWT.CR){
+ searchPressed(searchField,videoCheckBox,audioCheckBox,returnNum,tab);
+ }
+ }
+ });
+ {
+ //searchField
+ FormData searchFieldLData = new FormData();
+ searchFieldLData.width = 344;
+ searchFieldLData.height = 20;
+ searchFieldLData.left = new FormAttachment(0,1000,37);
+ searchFieldLData.top = new FormAttachment(0,1000,55);
+ searchField.setLayoutData(searchFieldLData);
+ searchField.setFont(SWTResourceManager.getFont("Times",12,0,false,false));
+ searchField.setToolTipText("Keyword");
+ searchField.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character==SWT.CR){
+ searchPressed(searchField,videoCheckBox,audioCheckBox,returnNum,tab);
+ }
+ }
+ });
+ }
+ {
+ //findButton
+ findButton.setText("Find");
+ FormData findButtonLData = new FormData(70,26);
+ findButtonLData.width = 70;
+ findButtonLData.height = 26;
+ findButtonLData.left = new FormAttachment(0,1000,403);
+ findButtonLData.top = new FormAttachment(0,1000,52);
+ findButton.setLayoutData(findButtonLData);
+ findButton.setSize(70, 26);
+ findButton.setToolTipText("Find");
+ findButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ add2.setEnabled(false);
+ searchPressed(searchField,videoCheckBox,audioCheckBox,returnNum,tab);
+ }
+ });
+ }
+ {
+ returnNum.setText("");
+ FormData returnNumLData = new FormData();
+ returnNumLData.width = 63;
+ returnNumLData.height = 21;
+ returnNumLData.left = new FormAttachment(0, 1000, 410);
+ returnNumLData.top = new FormAttachment(0, 1000, 93);
+ returnNum.setLayoutData(returnNumLData);
+ }
+ }
+
+ //TODO logo
+ private void logo(Group logo){
+ FormLayout logoLayout = new FormLayout();
+ logo.setLayout(logoLayout);
+ GridData logoLData = new GridData();
+ logoLData.widthHint = 260;
+ logoLData.heightHint = 130;
+ logo.setLayoutData(logoLData);
+ logoLayout.marginWidth=30;
+ logoLayout.marginHeight=0;
+ {
+ cLabel2 = new CLabel(logo,SWT.NONE);
+ cLabel2.setImage(new Image(this.getDisplay(),"img/yalpV2.gif"));
+ }
+
+
+
+ }
+
+
+
+ //TODO resultComposite
+ private void resultTable(Composite resultComposite,Table resultTable,int tab){
+
+ resultComposite.setVisible(false);
+ FormLayout resultCompositeLayout = new FormLayout();
+ resultComposite.setLayout(resultCompositeLayout);
+ GridData resultCompositeLData = new GridData();
+ resultCompositeLData.widthHint = 502;
+ if (tab==1)resultCompositeLData.heightHint = 390;
+ else resultCompositeLData.heightHint = 380;
+ resultComposite.setLayoutData(resultCompositeLData);
+ {
+ FormData resultTableLData = new FormData();
+ resultTableLData.width = 482;
+ if (tab==1)resultTableLData.height = 365;
+ else resultTableLData.height = 313;
+ resultTableLData.left = new FormAttachment(0, 1000, 0);
+ resultTableLData.top = new FormAttachment(0, 1000, 7);
+ resultTable.setLayoutData(resultTableLData);
+ resultTable.setHeaderVisible(true);
+ TableColumn id = new TableColumn(resultTable,SWT.RIGHT);
+ id.setText("ID");
+ id.setWidth(0);
+ id.setMoveable(true);
+ id.addListener(SWT.Selection, new SortListener(this,resultTable,0,8));
+ TableColumn title = new TableColumn(resultTable,SWT.LEFT);
+ title.setText("Title");
+ title.setWidth(110);
+ title.setMoveable(true);
+ title.addListener(SWT.Selection, new SortListener(this,resultTable,1,8));
+ TableColumn author = new TableColumn(resultTable,SWT.LEFT);
+ author.setText("Author");
+ author.setWidth(100);
+ author.setMoveable(true);
+ author.addListener(SWT.Selection, new SortListener(this,resultTable,2,8));
+ TableColumn album = new TableColumn(resultTable,SWT.LEFT);
+ album.setText("Album");
+ album.setWidth(100);
+ album.setMoveable(true);
+ album.addListener(SWT.Selection, new SortListener(this,resultTable,3,8));
+ TableColumn year = new TableColumn(resultTable,SWT.LEFT);
+ year.setText("Year");
+ year.setWidth(60);
+ year.setMoveable(true);
+ year.addListener(SWT.Selection, new SortListener(this,resultTable,4,8));
+ TableColumn category = new TableColumn(resultTable,SWT.LEFT);
+ category.setText("Category");
+ category.setWidth(60);
+ category.setMoveable(true);
+ category.addListener(SWT.Selection, new SortListener(this,resultTable,5,8));
+ TableColumn type = new TableColumn(resultTable,SWT.LEFT);
+ type.setText("Type");
+ type.setWidth(60);
+ type.setMoveable(true);
+ type.addListener(SWT.Selection, new SortListener(this,resultTable,6,8));
+ }
+
+ }
+ private void saveButtonWidgetSelected(SelectionEvent evt) {
+ try{
+ int OwnerId = model.getOwnerid(ownerId.getText());
+ Media media = new Media();
+ media.id = new Integer(id.getText()).intValue();
+ media.name = title.getText();
+ media.duration = duration.getText();
+ media.lastEdit = new Date(System.currentTimeMillis()).toString();
+ media.path = path.getText();
+ media.fileName = name.getText();
+ /* t.b.d.
+ author.getText();
+ album.getText();
+ category.getText();
+ year.getText();
+ new Integer(aBitrate.getText()).intValue();
+ new Integer(vBitrate.getText()).intValue();
+ resolution.getText();
+ OwnerId;
+ */
+ if (model.changeMedia(media, Action.EDIT)) {
+ int select=resultTable2.getSelectionIndex();
+ TableItem item= new TableItem(resultTable2,SWT.NONE,select);
+ item.setText(0,new Integer(media.id).toString());
+ item.setText(1,media.name);
+ /* t.b.d. read from string props
+ item.setText(2,media.author.name);
+ item.setText(3,media.album);
+ item.setText(4,media.year);
+ item.setText(5,media.category);
+ */
+ item.setText(6,model.getTypeName(media.type));
+ resultTable2.remove(select+1);
+ resultTable2.setSelection(select);
+ changeComposite.setVisible(false);
+ deleteButton.setVisible(false);
+ }
+ }catch (Exception e){
+ System.out.println("Exception in SaveButton"+e);
+ }
+ }
+
+ private void searchPressed(Text searchField,Button videoCheckBox,Button audioCheckBox,CLabel returnNum,int tab){
+ String search = searchField.getText();
+ int returnVal;
+ ArrayList<MediaType> types = new ArrayList<MediaType>();
+
+ if( videoCheckBox.getSelection() )
+ types.add(MediaType.VIDEO);
+
+ if( audioCheckBox.getSelection() )
+ types.add(MediaType.SOUND);
+ /* t.b.d. add IMAGE support */
+
+ if (tab==1){
+ while(resultTable1.getItemCount()!=0){
+ resultTable1.remove(0);
+ }
+ }else{
+ while(resultTable2.getItemCount()!=0){
+ resultTable2.remove(0);
+ }
+ }
+ returnVal= model.search(search, types, tab);
+ ArrayList<Media>resultList=model.getMedia(tab);
+ for(int i=0;i<resultList.size();i++){
+ TableItem item;
+ Media result=resultList.get(i);
+ if (tab==1) item=new TableItem(resultTable1,SWT.NONE);
+ else item= new TableItem(resultTable2,SWT.NONE);
+ item.setText(0,new Integer(result.id).toString());
+ item.setText(1,result.name);
+ /* t.b.d. add string_props support
+ if(result.author != null)
+ item.setText(2,result.author);
+
+ if(result.album != null)
+ item.setText(3,result.album);
+
+ if(result.year != null)
+ item.setText(4,result.year);
+
+ if(result.category != null)
+ item.setText(5,result.category);
+ */
+ if(result.type != null)
+ item.setText(6,model.getTypeName(result.type));
+
+ }
+ if (tab==1){
+ if (returnVal==1)returnNum.setText(returnVal+" Media");
+ else returnNum.setText(returnVal+" Medias");
+ resultComposite.setVisible(true);
+ playlistComposite.setVisible(true);
+ //bottemComposite.setVisible(true);
+ }
+ if (tab==2){
+ if (returnVal==1)returnNum.setText(returnVal+" Media");
+ else returnNum.setText(returnVal+" Medias");
+ composite1.setVisible(true);
+ }
+ }
+
+
+ private void deleteButtonWidgetSelected(SelectionEvent evt) {
+ try{
+ for (int i=resultTable2.getSelectionCount()-1;i>=0;i--){
+
+ Media result = model.getMediaWithId(
+ new Integer(resultTable2.getSelection()[i].getText(0)).intValue(),2 );
+
+ changeComposite.setVisible(false);
+ deleteButton.setVisible(false);
+ model.changeMedia(result, Action.DELETE);
+ resultTable2.remove(resultTable2.getSelectionIndices()[i]);
+ }
+ }catch (Exception e){
+ System.out.println("Exception in DeleteButton "+e);
+ }
+ }
+ private void addButtonWidgetSelected(SelectionEvent evt) {
+ System.out.println("browser not implemented in yalp v2");
+ }
+
+
+ public void refillIpTable(){
+ /* t.b.d. replace by session viewer
+ try{
+ ArrayList<ClientInfo> list=model.srvCon.getClientInfo();
+ while(iptable.getItemCount()!=0){
+ iptable.remove(0);
+ }
+ for(ClientInfo info : list){
+ TableItem item = new TableItem(iptable,SWT.NONE);
+ item.setText(0,info.getUserName());
+ item.setText(1,info.getIp());
+ }
+ }catch(Exception e){System.out.println("geht nicht "+e);}
+ */
+ }
+
+ public void show(){
+ ((Shell)this.parent).setImage(new Image(display,"img/yalpV2_klein.gif"));
+ ((Shell)this.parent).setText("yalp");
+ this.parent.addListener(SWT.Dispose,new org.eclipse.swt.widgets.Listener(){
+ public void handleEvent(org.eclipse.swt.widgets.Event e) {
+ ShellClose();
+ }
+ });
+ Point size = this.getSize();
+ java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ Rectangle shellBounds = this.parent.computeTrim((screen.width-size.x)/2,(screen.height-size.y)/2,size.x,size.y);
+ this.parent.setLayout(new FillLayout());
+ this.parent.layout();
+ this.parent.setBounds(shellBounds);
+ ((Shell)this.parent).open();
+ while (!this.parent.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+ public void ShellClose(){
+ this.model.logoff();
+ System.exit(0);
+ }
+
+}
+
diff --git a/src/YalpClients/SwtClient/GUI/InitGUI.java b/src/YalpClients/SwtClient/GUI/InitGUI.java new file mode 100644 index 0000000..6b1fa51 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/InitGUI.java @@ -0,0 +1,58 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient.GUI;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+import YalpClients.SwtClient.*;
+import YalpInterfaces.AccessRights;
+
+/*
+ * Class InitGUI
+ *
+ * <em></em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 1 02-04-2006<br>
+ *
+ */
+
+public class InitGUI {
+ private Model model;
+ private Display display;
+ private int time = 1000;
+
+ public InitGUI(Model model,AccessRights kind){
+ this.model=model;
+ this.display = Display.getDefault();
+ final Runnable timer = new Runnable() {
+ public void run() {
+ serverStillAlive(this);
+ }
+ };
+ display.timerExec(time, timer);
+
+ GUI gui= new GUI(
+ new Shell(display ,SWT.MIN), display, model, kind, SWT.NULL );
+ gui.show();
+ }
+
+ public void serverStillAlive(Runnable timer){
+ model.serverStillAlive();
+ if (!this.model.getLogoff()){
+ this.display.timerExec(time, timer);
+ }
+ }
+
+}
diff --git a/src/YalpClients/SwtClient/GUI/LoadDialog.java b/src/YalpClients/SwtClient/GUI/LoadDialog.java new file mode 100644 index 0000000..dcdc4a8 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/LoadDialog.java @@ -0,0 +1,110 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient.GUI;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/*
+ * Class LoadDialog
+ *
+ * <em></em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 1 02-04-2006<br>
+ */
+public class LoadDialog extends Composite{
+
+ {
+ //Register as a resource user - SWTResourceManager will
+ //handle the obtaining and disposing of resources
+ SWTResourceManager.registerResourceUser(this);
+ }
+
+ private CLabel cLabel1;
+ private CLabel cLabel2;
+ private CLabel cLabel3;
+ private Shell parent;
+
+ public LoadDialog(Composite parent, int style) {
+ super(parent, style);
+ this.parent=(Shell)parent;
+ initDialog();
+ }
+
+ private void initDialog(){
+ GridLayout thisLayout = new GridLayout();
+ thisLayout.makeColumnsEqualWidth = true;
+ this.setLayout(thisLayout);
+ this.setSize(300,170);
+ {
+ Composite composite = new Composite(this, SWT.NONE);
+ FormLayout compositeLayout = new FormLayout();
+ composite.setLayout(compositeLayout);
+ GridData compositeLData = new GridData();
+ compositeLData.widthHint = 287;
+ compositeLData.heightHint = 165;
+ composite.setLayoutData(compositeLData);
+ composite.setVisible(true);
+ {
+ cLabel3 = new CLabel(composite, SWT.LEFT);
+ cLabel3.setText("Copyright (c) 2006 Manuel Traut and Volker Dahnke");
+ FormData cLabel3LData = new FormData();
+ cLabel3LData.width = 300;
+ cLabel3LData.height = 20;
+ cLabel3LData.left = new FormAttachment(0, 1000, 0);
+ cLabel3LData.top = new FormAttachment(0, 1000, 145);
+ cLabel3.setLayoutData(cLabel3LData);
+ cLabel3.setFont(SWTResourceManager.getFont("Times", 7, 0, false, false));
+ }
+ {
+ cLabel2 = new CLabel(composite, SWT.CENTER);
+ cLabel2.setText("Loading...");
+ FormData cLabel2LData = new FormData();
+ cLabel2LData.width = 105;
+ cLabel2LData.height = 25;
+ cLabel2LData.left = new FormAttachment(0, 1000, 91);
+ cLabel2LData.top = new FormAttachment(0, 1000, 123);
+ cLabel2.setLayoutData(cLabel2LData);
+ cLabel2.setFont(SWTResourceManager.getFont("Times", 12, 1, false, false));
+ }
+ {
+ cLabel1 = new CLabel(composite, SWT.CENTER);
+ FormData cLabel1LData = new FormData();
+ cLabel1LData.width = 200;
+ cLabel1LData.height = 120;
+ cLabel1LData.left = new FormAttachment(0, 1000, 40);
+ cLabel1LData.top = new FormAttachment(0, 1000, 0);
+ cLabel1.setLayoutData(cLabel1LData);
+ cLabel1.setImage(new Image(this.getDisplay(),"img/yalpV2.gif"));
+ }
+
+ }
+ }
+
+ public void show(){
+ Point size = this.getSize();
+ java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ Rectangle shellBounds = this.parent.computeTrim((screen.width-size.x)/2,(screen.height-size.y)/2,size.x,size.y);
+ this.parent.setLayout(new FillLayout());
+ this.parent.layout();
+ this.parent.setBounds(shellBounds);
+ this.parent.open();
+ }
+
+ public void close(){
+ this.parent.close();
+ }
+}
diff --git a/src/YalpClients/SwtClient/GUI/SWTResourceManager.java b/src/YalpClients/SwtClient/GUI/SWTResourceManager.java new file mode 100644 index 0000000..87dffc3 --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/SWTResourceManager.java @@ -0,0 +1,145 @@ +package YalpClients.SwtClient.GUI;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Widget;
+
+/*
+ * Class to manage SWT resources (Font, Color, Image and Cursor)
+ * There are no restrictions on the use of this code.
+ *
+ * You may change this code and your changes will not be overwritten,
+ * but if you change the version number below then this class will be
+ * completely overwritten by Jigloo.
+ * #SWTResourceManager:version4.0.0#
+ */
+public class SWTResourceManager {
+
+ private static HashMap resources = new HashMap();
+ private static Vector users = new Vector();
+ private static SWTResourceManager instance = new SWTResourceManager();
+
+ private static DisposeListener disposeListener = new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ users.remove(e.getSource());
+ if (users.size() == 0)
+ dispose();
+ }
+ };
+
+ /*
+ * This method should be called by *all* Widgets which use resources
+ * provided by this SWTResourceManager. When widgets are disposed,
+ * they are removed from the "users" Vector, and when no more
+ * registered Widgets are left, all resources are disposed.
+ * <P>
+ * If this method is not called for all Widgets then it should not be called
+ * at all, and the "dispose" method should be explicitly called after all
+ * resources are no longer being used.
+ */
+ public static void registerResourceUser(Widget widget) {
+ if (users.contains(widget))
+ return;
+ users.add(widget);
+ widget.addDisposeListener(disposeListener);
+ }
+
+ public static void dispose() {
+ Iterator it = resources.keySet().iterator();
+ while (it.hasNext()) {
+ Object resource = resources.get(it.next());
+ if (resource instanceof Font)
+ ((Font) resource).dispose();
+ else if (resource instanceof Color)
+ ((Color) resource).dispose();
+ else if (resource instanceof Image)
+ ((Image) resource).dispose();
+ else if (resource instanceof Cursor)
+ ((Cursor) resource).dispose();
+ }
+ resources.clear();
+ }
+
+ public static Font getFont(String name, int size, int style) {
+ return getFont(name, size, style, false, false);
+ }
+
+ public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) {
+ String fontName = name + "|" + size + "|" + style + "|" + strikeout + "|" + underline;
+ if (resources.containsKey(fontName))
+ return (Font) resources.get(fontName);
+ FontData fd = new FontData(name, size, style);
+ if (strikeout || underline) {
+ try {
+ Class lfCls = Class.forName("org.eclipse.swt.internal.win32.LOGFONT");
+ Object lf = FontData.class.getField("data").get(fd);
+ if (lf != null && lfCls != null) {
+ if (strikeout)
+ lfCls.getField("lfStrikeOut").set(lf, new Byte((byte) 1));
+ if (underline)
+ lfCls.getField("lfUnderline").set(lf, new Byte((byte) 1));
+ }
+ } catch (Throwable e) {
+ System.err.println(
+ "Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e);
+ }
+ }
+ Font font = new Font(Display.getDefault(), fd);
+ resources.put(fontName, font);
+ return font;
+ }
+
+ public static Image getImage(String url, Control widget) {
+ Image img = getImage(url);
+ if(img != null && widget != null)
+ img.setBackground(widget.getBackground());
+ return img;
+ }
+
+ public static Image getImage(String url) {
+ try {
+ url = url.replace('\\', '/');
+ if (url.startsWith("/"))
+ url = url.substring(1);
+ if (resources.containsKey(url))
+ return (Image) resources.get(url);
+ Image img = new Image(Display.getDefault(), instance.getClass().getClassLoader().getResourceAsStream(url));
+ if (img != null)
+ resources.put(url, img);
+ return img;
+ } catch (Exception e) {
+ System.err.println("SWTResourceManager.getImage: Error getting image "+url+", "+e);
+ return null;
+ }
+ }
+
+ public static Color getColor(int red, int green, int blue) {
+ String name = "COLOR:" + red + "," + green + "," + blue;
+ if (resources.containsKey(name))
+ return (Color) resources.get(name);
+ Color color = new Color(Display.getDefault(), red, green, blue);
+ resources.put(name, color);
+ return color;
+ }
+
+ public static Cursor getCursor(int type) {
+ String name = "CURSOR:" + type;
+ if (resources.containsKey(name))
+ return (Cursor) resources.get(name);
+ Cursor cursor = new Cursor(Display.getDefault(), type);
+ resources.put(name, cursor);
+ return cursor;
+ }
+
+}
diff --git a/src/YalpClients/SwtClient/GUI/SortListener.java b/src/YalpClients/SwtClient/GUI/SortListener.java new file mode 100644 index 0000000..a2ff35a --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/SortListener.java @@ -0,0 +1,63 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient.GUI;
+
+import java.text.Collator;
+import java.util.Locale;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+
+/*
+ * Class SortListener
+ *
+ * <em></em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 1 02-04-2006<br>
+ */
+public class SortListener implements Listener{
+ private Table table;
+ private int colum,numColum;
+ private GUI gui;
+
+ public SortListener(GUI gui,Table table,int colum,int numColum){
+ this.colum=colum;
+ this.numColum=numColum;
+ this.table=table;
+ this.gui=gui;
+ }
+
+ public void handleEvent(Event e) {
+ TableItem[] items = table.getItems();
+ Collator collator = Collator.getInstance(Locale.getDefault());
+ for (int i = 1; i < items.length; i++) {
+ String value1 = items[i].getText(colum);
+ for (int j = 0; j < i; j++) {
+ String value2 = items[j].getText(colum);
+ if (collator.compare(value1, value2) < 0) {
+ String[] values= new String[numColum];
+ for(int g=0;g<numColum;g++){
+ values[g]= items[i].getText(g);
+ }
+ items[i].dispose();
+ TableItem item = new TableItem(table, SWT.NONE, j);
+ item.setText(values);
+ items = table.getItems();
+ break;
+ }
+ }
+ }
+ gui.changeComposite.setVisible(false);
+ table.setSelection(0);
+ }
+}
+
diff --git a/src/YalpClients/SwtClient/GUI/StartDialog.java b/src/YalpClients/SwtClient/GUI/StartDialog.java new file mode 100644 index 0000000..11ecc7f --- /dev/null +++ b/src/YalpClients/SwtClient/GUI/StartDialog.java @@ -0,0 +1,236 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient.GUI;
+
+import YalpClients.SwtClient.Model;
+import YalpInterfaces.AccessRights;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/*
+ * Class StartDialog
+ *
+ * <em></em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 1 02-04-2006<br>
+ */
+public class StartDialog extends Composite {
+
+ {
+ //Register as a resource user - SWTResourceManager will
+ //handle the obtaining and disposing of resources
+ SWTResourceManager.registerResourceUser(this);
+ }
+ private Display display;
+ private CLabel cLabel1;
+ private CLabel LogoLabel;
+ private Model model;
+ private Composite parent;
+ private Composite composite;
+ private CLabel logonLable;
+ private Button ok;
+ private Text passwd;
+ private Text username;
+ private CLabel passwdLable;
+ private CLabel usernameLable;
+
+
+ public StartDialog(Composite parent,Model model, int style) {
+ super(parent, style);
+
+ this.parent=parent;
+ this.model=model;
+ this.display=Display.getDefault();
+ initStartDialog();
+ }
+
+ private void initStartDialog(){
+ GridLayout thisLayout = new GridLayout();
+ thisLayout.makeColumnsEqualWidth = true;
+ this.setLayout(thisLayout);
+ this.setSize(300,150);
+ Listener listener =new Listener() {
+ public void handleEvent(org.eclipse.swt.widgets.Event evt) {
+ if (evt.character==SWT.CR){
+ OkPressed();
+ }
+ }
+ };
+ addListener(SWT.KeyDown,listener);
+ {
+ composite = new Composite(this, SWT.NONE);
+ FormLayout compositeLayout = new FormLayout();
+ composite.setLayout(compositeLayout);
+ GridData compositeLData = new GridData();
+ compositeLData.widthHint = 287;
+ compositeLData.heightHint = 140;
+ composite.setLayoutData(compositeLData);
+ composite.setVisible(true);
+ composite.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character==SWT.CR){
+ OkPressed();
+ }
+ }
+ });
+ {
+ cLabel1 = new CLabel(composite, SWT.NONE);
+ FormData cLabel1LData = new FormData();
+ cLabel1LData.width = 120;
+ cLabel1LData.height = 20;
+ cLabel1LData.left = new FormAttachment(0, 1000, 93);
+ cLabel1LData.top = new FormAttachment(0, 1000, 40);
+ cLabel1.setLayoutData(cLabel1LData);
+ Color col =display.getSystemColor(SWT.COLOR_RED);
+ cLabel1.setForeground(col);
+ cLabel1.setFont(SWTResourceManager.getFont("Times", 10, 1, false, false));
+ }
+ {
+ LogoLabel = new CLabel(composite, SWT.NONE);
+ FormData LogoLabelLData = new FormData();
+ LogoLabelLData.width = 70;
+ LogoLabelLData.height = 42;
+ LogoLabelLData.left = new FormAttachment(0, 1000, 77);
+ LogoLabelLData.top = new FormAttachment(0, 1000, 0);
+ LogoLabelLData.right = new FormAttachment(1000, 1000, -140);
+ LogoLabelLData.bottom = new FormAttachment(1000, 1000, -98);
+ LogoLabel.setLayoutData(LogoLabelLData);
+ LogoLabel.setImage(new Image(this.getDisplay(),"img/yalpV2_mittel.gif"));
+ }
+ {
+ logonLable = new CLabel(composite, SWT.BEGINNING);
+ logonLable.setText("Login");
+ FormData logonLableLData = new FormData();
+ logonLableLData.width = 70;
+ logonLableLData.height = 28;
+ logonLableLData.left = new FormAttachment(0, 1000, 147);
+ logonLableLData.top = new FormAttachment(0, 1000, 5);
+ logonLable.setLayoutData(logonLableLData);
+ logonLable.setFont(SWTResourceManager.getFont("Times", 14, 1, false, false));
+ }
+ {
+ username = new Text(composite, SWT.NONE);
+ FormData usernameLData = new FormData();
+ usernameLData.width = 117;
+ usernameLData.height = 15;
+ usernameLData.left = new FormAttachment(0, 1000, 120);
+ usernameLData.top = new FormAttachment(0, 1000, 65);
+ username.setLayoutData(usernameLData);
+ username.setFocus();
+ username.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character==SWT.CR){
+ OkPressed();
+ }
+ }
+ });
+ }
+ {
+ passwd = new Text(composite, SWT.PASSWORD);
+ FormData passwdLData = new FormData();
+ passwdLData.width = 117;
+ passwdLData.height = 15;
+ passwdLData.left = new FormAttachment(0, 1000, 120);
+ passwdLData.top = new FormAttachment(0, 1000, 88);
+ passwd.setLayoutData(passwdLData);
+ passwd.addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent evt) {
+ if (evt.character==SWT.CR){
+ OkPressed();
+ }
+ }
+ });
+ }
+ {
+ ok = new Button(composite, SWT.PUSH | SWT.CENTER);
+ ok.setText("OK");
+ FormData okLData = new FormData();
+ okLData.width = 65;
+ okLData.height = 21;
+ okLData.left = new FormAttachment(0, 1000, 110);
+ okLData.top = new FormAttachment(0, 1000, 115);
+ ok.setLayoutData(okLData);
+ ok.setFont(SWTResourceManager.getFont("Times", 10, 1, false, false));
+ ok.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ OkPressed();
+ }
+ });
+ }
+ {
+ passwdLable = new CLabel(composite, SWT.NONE);
+ passwdLable.setText("Password:");
+ FormData passwdLableLData = new FormData();
+ passwdLableLData.width = 70;
+ passwdLableLData.height = 20;
+ passwdLableLData.left = new FormAttachment(0, 1000, 35);
+ passwdLableLData.top = new FormAttachment(0, 1000, 83);
+ passwdLable.setLayoutData(passwdLableLData);
+ passwdLable.setFont(SWTResourceManager.getFont("Times", 10, 0, false, false));
+ }
+ {
+ usernameLable = new CLabel(composite, SWT.NONE);
+ usernameLable.setText("Username:");
+ FormData usernameLableLData = new FormData();
+ usernameLableLData.width = 70;
+ usernameLableLData.height = 20;
+ usernameLableLData.left = new FormAttachment(0, 1000, 35);
+ usernameLableLData.top = new FormAttachment(0, 1000, 60);
+ usernameLable.setLayoutData(usernameLableLData);
+ usernameLable.setFont(SWTResourceManager.getFont("Times", 10, 0, false, false));
+ }
+ }
+ this.layout();
+
+ }
+ private void OkPressed(){
+ AccessRights kind;
+ kind = model.userVerify(username.getText(), passwd.getText());
+
+ if (kind.value() == AccessRights._NO_YALP_SERVER ) {
+ cLabel1.setText("Server offline");
+ } else if (kind.value() == AccessRights._DENY ){
+ cLabel1.setText("Access Denied");
+ username.setText("");
+ passwd.setText("");
+ username.setFocus();
+ } else {
+ display.close();
+ InitGUI gui = new InitGUI(model, kind);
+ }
+
+ }
+
+ public void show(){
+ ((Shell)this.parent).setImage(new Image(display,"img/yalpV2_klein.gif"));
+ ((Shell)this.parent).setText("yalp");
+ Point size = this.getSize();
+ java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ Rectangle shellBounds = this.parent.computeTrim((screen.width-size.x)/2,(screen.height-size.y)/2,size.x,size.y);
+ this.parent.setLayout(new FillLayout());
+ this.parent.layout();
+ this.parent.setBounds(shellBounds);
+ ((Shell)this.parent).open();
+ while (!this.parent.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+
+}
diff --git a/src/YalpClients/SwtClient/Model.java b/src/YalpClients/SwtClient/Model.java new file mode 100755 index 0000000..3c48615 --- /dev/null +++ b/src/YalpClients/SwtClient/Model.java @@ -0,0 +1,744 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpClients.SwtClient;
+
+import YalpInterfaces.*;
+import YalpClients.*;
+
+import java.beans.XMLDecoder;
+import java.beans.XMLEncoder;
+import java.io.*;
+import java.net.Inet4Address;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+
+import org.omg.CosNaming.*;
+import org.omg.CosNaming.NamingContextPackage.*;
+import org.omg.CORBA.*;
+
+/*
+ * Class Model
+ *
+ * <em>Implementiert die Schnittstellenfunktionen zur Steuerung des Servers
+ * (Datenbankinhalte schreiben, lesen; Streaming steuern</em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 0.6 14-12-2005<br>
+ *
+ * @see client.GUI
+ */
+
+public class Model {
+
+ public ServerControlInterface srvCon;
+ private Process vlcPlayer;
+ private Output actualStream;
+ private Output streamInfo;
+ private ArrayList<Media> findMedia;
+ private ArrayList<Media> editMedia;
+ private ArrayList<Media> toPlaylist;
+ private ArrayList<Media> playList;
+ private ArrayList<YalpUser> userList;
+ private ClientConfiguration settings;
+ private String clientIP;
+ private String curPasswd;
+ private AccessRights userGroup=AccessRights.DENY;
+ private String userName;
+ private Boolean playback = false;
+ private Boolean logoff= false;
+ private Session session;
+/*
+ * Instances srvConnection to Registry, DbConnection, ServerControl
+ * and VlcStreamer. Also instances Class variables
+ */
+ public Model(String[] argv) {
+
+ this.settings=new ClientConfiguration();
+ loadConfig("ClientConfiguration.xml");
+ writeConfig("ClientConfiguration.xml");
+
+ try {
+ ORB orb = ORB.init(argv, null);
+
+ org.omg.CORBA.Object objRef =
+ orb.resolve_initial_references("NameService");
+
+ NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
+
+ String name = "YALP_Server";
+ srvCon = ServerControlInterfaceHelper.narrow(ncRef.resolve_str(name));
+ } catch (Exception e) {// DEBUG
+ String errorStr="couldn't connect to YALP Server";
+
+ MessageBox messageBox = new MessageBox(
+ new Shell(Display.getDefault(),SWT.MIN), SWT.OK );
+
+ System.out.println(e);
+ messageBox.setMessage(errorStr);
+ messageBox.open();
+ System.exit(0);
+ }
+
+ // determine client IP Adress
+ try {
+ this.clientIP = Inet4Address.getLocalHost().getHostAddress();
+ System.out.println(this.clientIP);
+ } catch (UnknownHostException e) {
+ String errorStr = "Model.model: determine IP failed";
+
+ MessageBox messageBox = new MessageBox(
+ new Shell(Display.getDefault(),SWT.MIN), SWT.OK );
+
+ System.out.println(errorStr);
+ messageBox.setMessage(errorStr);
+ messageBox.open();
+ System.exit(0);
+ }
+ this.userList = new ArrayList<YalpUser>();
+ this.playList = new ArrayList<Media>();
+ this.toPlaylist = new ArrayList<Media>();
+ }
+
+/*
+ * write Configuration to XML File
+ *
+ * @param fileName
+ * @return boolean: true if succesful
+ */
+ public boolean writeConfig(String fileName) {
+ try {
+ FileOutputStream srvConfigFile = new FileOutputStream(fileName);
+ XMLEncoder srvConfigWriter = new XMLEncoder(srvConfigFile);
+ srvConfigWriter.writeObject(settings.serverIP);
+ srvConfigWriter.writeObject(settings.classServerPort);
+ srvConfigWriter.writeObject(settings.registryPort);
+ srvConfigWriter.writeObject(settings.vlcCommand);
+ srvConfigWriter.close();
+ } catch (FileNotFoundException fnfe) {
+ return false;
+ }
+ return true;
+ }
+
+/*
+ * load Configuration from XML File if possible
+ *
+ * @param fileName
+ * @return boolean: true if succesful
+ */
+ public boolean loadConfig(String fileName){
+ try{
+ FileInputStream srvConfigFile = new FileInputStream(fileName);
+ XMLDecoder srvConfigLoader = new XMLDecoder(srvConfigFile);
+ System.out.println(srvConfigFile);
+ settings.serverIP = (String)srvConfigLoader.readObject();
+ settings.classServerPort= (Integer)srvConfigLoader.readObject();
+ settings.registryPort = (Integer)srvConfigLoader.readObject();
+ settings.vlcCommand = (String)srvConfigLoader.readObject();
+ srvConfigLoader.close();
+ } catch(FileNotFoundException fnfe) {
+ System.out.println("Configuration not found, loading defaults...");
+ return false;
+ } catch(ClassCastException cce) {
+ System.out.println("Errors in Configuration, loading defaults...");
+ return false;
+ }
+ return true;
+ }
+
+/*
+ * get acutal srvConfig object
+ *
+ * @return ClientConfiguration: aktuelle Konfiguration
+ */
+ public ClientConfiguration getConfig(){
+ return this.settings;
+ }
+
+/*
+ * setzen und speichern eines ClientConfiguration Files
+ *
+ * @param set
+ * ClientConfiguration.xml
+ * @return boolean: true if succesful written Configuration
+ */
+ public boolean setConfig(ClientConfiguration set){
+ this.settings = set;
+ return this.writeConfig("ClientConfiguration.xml");
+ }
+
+/*
+ * Sends YalpUsername and passwd to Server and returns YalpUsergroup
+ *
+ * @param username
+ * @param passwd
+ * @return AccessRights
+ */
+ public AccessRights userVerify(String username,String passwd){
+ this.userName=username;
+ this.curPasswd = passwd;
+ YalpErrorHolder err = new YalpErrorHolder();
+ SessionHolder sess = new SessionHolder();
+ try{
+ // log on server
+ this.srvCon.clientLogon(this.userName,passwd,this.clientIP,sess,err);
+ this.session = sess.value;
+ this.userGroup = sess.value.me.level;
+ /*
+ } catch (RemoteException e) {
+ System.out.println("client.Model: Logon on Server failed 1"+ e);
+ e.printStackTrace();
+ System.out.println("client.Model: Logon on Server failed 1");
+ } catch (MalformedURLException e) {
+ System.out.println("client.Model: Logon on Server failed 2");
+ } catch (SQLException e) {
+ System.out.println("client.Model: Logon on Server failed 3");
+ } catch (NotBoundException e) {
+ System.out.println("client.Model: Logon on Server failed 4");
+ */
+ }catch(NullPointerException e){
+ System.out.println("YALP Server couldn't be reached");
+ this.userGroup = AccessRights.NO_YALP_SERVER;
+ }
+ return this.userGroup;
+ }
+
+/*
+ * Gets a list with all YalpUsers from the server
+ *
+ * @return ArrayList<YalpUser> all registered YalpUsers
+ */
+ public ArrayList<YalpUser> getUser(){
+ YalpErrorHolder err = new YalpErrorHolder();
+ try{
+ UsersHolder usr = new UsersHolder();
+ this.srvCon.getUser(usr, err);
+ this.userList = new ArrayList<YalpUser>(usr.value.length);
+ for(int i = 0; i < usr.value.length; i++)
+ this.userList.add(usr.value[i]);
+ }catch(Exception e){
+ System.out.println("Exceoption in Model userList "+ e);
+ }
+ return userList;
+ }
+
+/*
+ * Sends User change request to server
+ *
+ * @param user
+ * Configuration with changes on specific YalpUser
+ */
+ public void changeUser(YalpUser user, String passwd, Action action) {
+ YalpErrorHolder err = new YalpErrorHolder();
+ try{
+ this.srvCon.changeUser( user,
+ passwd,
+ action,
+ err );
+ System.out.println(err.value.descr);
+ }catch(Exception e){
+ System.out.println("Exceoption in Model changeUser "+ e);
+ }
+ }
+
+/*
+ * Sends Media change request to server and refreshes Model data
+ *
+ * @param media
+ * to change
+ * @return boolean: succesful changed media
+ */
+ public Boolean changeMedia(Media media, Action action){
+ YalpErrorHolder err = new YalpErrorHolder();
+ try{
+ this.srvCon.changeMedia(media, action, err);
+ if(err.value.code == YalpErrorCode.OK){
+ Media result;
+ for (int i=0;i<this.editMedia.size();i++){
+ result=this.editMedia.get(i);
+ /* t.b.d. alter to new db desgin
+ if (result.id==media.id){
+ result.type=media.type;
+ result.title=media.title;
+ result.author=media.author;
+ result.album=media.album;
+ result.category=media.category;
+ result.year=media.year;
+ result.duration=media.duration;
+ result.aBitrate=media.aBitrate;
+ result.vBitrate=media.vBitrate;
+ result.resolution=media.resolution;
+ result.ownerId=media.ownerId;
+ result.lastEdit=media.lastEdit;
+ result.path=media.path;
+ result.name=media.name;
+ return true;
+ }
+ */
+ }
+ }
+ } catch(Exception e) {
+ System.out.println("Exceoption in Model changeUser "+ e);
+ }
+ return false;
+ }
+
+/*
+ * adds Media with given id to Playlist
+ *
+ * @param id
+ */
+ public void add2PlayList(int id){
+ Boolean notfound=true;
+ for (int i=0;(i<this.findMedia.size())&& (notfound);i++){
+ Media result=this.findMedia.get(i);
+ if (result.id==id){
+ String name = result.name;
+ String path = result.path;
+ if(playback){
+ this.add2Stream(name, path);
+ }
+ this.playList.add(result);
+ this.toPlaylist.add(result);
+ notfound=false;
+ }
+ }
+ }
+
+/*
+ * Removes Media with given id from Playlist
+ *
+ * @param id
+ */
+ public void removeFromPlayList(int id){
+ /* t.b.d.
+ this.playList.remItem(id);
+ this.toPlaylist.remove(id);
+ */
+ }
+
+/*
+ * Returns List with items to play
+ *
+ * @return ArrayList<Media>: ArrayList to create Playlist from
+ */
+ public ArrayList<Media> getToPlaylist(){
+ return this.toPlaylist;
+ }
+
+/*
+ * Creates new Stream with actual playlist
+ *
+ * @return Streaminfo: about new created Stream, Client should use this,
+ * information to get the Information howto receive the stream
+ */
+ public Output createOutput(){
+ /* t.b.d. former createStream */
+ this.streamInfo.outputAction = Action.CREATE;
+ Media[] a = {};
+ this.streamInfo.playlist = this.playList.toArray(a);
+ return this.streamInfo;
+ }
+
+/*
+ * Sends search request to server and refreshes Model data
+ *
+ * @param request
+ * Search Request
+ * @param kind
+ * 1 - search in first Window; other ints: search in other window
+ * (admins edit view)
+ * @return int: number of results
+ */
+ public int search(String request, ArrayList<MediaType> types, int kind){
+ YalpErrorHolder err = new YalpErrorHolder();
+ MediasHolder result = new MediasHolder();
+ try{
+ MediaType[] a = {};
+ if (kind == 1){
+ srvCon.search(request, types.toArray(a), result, err);
+ for(int i = 0; i < result.value.length; i++)
+ this.findMedia.add(result.value[i]);
+ return this.findMedia.size();
+ } else {
+ srvCon.search(request, types.toArray(a), result, err);
+ for(int i = 0; i < result.value.length; i++)
+ this.editMedia.add(result.value[i]);
+ return this.editMedia.size();
+ }
+ } catch(Exception e){
+ System.out.println("Exceoption in Model search "+ e);
+ return 0;
+ }
+ }
+
+/*
+ * Returns the search result
+ *
+ * @param kind
+ * 1 - for searchMedia of mainwindow; 2 - for searchMedia of editView
+ * @return ArrayList<Media>: last found medias
+ */
+
+ public ArrayList<Media> getMedia(int kind){
+ if (kind==1) return this.findMedia;
+ else return this.editMedia;
+ }
+
+/*
+ * Retuns search result with given id
+ *
+ * @param id
+ * of the result
+ * @param kind
+ * 1 - for mainWindow, 2 for admins editView
+ * @return Media: searchMedia, with specified ID
+ */
+ public Media getMediaWithId(int id,int kind){
+ ArrayList<Media> resultList;
+ if (kind==1)resultList= this.findMedia;
+ else resultList=this.editMedia;
+ for (int i=0;(i<resultList.size());i++){
+ Media result=resultList.get(i);
+ if (result.id==id){
+ return result;
+ }
+ }
+ return null;
+ }
+
+/*
+ * Retuns id of YalpUser with given username
+ *
+ * @param username
+ * @return int: useriD
+ */
+ public int getOwnerid(String username){
+ ArrayList<YalpUser> ownerList =this.userList;
+ for (YalpUser owner:ownerList){
+ if (owner.name.equals(username)){
+ return owner.id;
+ }
+ }
+ return 0;
+ }
+
+/*
+ * Returns MediaType as string
+ *
+ * @param mediatype
+ * @return string
+ */
+ public String getTypeName(MediaType type)
+ {
+ switch(type.value())
+ {
+ case MediaType._IMAGE:
+ return "image";
+ case MediaType._SOUND:
+ return "sound";
+ case MediaType._VIDEO:
+ return "video";
+ default:
+ return "unknown";
+ }
+ }
+
+/*
+ * Returns AccessRights as string
+ *
+ * @param mediatype
+ * @return string
+ */
+ public String accessRightsName(AccessRights type)
+ {
+ switch(type.value())
+ {
+ case AccessRights._USER:
+ return "user";
+ case AccessRights._ADMIN:
+ return "admin";
+ case AccessRights._DENY:
+ return "no login";
+ default:
+ return "unknown";
+ }
+ }
+
+
+/*
+ * Sets class variable actualStream to given value
+ *
+ * @param aStream
+ * stream to srvControl via play, pause, etc
+ */
+ public void setActualStream(Output aStream){
+ this.actualStream = aStream;
+ }
+
+/*
+ * Starts Video Lan Player
+ *
+ * @return boolean: true if vlc can be started and a stream is actualStream
+ */
+ private boolean startVLC(){
+
+ String vlcCmd = settings.vlcCommand +
+ " --reset-srvConfig --video-on-top -I telnet --telnet-port 12345 ";
+/*
+ switch (this.actualStream.getAccess()){
+ case UDP:
+ vlcCmd += "udp:@";
+ break;
+ case HTTP:
+ vlcCmd += "http://";
+ break;
+ default:
+ System.out.println(
+ "client.Model.startVLC: playback this type is not supported" );
+ }
+*/
+ vlcCmd += this.actualStream.info.params;
+ System.out.println(vlcCmd);
+
+ try {
+ this.vlcPlayer = Runtime.getRuntime().exec(vlcCmd);
+ } catch (IOException e) {
+ System.out.println("client.Model.startVLC: starting vlcPlayer failed");
+ return false;
+ }
+ return true;
+ }
+
+/*
+ * Stops Video Lan Player
+ *
+ */
+ private void stopVLC(){
+ this.playback = false;
+ this.vlcPlayer.destroy();
+ }
+
+/*
+ * Starts playback of actual playlist
+ *
+ * @return void
+ */
+ public boolean play(){
+
+ this.playback = true;
+
+ this.actualStream = this.createOutput();
+ this.actualStream.destIp = this.clientIP;
+
+ YalpErrorHolder err = new YalpErrorHolder();
+
+ OutputHolder tmp = new OutputHolder(this.actualStream);
+ this.srvCon.control(tmp, err);
+ this.actualStream = tmp.value;
+
+ this.actualStream.outputAction = Action.START;
+ OutputHolder tmp2 = new OutputHolder(this.actualStream);
+ this.srvCon.control(tmp2, err);
+ this.actualStream = tmp2.value;
+ this.startVLC();
+ return true;
+ }
+
+/*
+ * Adds a new Media to Playlist. Only during playback
+ *
+ * @param name
+ * @param path
+ * @return boolean: true if succesful added
+ */
+ public boolean add2Stream(String name, String path){
+
+ YalpErrorHolder err = new YalpErrorHolder();
+ Media[] empty = {};
+ this.actualStream.playlist = empty;
+
+ Media media = new Media();
+ media.path = path;
+ media.fileName = name;
+
+ this.actualStream.playlist[this.actualStream.playlist.length] = media;
+ this.actualStream.outputAction = Action.CREATE;
+
+ OutputHolder tmp = new OutputHolder(this.actualStream);
+ this.srvCon.control(tmp, err);
+ this.actualStream = tmp.value;
+ return true;
+ }
+
+/*
+ * Stops playback
+ *
+ * @return boolean: false - if srvConnection to streamer failed
+ */
+ public boolean stop(){
+ YalpErrorHolder err = new YalpErrorHolder();
+ this.actualStream.outputAction = Action.STOP;
+ OutputHolder tmp = new OutputHolder(this.actualStream);
+ this.srvCon.control(tmp,err);
+ this.actualStream = tmp.value;
+ this.stopVLC();
+ return true;
+ }
+
+/*
+ * jumps to next media in playlist
+ *
+ * @return boolean: false - if srvConnection to streamer failed
+ */
+ public boolean next(){
+ YalpErrorHolder err = new YalpErrorHolder();
+ this.actualStream.outputAction = Action.FORWARD;
+ OutputHolder tmp = new OutputHolder(this.actualStream);
+ this.srvCon.control(tmp,err);
+ this.actualStream = tmp.value;
+ return true;
+ }
+
+/*
+ * Pauses playback
+ *
+ * @return boolean: false - if srvConnection to streamer failed
+ */
+ public boolean pause(){
+ YalpErrorHolder err = new YalpErrorHolder();
+ this.actualStream.outputAction = Action.PAUSE;
+ OutputHolder tmp = new OutputHolder(this.actualStream);
+ this.srvCon.control(tmp,err);
+ this.actualStream = tmp.value;
+ return true;
+ }
+
+/*
+ * Causes the server to clean up and shutdown
+ *
+ */
+ public void serverShutdown(){
+ if (this.playback)
+ this.stop();
+ this.srvCon.serverShutdown();
+ }
+
+/*
+ * Checks if the server is still alive if not Client shutdown
+ *
+ */
+ public void serverStillAlive(){
+ // try{
+ // srvCon.ping();
+ /* }catch (RemoteException e){
+ if (this.playback)
+ this.stopVLC();
+ String errorStr="Server shutdown - Client is going down too";
+
+ MessageBox messageBox = new MessageBox(
+ new Shell(Display.getDefault(),SWT.MIN), SWT.OK);
+
+ System.out.println(errorStr);
+ messageBox.setMessage(errorStr);
+ messageBox.open();
+ System.exit(0);
+ } */
+ }
+
+/*
+ * Returns client IP address
+ *
+ * @return String: ipAddress
+ */
+ public String getClientIp(){
+ return this.clientIP;
+ }
+
+/*
+ * Returns username of logged in user
+ *
+ * @return String: username
+ */
+ public String getYalpUserName(){
+ return this.userName;
+ }
+
+/*
+ * Returns indication if playback is runing
+ *
+ * @return boolean: true - if is play'in
+ */
+ public Boolean getPlayback(){
+ return this.playback;
+ }
+
+/*
+ * Get Total amount of streams played
+ *
+ * @return int: number of Streams totally played
+ *
+ public int getAllStreamNum(){
+ try{
+ return this.srvCon.getStreamCounter().getAllStreams();
+ }catch (Exception e){
+ System.out.println("Exception in Model.getAllStreamNum"+e);
+ }
+ return -1;
+ }
+ */
+
+/*
+ * Gets amount of Streams actual playing
+ *
+ * @return int: number of Streams play'in at the moment
+ *
+ public int getActualStreamNum(){
+ try{
+ return this.srvCon.getStreamCounter().getActualStreams();
+ }catch (Exception e){
+ System.out.println("Exception in Model.getActualStreamNum"+e);
+ }
+ return -1;
+ }
+ */
+
+/*
+ * Sets class variable logoff to true and logs off from server
+ */
+ public void logoff(){
+ YalpErrorHolder err = new YalpErrorHolder();
+ try{
+ this.logoff=true;
+ this.srvCon.clientLogoff(this.session, err);
+ }catch(Exception e) {// DEBUG
+ System.out.println("Model Exeptions in logoff");
+ e.printStackTrace();
+ }
+ }
+
+/*
+ * Returns indication if client is logging of
+ *
+ * @return Boolean: true - if is logging of
+ */
+ public Boolean getLogoff(){
+ return this.logoff;
+ }
+}
diff --git a/src/YalpClients/SwtClient/SwtClient.java b/src/YalpClients/SwtClient/SwtClient.java new file mode 100755 index 0000000..513d4ff --- /dev/null +++ b/src/YalpClients/SwtClient/SwtClient.java @@ -0,0 +1,61 @@ +/*
+ *
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ *
+ */
+package YalpClients.SwtClient;
+
+import YalpClients.SwtClient.GUI.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+
+/*
+ * Class SwtClient
+ *
+ * <em>static main method</em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 0.1 20-11-2005<br>
+ */
+public class SwtClient{
+
+/*
+ * Client initialization
+ *
+ * @param argv
+ * arguments which are not used
+ */
+ public static void main (String[] argv) {
+ try{
+ System.setProperty("java.security.policy","client.policy");
+ }
+ catch (Exception e) {//DEBUG
+ System.out.println ("Server SecurityManagerExeptions not caught jet " + e);
+ System.exit(0);
+ }
+
+ LoadDialog load = new LoadDialog(
+ new Shell(Display.getDefault(),SWT.NONE), SWT.NONE);
+
+ load.show();
+ final Model model = new Model(argv);
+ load.close();
+
+ StartDialog start =
+ new StartDialog(new Shell(Display.getDefault(),SWT.MIN),model, SWT.NONE);
+
+ start.show();
+
+ return;
+ }
+}
diff --git a/src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java b/src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java new file mode 100644 index 0000000..b6ee2ce --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/DatabaseDefines.java @@ -0,0 +1,65 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+package YalpInputs.YalpPGSqlInput;
+
+/*
+ * Class DatabaseDefines
+ *
+ * <em></em>
+ *
+ * @author Manuel Traut
+ *
+ * @version 0.1 28-08-2008<br>
+ *
+ */
+
+public class DatabaseDefines {
+
+ public String dbConnection="jdbc:postgresql://10.0.3.20:5432/yalp_media";
+ public String dbUser="yalp";
+ public String dbPasswd="huhu";
+
+/*
+ * set string for dbConnection
+ * @param dbConnection
+ * "jdbc:postgresql://<serverIP>:<portOfDB>/<dataBaseName>";
+ */
+ public void setDBConnection(String dbConnection){
+ this.dbConnection = dbConnection;
+ }
+
+/*
+ * set userName for db Edit
+ * @param dbUser
+ */
+ public void setDBUser(String dbUser){
+ this.dbUser = dbUser;
+ }
+
+/*
+ * set string for db Password
+ * @param DBPasswd
+ */
+ public void setDBPasswd(String DBPasswd){
+ this.dbPasswd = DBPasswd;
+ }
+
+ public String getDBConnection(){
+ return this.dbConnection;
+ }
+
+ public String getDBUser(){
+ return this.dbUser;
+ }
+
+ public String getDBPasswd(){
+ return this.dbPasswd;
+ }
+}
diff --git a/src/YalpInputs/YalpPGSqlInput/PGSqlInput.java b/src/YalpInputs/YalpPGSqlInput/PGSqlInput.java new file mode 100644 index 0000000..531f53d --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/PGSqlInput.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpInputs.YalpPGSqlInput; + +import YalpInterfaces.*; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +/* + * Class PGSqlInput + * + * <em>Postgre SQL database connection</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 2.0 2008-09-23<br> + */ +public class PGSqlInput { + + private static ORB orb; + private static POA poa; + private static YalpInputPluginImpl psql; + private static InputPluginInterface inputPlugin; + private static ServerControlInterface srvCon; + private static PluginInfo pluginInfo; + + public PGSqlInput(String[] argv) { + + pluginInfo = new PluginInfo(); + pluginInfo.name = "Postgre SQL Input Plugin"; + pluginInfo.description = "provides information about files, which are stored on a harddisk and have been indicated to the YALP Postgre SQL database"; + pluginInfo.type = PluginType.INPUT_PLUGIN; + pluginInfo.supportedTypes = new MediaType[3]; + pluginInfo.supportedTypes[0] = MediaType.IMAGE; + pluginInfo.supportedTypes[1] = MediaType.VIDEO; + pluginInfo.supportedTypes[2] = MediaType.SOUND; + pluginInfo.access = new AccessInfo(); + pluginInfo.access.name = "local files"; + pluginInfo.access.description = ""; + pluginInfo.access.executable = ""; + pluginInfo.access.params = ""; + pluginInfo.access.type = AccessType.FILES; + + try { + this.orb = ORB.init(argv, null); + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + } catch(Exception e) { + /* t.b.d. error handling */ + System.out.println("couldn't host plugin implementation"); + } + + try { + poa.the_POAManager().activate(); + } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { + /* t.b.d. error handling */ + System.out.println("poa inactive"); + } + + YalpErrorHolder err = new YalpErrorHolder(); + + try { + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Server"; + srvCon = ServerControlInterfaceHelper.narrow(ncRef.resolve_str(name)); + } catch (Exception e) { + System.out.println("Couldn't connect to YALP Server"); + System.exit(0); + } + + psql = new YalpInputPluginImpl(); + psql.setORB(orb); + + try { + poa.activate_object(psql); + org.omg.CORBA.Object ref = poa.servant_to_reference(psql); + inputPlugin = InputPluginInterfaceHelper.narrow(ref); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Postgre_SQL_Input"; + NameComponent path[] = ncRef.to_name(name); + ncRef.rebind(path, inputPlugin); + + PluginInfoHolder tmp = new PluginInfoHolder(pluginInfo); + srvCon.ping(err); + System.out.println(err.value.descr); + srvCon.registerInputPlugin(inputPlugin, tmp, err ); + pluginInfo = tmp.value; + + if(err.value.code != YalpErrorCode.OK) + System.out.println("registring inputplugin failed"); + else + System.out.println("input plugin registered"); + + orb.run(); + + } catch (Exception e) { + System.out.println("binding plugin failed 1"); + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java b/src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java new file mode 100644 index 0000000..7f599be --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/YalpInputPluginImpl.java @@ -0,0 +1,189 @@ +package YalpInputs.YalpPGSqlInput; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.*; +import java.sql.*; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; + +import YalpInterfaces.*; + +public class YalpInputPluginImpl extends InputPluginInterfacePOA { + + private String db; + private String dbuser; + private String dbpasswd; + private Statement stat; + private Connection con; + private PluginInfo pluginInfo; + private ORB orb; + + public YalpInputPluginImpl() + { + System.out.println("YalpInputPluginImpl()"); + } + + public void setORB(ORB _orb) + { + orb = _orb; + String db = "jdbc:postgresql://localhost:5432/yalp"; + String dbYalpUser = "yalp"; + String dbPasswd = "yalp"; + + try{ + dbuser = dbYalpUser; + dbpasswd = dbPasswd; + Class.forName("org.postgresql.Driver"); + con = DriverManager.getConnection(db,dbuser,dbpasswd); + System.out.println("YalpPGSqlInput: db connection established"); + stat= con.createStatement(); + } catch (SQLException e) { + System.out.println("Exception in PGSqlInput Constructor: "+e); + } catch (ClassNotFoundException e) { + System.out.println("Exception in PGSqlInput Constructor: "+e); + } + } + +/* + * submits changes to yalpMediaDatabase + * + * @param change + * describes the change to commit + * @return int + * -1 if failed + */ + public void changeMedia (Media toChange, Action todo, YalpErrorHolder err) { + /* t.b.d. alter this to new database design + try{ + String sql1,sql2,sql3; + int Return; + switch (change.updateType){ + // if updateType is UPDATE + case UPDATE: + sql1="update \"medien\" set \"type\"='"+change.type+"', \"title\"='"+change.title+"', \"author\"='"+change.author+"', \"album\"='"+change.album+"', \"category\"='"+change.category+"', \"year\"='"+change.year+"', \"duration\"='"+change.duration+"', \"aBitrate\"="+change.aBitrate+", \"vBitrate\"="+change.vBitrate+", \"resolution\"='"+change.resolution+"', \"lastEdit\"='"+new java.util.Date(System.currentTimeMillis()).toString()+"' where \"id\"= "+change.id+" ;"; + System.out.println(sql1); + Return=stat.executeUpdate(sql1); + break; + // if updateType is INSERT INTO + case INSERT: + sql1="insert into \"medien\" values(nextval('medienId'),'"+change.type+"','"+change.title+"','"+change.author+"','"+change.album+"','"+change.category+"','"+change.year+"','"+change.duration+"',"+change.aBitrate+","+change.vBitrate+",'"+change.resolution+"',"+change.ownerId+",'"+new java.util.Date(System.currentTimeMillis()).toString()+"','"+change.path+"','"+change.name+"');"; + System.out.println(sql1); + Return=stat.executeUpdate(sql1); + break; + // if updateType is DELETE + case DELETE: + sql1="delete from \"medien\" where \"id\"= "+change.id+" ;"; + System.out.println(sql1); + Return=stat.executeUpdate(sql1); + break; + default : return -1; + } + // perform operation on table an return number of updated rows + }catch(SQLException e){ + System.out.println("Exception in PGSqlInput.changeMedia: "+e); + } + */ + } + +/* + * returns an ArrayList of Results which are matching to the commited Find object + * + * @param media + * Object which describes search criterias + * @return ArrayList<Result> + * List with Results matching search criteria + */ + public void search(String str, MediaType[] types, MediasHolder result, YalpErrorHolder err) { + /* t.b.d. alter this to new database design + try{ + ArrayList <String > searchWords=stringCut(media.str); + String query= new String(); + Boolean first; + for (int i=0;i<searchWords.size();i++){ + first=true; + if (i!=0)query = query+") intersect "; + query= query+"select * from \"medien\" where ("; + if (media.audio){ + first=false; + query=query+"\"type\" = 'audio' "; + } + if (media.video){ + if (first)first=false; + else query=query+"or "; + query=query+"\"type\" = 'video' "; + } + if (!first)query=query+") and ("; + query=query+"\"title\" Ilike '%"+searchWords.get(i)+"%' or \"author\" Ilike '%"+searchWords.get(i)+"%' or \"album\" Ilike '%"+searchWords.get(i)+"%'or \"year\" Ilike '%"+searchWords.get(i)+"%'or \"category\" Ilike '%"+searchWords.get(i)+"%'"; + } + query=query+")order by \"id\";"; + + ArrayList<Result> resultList=new ArrayList<Result>(); + Statement stat= con.createStatement(); + ResultSet result=stat.executeQuery(query); + while(result.next()){ + resultList.add( new Result(result.getInt(1),result.getString(2),result.getString(3),result.getString(4),result.getString(5),result.getString(6),result.getString(7),result.getString(8),result.getInt(9),result.getInt(10),result.getString(11),result.getInt(12),result.getString(13),result.getString(14),result.getString(15))); + } + return resultList; + }catch(SQLException e){ + System.out.println("Exception in PGSqlInput.search: "+e); + return new ArrayList<Result>(); + } + */ + } + +/* + * cuts Strings and returns an ArrayList of the cutted Strings + * + * @param str + * String to cut + * @return ArrayList<String> + * ArrayList with cutted Strings + */ + private ArrayList <String> stringCut (String str){ + int i=0,j=0; + ArrayList<String> list= new ArrayList<String>(); + while(j!=-1){ + j=str.indexOf(" ",i); + if (j!=-1){ + list.add(new String (str.substring(i,j))); + i=j+1; + } else list.add(new String (str.substring(i,str.length()))); + } + return list; + } + +/* + * returns number of medias in database + * + * @return String + * Number of medias in database + */ + public void getNumOfMedias(IntHolder num, YalpErrorHolder err) { + try{ + ResultSet result=this.stat.executeQuery("select count (\"id\") from \"medien\";"); + result.next(); + num = new IntHolder(new Integer(result.getString(1))); + }catch(SQLException e){ + System.out.println("exception in PGSql Input getNumOfMedias: "+e); + YalpError error = new YalpError(); + error.code = YalpErrorCode.ERROR_SQL; + error.level= YalpErrorLevel.ERROR_LEVEL_ERROR; + error.descr= e.toString(); + err = new YalpErrorHolder(error); + } + } + +/* + * returns plugin information + * @param PluginInfoHolder info holder for PluginInformation + * @param YalpErrorHolder err holder for error information + */ + public void getInfo(PluginInfoHolder info, YalpErrorHolder err) + { + info = new PluginInfoHolder(pluginInfo); + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java b/src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java new file mode 100644 index 0000000..b816542 --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/YalpPGSqlInput.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpInputs.YalpPGSqlInput; + +import YalpInterfaces.*; + +/* + * Class YalpPGSqlInput + * + * <em>Implements functionality of the DBConnectionInterface</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 1 02-04-2006<br> + */ +public class YalpPGSqlInput { + private YalpInputInterfaceImpl con; + private DatabaseDefines config; + + public static void main(String[] args) + { + System.out.println("YalpPGSqlInput\n"); + PGSqlInput input = new PGSqlInput(args); + } +} diff --git a/src/YalpInputs/YalpPGSqlInput/db-design-backup.sql b/src/YalpInputs/YalpPGSqlInput/db-design-backup.sql new file mode 100644 index 0000000..0ab8d4d --- /dev/null +++ b/src/YalpInputs/YalpPGSqlInput/db-design-backup.sql @@ -0,0 +1,321 @@ +-- +-- PostgreSQL database dump +-- + +-- Started on 2008-09-23 20:48:41 CEST + +SET client_encoding = 'UNICODE'; +SET check_function_bodies = false; +SET client_min_messages = warning; + +-- +-- TOC entry 1518 (class 0 OID 0) +-- Dependencies: 5 +-- Name: SCHEMA public; Type: COMMENT; Schema: -; Owner: postgres +-- + +COMMENT ON SCHEMA public IS 'Standard public schema'; + + +SET search_path = public, pg_catalog; + +SET default_tablespace = ''; + +SET default_with_oids = false; + +-- +-- TOC entry 1170 (class 1259 OID 17306) +-- Dependencies: 1491 5 +-- Name: IntProperties; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "IntProperties" ( + id bigserial NOT NULL, + description "char", + value integer +); + + +ALTER TABLE public."IntProperties" OWNER TO yalp; + +-- +-- TOC entry 1520 (class 0 OID 0) +-- Dependencies: 1169 +-- Name: IntProperties_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"IntProperties"', 'id'), 1, false); + + +-- +-- TOC entry 1172 (class 1259 OID 17313) +-- Dependencies: 1492 5 +-- Name: Medias; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "Medias" ( + id bigserial NOT NULL, + "type" character(1), + path "char", + "fileName" "char", + tags "char"[], + duration "char" +); + + +ALTER TABLE public."Medias" OWNER TO yalp; + +-- +-- TOC entry 1521 (class 0 OID 0) +-- Dependencies: 1171 +-- Name: Medias_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"Medias"', 'id'), 1, false); + + +-- +-- TOC entry 1174 (class 1259 OID 17323) +-- Dependencies: 1493 1494 1495 5 +-- Name: PropertyConnector; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "PropertyConnector" ( + "mediaId" integer, + "stringPropertyId" integer DEFAULT 0, + "intPropertyId" integer DEFAULT 0, + id bigserial NOT NULL +); + + +ALTER TABLE public."PropertyConnector" OWNER TO yalp; + +-- +-- TOC entry 1168 (class 1259 OID 17294) +-- Dependencies: 1490 5 +-- Name: StringProperties; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "StringProperties" ( + id bigserial NOT NULL, + description "char", + value "char" +); + + +ALTER TABLE public."StringProperties" OWNER TO yalp; + +-- +-- TOC entry 1522 (class 0 OID 0) +-- Dependencies: 1167 +-- Name: StringProperties_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"StringProperties"', 'id'), 1, false); + + +-- +-- TOC entry 1165 (class 1259 OID 17269) +-- Dependencies: 1488 1489 5 +-- Name: Users; Type: TABLE; Schema: public; Owner: yalp; Tablespace: +-- + +CREATE TABLE "Users" ( + name "char"[] NOT NULL, + "realName" name[], + "level" integer DEFAULT 1 NOT NULL, + id bigserial NOT NULL +); + + +ALTER TABLE public."Users" OWNER TO yalp; + +-- +-- TOC entry 1523 (class 0 OID 0) +-- Dependencies: 1166 +-- Name: Users_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"Users"', 'id'), 1, false); + + +-- +-- TOC entry 1524 (class 0 OID 0) +-- Dependencies: 1173 +-- Name: propertyConnector_id_seq; Type: SEQUENCE SET; Schema: public; Owner: yalp +-- + +SELECT pg_catalog.setval(pg_catalog.pg_get_serial_sequence('"PropertyConnector"', 'id'), 1, false); + + +-- +-- TOC entry 1513 (class 0 OID 17306) +-- Dependencies: 1170 +-- Data for Name: IntProperties; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "IntProperties" (id, description, value) FROM stdin; +\. + + +-- +-- TOC entry 1514 (class 0 OID 17313) +-- Dependencies: 1172 +-- Data for Name: Medias; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "Medias" (id, "type", path, "fileName", tags, duration) FROM stdin; +\. + + +-- +-- TOC entry 1515 (class 0 OID 17323) +-- Dependencies: 1174 +-- Data for Name: PropertyConnector; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "PropertyConnector" ("mediaId", "stringPropertyId", "intPropertyId", id) FROM stdin; +\. + + +-- +-- TOC entry 1512 (class 0 OID 17294) +-- Dependencies: 1168 +-- Data for Name: StringProperties; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "StringProperties" (id, description, value) FROM stdin; +\. + + +-- +-- TOC entry 1511 (class 0 OID 17269) +-- Dependencies: 1165 +-- Data for Name: Users; Type: TABLE DATA; Schema: public; Owner: yalp +-- + +COPY "Users" (name, "realName", "level", id) FROM stdin; +\. + + +-- +-- TOC entry 1507 (class 16386 OID 17329) +-- Dependencies: 1174 1174 +-- Name: key_id_con; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT key_id_con PRIMARY KEY (id); + + +ALTER INDEX public.key_id_con OWNER TO yalp; + +-- +-- TOC entry 1497 (class 16386 OID 17291) +-- Dependencies: 1165 1165 +-- Name: key_is_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "Users" + ADD CONSTRAINT key_is_id PRIMARY KEY (id); + + +ALTER INDEX public.key_is_id OWNER TO yalp; + +-- +-- TOC entry 1501 (class 16386 OID 17298) +-- Dependencies: 1168 1168 +-- Name: prim_key_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "StringProperties" + ADD CONSTRAINT prim_key_id PRIMARY KEY (id); + + +ALTER INDEX public.prim_key_id OWNER TO yalp; + +-- +-- TOC entry 1503 (class 16386 OID 17310) +-- Dependencies: 1170 1170 +-- Name: prim_key_int_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "IntProperties" + ADD CONSTRAINT prim_key_int_id PRIMARY KEY (id); + + +ALTER INDEX public.prim_key_int_id OWNER TO yalp; + +-- +-- TOC entry 1505 (class 16386 OID 17320) +-- Dependencies: 1172 1172 +-- Name: prim_key_m_id; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "Medias" + ADD CONSTRAINT prim_key_m_id PRIMARY KEY (id); + + +ALTER INDEX public.prim_key_m_id OWNER TO yalp; + +-- +-- TOC entry 1499 (class 16386 OID 17278) +-- Dependencies: 1165 1165 +-- Name: user_name_unique; Type: CONSTRAINT; Schema: public; Owner: yalp; Tablespace: +-- + +ALTER TABLE ONLY "Users" + ADD CONSTRAINT user_name_unique UNIQUE (name); + + +ALTER INDEX public.user_name_unique OWNER TO yalp; + +-- +-- TOC entry 1509 (class 16386 OID 17334) +-- Dependencies: 1174 1170 1502 +-- Name: int_prop; Type: FK CONSTRAINT; Schema: public; Owner: yalp +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT int_prop FOREIGN KEY ("intPropertyId") REFERENCES "IntProperties"(id); + + +-- +-- TOC entry 1508 (class 16386 OID 17330) +-- Dependencies: 1174 1172 1504 +-- Name: media_prop; Type: FK CONSTRAINT; Schema: public; Owner: yalp +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT media_prop FOREIGN KEY ("mediaId") REFERENCES "Medias"(id); + + +-- +-- TOC entry 1510 (class 16386 OID 17338) +-- Dependencies: 1174 1168 1500 +-- Name: string_prop; Type: FK CONSTRAINT; Schema: public; Owner: yalp +-- + +ALTER TABLE ONLY "PropertyConnector" + ADD CONSTRAINT string_prop FOREIGN KEY ("stringPropertyId") REFERENCES "StringProperties"(id); + + +-- +-- TOC entry 1519 (class 0 OID 0) +-- Dependencies: 5 +-- Name: public; Type: ACL; Schema: -; Owner: postgres +-- + +REVOKE ALL ON SCHEMA public FROM PUBLIC; +REVOKE ALL ON SCHEMA public FROM postgres; +GRANT ALL ON SCHEMA public TO postgres; +GRANT ALL ON SCHEMA public TO yalp; +GRANT ALL ON SCHEMA public TO PUBLIC; + + +-- Completed on 2008-09-23 20:48:41 CEST + +-- +-- PostgreSQL database dump complete +-- + diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java b/src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java new file mode 100644 index 0000000..c8441ac --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/TelnetInterface.java @@ -0,0 +1,147 @@ +/*********************************************************************** + * + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + ************************************************************************/ + +package YalpOutputs.YalpVlcTelnetOutput; + +import java.net.Socket; +import java.io.*; + +import org.apache.commons.net.telnet.*; + +/******************************************************************************* +* +* Class TelnetInterface +* +* <em>handels telnet connection</em> +* +* @author Volker Dahnke / Manuel Traut +* +* @version 0.1 20-11-2005<br> +* +* @see VlcStreamer +* +******************************************************************************/ +public class TelnetInterface { + + private PrintStream out; + private InputStream in; + private TelnetClient tc = new TelnetClient(); + + /** + * creates socket, logs on + * + * @param host + * hostname of telnetserver + * @param port + * destination port + * @param pass + * password + * + */ + + public TelnetInterface(String host, int port, String pass){ + try{ + this.tc.connect(host,port); + this.out = new PrintStream(this.tc.getOutputStream()); + this.in = this.tc.getInputStream(); + } catch(IOException e){ + System.out.println("server.TelnetInterface.java: Telnet connection "+host+":"+port+" failed"); + return; + } + + readUntil( "Password:" ); + write(pass); + // Advance to a prompt + readUntil("> "); + } + + /** + * write to TelnetInterface + * @param value + * String to write to Interface + */ + public void write( String value ) { + try { + out.println( value ); + out.flush(); + System.out.println( value ); + } + catch( Exception e ) { + e.printStackTrace(); + } + } + + /** + * reads output of telnet client + * @param pattern + * for stop reading + * @return String + */ + public String readUntil( String pattern ) { + try { + char lastChar = pattern.charAt( pattern.length() - 1 ); + StringBuffer sb = new StringBuffer(); + char ch = ( char )in.read(); + while( true ) { + System.out.print( ch ); + sb.append( ch ); + if( ch == lastChar ) { + if( sb.toString().endsWith( pattern ) ) { + return sb.toString(); + } + } + ch = ( char )in.read(); + } + } + catch( Exception e ) { + e.printStackTrace(); + } + return null; + } + + /** + * executes command + * @param cmd + * any telnet command + * @return String + * telnet output caused by the command + * null if failed + */ + public String exec(String cmd){ + + try { + write(cmd); + return readUntil( "> " ); + } + catch( Exception e ) { + e.printStackTrace(); + } + return null; + } + + /** + * close telnet connection + * + * @return boolean + * true: connection closed + * false: connection close failed + */ + + public boolean close(){ + try { + this.tc.disconnect(); + } catch(IOException e){ + return false; + } + return true; + } +} diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java b/src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java new file mode 100644 index 0000000..568bfb8 --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/VlcStreamer.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpOutputs.YalpVlcTelnetOutput; + +import YalpInterfaces.*; + +import java.io.*; +import java.util.LinkedList; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +/* + * + * Class VlcStreamer + * + * <em>Controlling Streams on a high level</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 04-12-2005<br> + * + * @see InitServer + */ +public class VlcStreamer { + + private static ORB orb; + private static POA poa; + private static YalpOutputPluginImpl streamer; + private static OutputPluginInterface outputPlugin; + private static ServerControlInterface srvCon; + private static PluginInfo pluginInfo; +/* + * starts a vlc player in a new process + * + * @param serverIP + * where vlcStreamer is running + * @param startport + * first port used for streaming + * @param vlcCmd + * path and name of vlc player executable + * @param args + * from cmd line + */ + public VlcStreamer(String serverIP, int startport, String vlcCmd, + String[] argv) { + + pluginInfo = new PluginInfo(); + pluginInfo.name = "VLC Telnet Streamer"; + pluginInfo.description = "creates streams via VLC players telnet interface"; + pluginInfo.type = PluginType.OUTPUT_PLUGIN; + pluginInfo.supportedTypes = new MediaType[0]; + pluginInfo.access = new AccessInfo(); + pluginInfo.access.name = "stream provided by vlc player"; + pluginInfo.access.description = "streams can be displayed with vlc player"; + pluginInfo.access.executable = "vlc"; + pluginInfo.access.params = ""; + pluginInfo.access.type = AccessType.STREAM; + + try { + this.orb = ORB.init(argv, null); + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + } catch(Exception e) { + /* t.b.d. error handling */ + System.out.println("couldn't host plugin implementation"); + } + + try { + poa.the_POAManager().activate(); + } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { + /* t.b.d. error handling */ + System.out.println("poa inactive"); + } +/* + YalpError error = new YalpError(); + error.msg = ""; + error.descr = ""; + error.code = YalpErrorCode.OK; + error.level= YalpErrorLevel.ERROR_LEVEL_INFO; + */ + YalpErrorHolder err = new YalpErrorHolder(/*error*/); + + try { + /* only start vlc player if it isn't currently running */ + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Server"; + srvCon = ServerControlInterfaceHelper.narrow(ncRef.resolve_str(name)); + } catch (Exception e) { + System.out.println("Couldn't connect to YALP Server"); + System.exit(0); + } + + streamer = new YalpOutputPluginImpl(); + streamer.setORB(orb); + + try { + poa.activate_object(streamer); + org.omg.CORBA.Object ref = poa.servant_to_reference(streamer); + outputPlugin = OutputPluginInterfaceHelper.narrow(ref); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Vlc_Telnet_Streamer_Output"; + NameComponent path[] = ncRef.to_name(name); + ncRef.rebind(path, outputPlugin); + + PluginInfoHolder tmp = new PluginInfoHolder(pluginInfo); + srvCon.ping(err); + System.out.println(err.value.descr); + srvCon.registerOutputPlugin(outputPlugin, tmp, err ); + pluginInfo = tmp.value; + + if(err.value.code != YalpErrorCode.OK) + System.out.println("registring outputplugin failed"); + else + System.out.println("output plugin registered"); + + orb.run(); + + } catch (Exception e) { + System.out.println("binding plugin failed 1"); + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java b/src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java new file mode 100644 index 0000000..50bdaa4 --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/YalpOutputPluginImpl.java @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2008 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut + */ + +package YalpOutputs.YalpVlcTelnetOutput; + +import YalpInterfaces.*; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; + +import java.util.*; +import java.io.IOException; + +/* + * Class YalpOutputPluginImpl + * + * <em>Implements VLC Telnet Streamer as YALP Plugin</em> + * + * @author Volker Dahnke / Manuel Traut + * @version 0.7 10-09-2008 + */ +public class YalpOutputPluginImpl extends OutputPluginInterfacePOA { + + private ORB orb; + private static Process vlcPlayer = null; + private StreamCounter streamCounter= new StreamCounter(); + private LinkedList<Output> currentStreams = new LinkedList<Output>(); + private int startPort; + private String hostIP; + private String vlcCommand; + private ServerControlInterface srvCon; + private PluginInfo pluginInfo; + +/* + * starts a vlc player in a new process + * + * @param serverIP + * where vlcStreamer is running + * @param startport + * first port used for streaming + * @param vlcCmd + * path and name of vlc player executable + * + * @throws RemoteException + * @throws ClassNotFoundException + */ + public void setORB(ORB _orb) { + orb = _orb; + + pluginInfo = new PluginInfo(); + pluginInfo.name = "VLC Telnet Streamer"; + pluginInfo.description = "creates streams via VLC players telnet interface"; + pluginInfo.type = PluginType.OUTPUT_PLUGIN; + pluginInfo.access = new AccessInfo(); + pluginInfo.access.name = "stream provided by vlc player"; + pluginInfo.access.description = "streams can be displayed with vlc player"; + pluginInfo.access.executable = "vlc"; + pluginInfo.access.params = ""; + pluginInfo.access.type = AccessType.STREAM; + + /* t.b.d. read vlccmod, startport, hostip from config xml */ + String vlcCmd = "/usr/bin/vlc"; + vlcCommand = vlcCmd + " --reset-config -I telnet"; + startPort = 9000; + hostIP = "127.0.0.1"; + + if(vlcPlayer == null){ + try{ + vlcPlayer = Runtime.getRuntime().exec(this.vlcCommand); + } catch(IOException e){ + System.out.println("server.VlcStreamer.java: Streamingserver failed"); + } + } + } + + public void shutdown() { + /* t.b.d. */ + } + +/* + * controls Streaming (start, stop, etc) + * + * @param howtoStream + * specifies streaming options + */ + public void control(OutputHolder howtoStream, YalpErrorHolder err) { + + switch( howtoStream.value.outputAction.value() ) { + + case Action._START: + start(howtoStream.value); + break; + + case Action._STOP: + stop(howtoStream.value); + break; + + case Action._PAUSE: + pause(howtoStream.value); + break; + + case Action._PLAY: + play(howtoStream.value); + break; + + case Action._FORWARD: + next(howtoStream.value); + break; + + //add sth. to current playing stream + case Action._CREATE: + add(howtoStream.value); + break; + + default: + System.out.println("server.VlcStreamer.control: action not supported"); + break; + } + } + +/* + * get plugin infos + * + * @param PluginInfoHolder (out) + * @param YalpErrorHolder (out) + */ + public void getInfo(PluginInfoHolder info, YalpErrorHolder err) + { + info = new PluginInfoHolder(); + err = new YalpErrorHolder(); + err.value.code = YalpErrorCode.OK; + info.value = pluginInfo; + } + +/* + * request Streaming of submitted Output + * + * @param stream + * which should be streamed + * @return Output + * extends Information "how to receive" of submitted Output + */ + public Output request(Output stream) { + //stream.setIP(hostIP); for UDP + stream.info.name = streamName(); + stream.info.params = new Integer(++startPort).toString(); + currentStreams.add(stream); + return stream; + } + + + /** + * starts streaming of submitted streamInfo + * @param howtoStream + */ + private void start(Output howtoStream){ + /* + String newString, setup2; + this.streamCounter.actualStreams++; + this.streamCounter.allStreams++; + + switch (howtoStream.info.type.value()){ + case AccessType._VOD: + newString = "new "+howtoStream.info.name+" vod enabled"; + break; + case AccessType._BROADCAST: + newString = "new "+howtoStream.info.name+" broadcast enabled"; + break; + default: + newString =""; + System.out.println("server.VlcStreamer.start: unsupported Type"); + break; + } + + String comp = "#transcode{vcodec=mp2v,vb=1024,scale=1,acodec=mpga,ab=192,channels=2}:duplicate{dst="; + + setup2 = "setup "+howtoStream.info.name+" output "+comp+"std{"; + + switch (howtoStream.access_type.value()){ + case Access._STREAM: + setup2 += "access=http,"; + break; + case Access._UDP: + setup2 += "access=udp,"; + break; + default: + System.out.println("server.VlcStreamer.start: unsupported Accesstype"); + break; + } + + switch (howtoStream.mux_type.value()){ + case Mux._TS: + setup2 += "mux=ts,url="+howtoStream.ip+":"+howtoStream.port+"}"; + break; + case Mux._ES: + setup2 += "mux=es,url="+howtoStream.ip+":"+howtoStream.port+"}"; + break; + case Mux._OGG: + setup2 += "mux=ogg,url="+howtoStream.ip+":"+howtoStream.port+"}"; + break; + default: + System.out.println("server.VlcStreamer.start: unsupported Muxer"); + break; + } + + // DEBUG COMP + setup2 += "}"; + + String control = "control "+howtoStream.info.name+" play"; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + // execute telnet commands + telnet.exec(newString); + + // Playlist + String input = ""; + for(int i=0; i < howtoStream.list.length; i++){ + input = "setup "+howtoStream.info.name+" "; + String fileItem = howtoStream.list[i]; + fileItem.replace(" ", "\\ "); + input += fileItem; + telnet.exec(input); + } + + telnet.exec(setup2); + telnet.exec(control); + + // close telnet connection + telnet.close(); + */ + } + + /** + * plays submitted streamInfo + * @param howtoStream + */ + private void play(Output howtoStream){ + + String control = "control "+howtoStream.info.name+" play"; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(control); + + // close telnet connection + telnet.close(); + } + + /** + * pause submitted streamInfo + * @param howtoStream + */ + private void pause(Output howtoStream){ + + String control = "control "+howtoStream.info.name+" pause"; + + // DEBUG + System.out.println("client.VlcStreamer: Telnetcmd: "); + System.out.println(control); + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(control); + + // close telnet connection + telnet.close(); + } + + /** + * go to next file in playlist + * + * @param howtoStream + */ + private void next(Output howtoStream){ + + String control = "control "+howtoStream.info.name+" seek 100"; + + // DEBUG + System.out.println("client.VlcStreamer: Telnetcmd: "); + System.out.println(control); + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(control); + + // close telnet connection + telnet.close(); + } + + /** + * stop streaming, delete stream + * + * @param howtoStream + */ + private void stop(Output howtoStream){ + + String del = "del "+howtoStream.info.name; + this.streamCounter.actualStreams--; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + telnet.exec(del); + + // close telnet connection + telnet.close(); + + currentStreams.remove(howtoStream); + } + + /** + * register Stream at vlcPlayer + * @param howtoStream + */ + private void add(Output howtoStream){ + + String input = ""; + + // telnet connection + TelnetInterface telnet = new TelnetInterface(hostIP, 4212, "admin"); + + for(int i=0; i < howtoStream.playlist.length; i++){ + input += "setup "+howtoStream.info.name+" "; + input += howtoStream.playlist[i]; + telnet.exec(input); + input = ""; + } + telnet.close(); + } + + /** + * calculates streamName + * @return String streamName + */ + + private String streamName(){ + String streamName = "stream"; + streamName += streamCounter.allStreams; + return streamName; + } + + /** + * stops the streaming server + * + */ + + public void quit(){ + vlcPlayer.destroy(); + } + + /** + * returns the streamcounter + * @return StreamCounter + */ + public StreamCounter getStreamCounter(){ + return this.streamCounter; + } +} diff --git a/src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java b/src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java new file mode 100644 index 0000000..766936d --- /dev/null +++ b/src/YalpOutputs/YalpVlcTelnetOutput/YalpVlcTelnetOutput.java @@ -0,0 +1,20 @@ +package YalpOutputs.YalpVlcTelnetOutput; + +import YalpInterfaces.*; + +public class YalpVlcTelnetOutput { + + public static void main(String[] args) { + + try { + System.setProperty("java.security.policy","output.policy"); + } + catch (Exception e) {//DEBUG + System.out.println ("Output SecurityManager File not found" + e); + System.exit(0); + } + + VlcStreamer vlc = new VlcStreamer("localhost", 2501, "/usr/bin/vlc", args); + System.out.println("VlcTelnetOutput"); + } +} diff --git a/src/YalpServer/FileBrowser.java b/src/YalpServer/FileBrowser.java new file mode 100755 index 0000000..2f2a3a5 --- /dev/null +++ b/src/YalpServer/FileBrowser.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpServer; + +import java.util.ArrayList; +import java.io.File; +import java.io.Serializable; + +import YalpInterfaces.*; + +/* + * Class FileBrowser + * + * <em>each Admin Client has his own FileBrowser, to browse through the + * subDirectories of the as startDir defined Directory</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 14-12-2005<br> + * + * @see client.GUI.Browser + */ + +public class FileBrowser { + + private File actualFile, startDir; + private String owner; + private String userName; + private ArrayList<YalpFile> fileList; + + /* t.b.d. add some more types */ + private String[] extensions = {".mp3",".mpg",".mpeg",".avi"}; + +/* + * Constructor starts Browsing in startDir + * + * @param startdir + * directory which could be browser recursively + * @param owner + * of the Browser (IP of the Client) + * @param userName + * of the Admin using this browser + */ + + public FileBrowser(String startdir, String owner,String userName) { + this.owner = owner; + this.userName=userName; + this.actualFile = new File(startdir); + this.startDir = new File(startdir); + this.fileList = new ArrayList<YalpFile>(); + } + +/* + * returns owner of the browser + * + * @return String + * owner + */ + + public String getOwner(){ + return this.owner; + } + +/* + * returns user of the browser + * + * @return String + * user + */ + + public String getUserName(){ + return this.userName; + } + +/* + * returns list of all files in actual Folder + * (none recursive) + * + * @return ArrayList<YalpFile> + * list of all files + */ + + public ArrayList<YalpFile> getFiles(){ + return this.fileList; + } + +/* + * returns list of all files in actual Folder + * (recursive) + * + * @return ArrayList<YalpFile> + * list of all files + */ + + public ArrayList<File> findAll() { + + System.out.println( "server.FileBrowser.findAll: lookin in - " + + this.actualFile.toString() ); + + FileFinder ff = new FileFinder(actualFile.getPath(), extensions); + return ff.getFiles(); + } + +/* + * change actual Folder + * + * @param dirName + * String dir to change to + */ + + public void changeDir(String dirName) { + + this.actualFile = new File(this.startDir+dirName); + this.fileList.clear(); + + if(actualFile.isDirectory()) { + for ( File aFile : this.actualFile.listFiles() ) { + /* add to fileList if extension is allowed or File is a Directory */ + if (match(aFile.getName(), extensions) || aFile.isDirectory()) + { + YalpFile tmp = new YalpFile(); + tmp.name = aFile.getName(); + tmp.isDir = aFile.isDirectory(); + tmp.parent = aFile.getParent(); + this.fileList.add( tmp ); + } + } + } + } + +/* + * prints current directory out to console + * + * (for debugging) + */ + + public void printActualDir(){ + for(YalpFile one : this.fileList){ + if(one.isDir) System.out.print("+"); + else System.out.print("|"); + System.out.println(one.name); + } + } + +/* + * checks if file extension matches or not + * + * @param s + * fileName including Extension + * @param suffixes + * Array of allowed Extensions + * @return boolean + * true if yalp can handle this extension, else false + */ + + private static boolean match( String s, String suffixes[] ) { + for ( String suffix : suffixes ) { + int huhu = s.length(); + int huhu2 = suffix.length(); + int huhu3 = huhu - huhu2; + if ( s.length() >= suffix.length() && + s.substring( huhu3, s.length()).equalsIgnoreCase(suffix) ) + return true; + } + return false; + } +} diff --git a/src/YalpServer/FileFinder.java b/src/YalpServer/FileFinder.java new file mode 100755 index 0000000..2d6527c --- /dev/null +++ b/src/YalpServer/FileFinder.java @@ -0,0 +1,110 @@ +/*********************************************************************** + * + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + ***********************************************************************/ +package YalpServer; + +import java.io.*; +import java.util.*; + +/************************************************************************ + * + * Class FileFinder + * + * <em>algorithm for scanning files recursively</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.6 14-12-2005<br> + * + * @see FileBrowser + * + ************************************************************************/ + +public class FileFinder +{ + private ArrayList<File> files; + + /** + * Constructor: scans subdirectories of commited directory + * uses only files with allowed extensions + * @param start + * directory to scan + * @param extensions + * allowed extensions + */ + public FileFinder( String start, String extensions[] ) { + + this.files = new ArrayList<File>(); + Stack<File> dirs = new Stack<File>(); + File startdir = new File(start); + + // push startdir to stack + if (startdir.isDirectory()) dirs.push(startdir); + // startdir is File + else { + if (match(startdir.getName(), extensions)) this.files.add(startdir); + return; + } + // for each dir on stack + while (dirs.size() > 0) { + // contents of dir on stack + for (File file : dirs.pop().listFiles()){ + try { + // add subdirectory to stack + if (file.isDirectory()) dirs.push(file); + // if file is of correct filetype add it to filelist + else if (match(file.getName(), extensions)) this.files.add(file); + } catch (NullPointerException e) { + System.out.println("FileFinder: "+ file.getName() +"Premission denied"); + } + } + } + } + + /** + * returns and prints out all Medias found + * @return ArrayList<File> + * all found Medias + */ + public ArrayList<File> getFiles(){ + print(); + return this.files; + } + + /** + * prints out found medias + * + */ + public void print() { + System.out.println( "Found " + files.size() + " file" + (files.size() == 1 ? "." : "s.") ); + for ( File f : files ) System.out.println( f.getAbsolutePath() ); + } + + /** + * checks if file extension matches or not + * + * @param s + * file to check + * @param suffixes + * allowed extensions + * + * @return boolean: true if it's a media, yalp can handle + */ + private static boolean match( String s, String suffixes[] ) { + for ( String suffix : suffixes ) { + int huhu = s.length(); + int huhu2 = suffix.length(); + int huhu3 = huhu - huhu2; + if ( s.length() >= suffix.length() && s.substring(huhu3, s.length()).equalsIgnoreCase(suffix) ) return true; + } + return false; + } +} diff --git a/src/YalpServer/FileInfoManager.java b/src/YalpServer/FileInfoManager.java new file mode 100755 index 0000000..34fe49b --- /dev/null +++ b/src/YalpServer/FileInfoManager.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + */ + +package YalpServer; + +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import de.hampelratte.id3.*; + +import YalpInterfaces.*; + +/* + * Class FileInfoManager + * + * <em>Creates a Result out of FileInformations (ID3, etc)</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.1 14-12-2005<br> + * + * @see ServerControl + */ + +public class FileInfoManager { + + private Media fileInfo; + private EncodingType eType; + +/* + * Constructor: tries to get all Informations about a file + * + * @param file + */ + + public FileInfoManager(File file) { + + this.eType = EncodingType.UNKNOWN; + this.fileInfo = new Media(); + this.fileInfo.path = file.getParent()+file.separator; + this.fileInfo.fileName = file.getName(); + + /* check extensions is mp3 */ + if( this.fileInfo.fileName.substring( this.fileInfo.fileName.length() - 3, + this.fileInfo.fileName.length()).equalsIgnoreCase( "mp3" ) ) + { + this.eType = EncodingType.MP3; + } + + switch(this.eType.value()) { + case EncodingType._MP3: + try + { + /* opening mp3 file for reading and writing */ + MP3File mp3 = new de.hampelratte.id3.MP3File(file.toString(), "r"); + this.fileInfo.type = MediaType.SOUND; + + if(mp3.hasID3v1Tag){ + ID3v1Tag tag = mp3.readID3v1Tag(); + /* t.b.d. create StringProperties + this.fileInfo.album = tag.getAlbum(); + this.fileInfo.author = tag.getArtist(); + this.fileInfo.category = tag.getGenre(); + this.fileInfo.name = tag.getTrack() +" - "+tag.getTitle(); + this.fileInfo.year = tag.getYear(); + */ + } + + if(mp3.hasID3v2Tag){ + + // reading the ID3v2Tag + ID3v2Tag tag = mp3.readID3v2Tag(); + /* t.b.d. create StringProperties + this.fileInfo.album = tag.getAlbum(); + this.fileInfo.author = tag.getArtist(); + this.fileInfo.category = tag.getGenre(); + this.fileInfo.year = tag.getYear(); + */ + if( !(tag.getTrack().equals(""))){ + this.fileInfo.name = tag.getTrack() +" - "+tag.getTitle(); + } else { + this.fileInfo.name = tag.getTitle(); + } + } + + if (this.fileInfo.name.equals("")) { + + this.fileInfo.name = + file.getName().substring( 0, file.getName().length() - 4 ); + } + + mp3.close(); + } catch (Exception e) { + + this.fileInfo.name = + file.getName().substring(0,file.getName().length() - 4); + } + break; + + default: + this.fileInfo.name = + file.getName().substring(0,file.getName().length()-4); + + this.fileInfo.type = MediaType.VIDEO; + break; + } + } + +/* + * returns the information to an media, found + * @return MediaChange + * Informations about the media + */ + + public Media getInfo(){ + return this.fileInfo; + } +} diff --git a/src/YalpServer/InitServer.java b/src/YalpServer/InitServer.java new file mode 100755 index 0000000..ac9d507 --- /dev/null +++ b/src/YalpServer/InitServer.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2006 Manuel Traut and Volker Dahnke + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: Manuel Traut and Volker Dahnke + * + */ + +package YalpServer; + +import java.net.Inet4Address; +import java.net.MalformedURLException; +import java.net.UnknownHostException; + +import java.beans.XMLDecoder; +import java.beans.XMLEncoder; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.File; + +import java.util.ArrayList; +import java.util.Properties; + +import java.security.*; + +import java.sql.SQLException; + +import org.omg.CosNaming.*; +import org.omg.CosNaming.NamingContextPackage.*; +import org.omg.CORBA.*; +import org.omg.PortableServer.*; +import org.omg.PortableServer.POA; + +import YalpInterfaces.*; + +/* + * Class InitServer + * + * <em>Establishes DBConnection and creates VlcStreamer waits for + * further Instructions via Interfaces</em> + * + * @author Volker Dahnke / Manuel Traut + * + * @version 0.1 20-11-2005<br> + * + * @see Server + * + */ + +public class InitServer { + + private ServerSettings settings = new ServerSettings(); + private ServerControlImpl srvCon; + private ServerControlInterface srv; + private ORB orb; + private String[] orbArgs; + private POA poa; + private String serverIP; + private ArrayList<FileBrowser> browseList; + + /* + * Constructor: starts Server initialization + */ + public InitServer(String[] _orbArgs) { + + loadConfig("ServerSettings.xml"); + writeConfig("ServerSettings.xml"); + + this.browseList = new ArrayList<FileBrowser>(); + + this.orbArgs = _orbArgs; // t.b.d. read orbargs from config xml + + try { + this.serverIP = Inet4Address.getLocalHost().getHostAddress(); + } catch(UnknownHostException e) { + /* t.b.d. error handling */ + System.out.println("couldn't resolve hostname"); + } + + /* bind ServerControl to ORB and NamingService */ + this.orb = ORB.init(orbArgs, null); + + try { + this.poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); + } catch(org.omg.CORBA.ORBPackage.InvalidName e) { + /* t.b.d. error handling */ + System.out.println("couldn't get name ref of root poa"); + } + + try { + poa.the_POAManager().activate(); + } catch(org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { + /* t.b.d. error handling */ + System.out.println("poa inactive"); + } + + this.srvCon = new ServerControlImpl(); + this.srvCon.setORB(this.orb); + + try { + org.omg.CORBA.Object ref = poa.servant_to_reference(this.srvCon); + this.srv = ServerControlInterfaceHelper.narrow(ref); + + org.omg.CORBA.Object objRef = + orb.resolve_initial_references("NameService"); + + NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); + String name = "YALP_Server"; + NameComponent path[] = ncRef.to_name(name); + ncRef.rebind(path, this.srv); + + System.out.println("YALP Server ready"); + this.orb.run(); + + } catch( org.omg.CosNaming.NamingContextPackage.InvalidName e) { + /* t.b.d. error handling */ + System.out.println("couldn't narrow ref to path"); + } catch( org.omg.CosNaming.NamingContextPackage.NotFound e) { + /* t.b.d. error handling */ + System.out.println("naming context not found, couldn't bind server ctl"); + } catch(org.omg.PortableServer.POAPackage.ServantNotActive e) { + /* t.b.d. error handling */ + System.out.println("couldn't get name ref of root poa"); + } catch (org.omg.CORBA.ORBPackage.InvalidName e) { + /* t.b.d. error handling */ + System.out.println("couldn't get NameService"); + } catch (org.omg.PortableServer.POAPackage.WrongPolicy e) { + /* t.b.d. error handling */ + System.out.println("policies not set correctly"); + } catch (org.omg.CosNaming.NamingContextPackage.CannotProceed e) { + /* t.b.d. error handling */ + System.out.println("rebind failed, cannot proceed"); + } + } + +/* + * write Configuration to XML File + * + * @param fileName + * where to write the configuration file + * @return boolean + * false - if failed + */ + + public boolean writeConfig(String fileName) { + try{ + FileOutputStream configFile = new FileOutputStream(fileName); + XMLEncoder configWriter = new XMLEncoder(configFile); + configWriter.writeObject(settings.imageDir); + configWriter.writeObject(settings.videoDir); + configWriter.writeObject(settings.soundDir); + configWriter.close(); + } catch (FileNotFoundException fnfe){ + return false; + } + return true; + } + +/* + * tries to load ServerSettings from XML File + * @param fileName + * Configuration file + * @return boolean + * false - if loading failed + */ + + public boolean loadConfig(String fileName) { + try{ + FileInputStream configFile = new FileInputStream(fileName); + XMLDecoder configLoader = new XMLDecoder(configFile); + settings.imageDir = (String)configLoader.readObject(); + settings.videoDir = (String)configLoader.readObject(); + settings.soundDir = (String)configLoader.readObject(); + configLoader.close(); + } catch(FileNotFoundException fnfe) { + System.out.println("Configuration not found, loading defaults..."); + return false; + } catch(ClassCastException cce) { + System.out.println("Errors in Configuration, loading defaults..."); + return false; + } + return true; + } + +/* + * returns actual configuration of the server + * @return ServerSettings + * actual configuration + */ + + public ServerSettings getConfig() { + return this.settings; + } + +/* + * sets and saves a new ServerConfiguration + * + * @param set + * new ServerSettings + * @return boolean + * true if succesfully saved + */ + + public boolean setConfig(ServerSettings set){ + this.settings = set; + return this.writeConfig("ServerConfiguration.xml"); + } + +/* + * t.b.d. session management + * + * Client logon (give him,his fileBrowser) + * + * @param ipAdress + * of the Client + * @param userName + * using the Client + * + + public void newClient(String ipAdress,String userName) { + this.browseList.add( new FileBrowser( this.settings.startDir, + ipAdress, + userName ) ); + } + */ + +/* + * Client logoff (free memory of his fileBrowser + * + * @param ipAdress + * of the Client + * @param userName + * using the Client + */ + + public void remClient(String ipAdress, String userName) { + for( FileBrowser aBrowser : this.browseList ) { + if( aBrowser.getOwner().equals(ipAdress) && + aBrowser.getUserName().equals(userName) ) { + this.browseList.remove(aBrowser); + break; + } + } + } + +/* + * change Directory in fileBrowser + * + * @param ip + * of the Client + * @param dir + * to which should be changed + * @return ArrayList<YalpFile> + * content of the directory changed to + */ + + public ArrayList<YalpFile> changeDir(String ip, String dir) { + FileBrowser aBrowser = null; + for(FileBrowser oneMoreBrowser : this.browseList) { + if( oneMoreBrowser.getOwner().equals(ip) ) { + oneMoreBrowser.changeDir(dir); + aBrowser = oneMoreBrowser; + break; + } + } + return aBrowser.getFiles(); + } + +/* + * Server Shutdown + */ + + public void serverShutdown() { + System.out.println("Server shutdown - Server is going down"); + System.exit(0); + } +} diff --git a/src/YalpServer/ServerControlImpl.java b/src/YalpServer/ServerControlImpl.java new file mode 100755 index 0000000..a88445a --- /dev/null +++ b/src/YalpServer/ServerControlImpl.java @@ -0,0 +1,385 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpServer;
+
+import YalpInterfaces.*;
+
+import java.net.*;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Properties;
+
+import org.omg.CosNaming.*;
+import org.omg.CosNaming.NamingContextPackage.*;
+import org.omg.CORBA.*;
+import org.omg.PortableServer.*;
+import org.omg.PortableServer.POA;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+/*
+ * Class ServerControlImpl
+ *
+ * <em>Implements functionality of the ServerControl Interface</em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ * @version 0.6 14-12-2005<br>
+ * @see client
+ */
+public class ServerControlImpl extends ServerControlInterfacePOA {
+
+ private ORB orb;
+ private InitServer srv;
+ private String log4jFile = "log4j_server.conf";
+ private static Logger logger = Logger.getLogger("Yalp.Server");
+
+public ServerControlImpl() {
+ PropertyConfigurator.configureAndWatch(log4jFile);
+ logger.debug("ServerControlImpl()");
+}
+
+ public void setORB(ORB _orb) {
+ logger.debug("setOrb()");
+ orb = _orb;
+ }
+
+ public void init(InitServer srv) {
+ logger.debug("init()");
+ this.srv=srv;
+ }
+
+/*
+ * client logon
+ *
+ * @param userName
+ * @param password
+ * @param ipAdress
+ * @param session (out)
+ * @param error (out)
+ */
+ public void clientLogon( String userName,
+ String password,
+ String ipAdress,
+ SessionHolder session,
+ YalpErrorHolder err )
+ {
+ logger.debug("clientLogon()");
+ /* t.b.d. session managmnet */
+ try {
+ System.out.println("logon: "+userName+" - "+ipAdress);
+
+ session.value = new Session();
+ session.value.id = 666;
+ session.value.me = new YalpUser();
+ session.value.me.level = AccessRights.ADMIN;
+
+ err.value = new YalpError();
+ err.value.code = YalpErrorCode.OK;
+
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ System.out.println("t.b.d. clientLogon nothing implemented at the moment");
+ }
+
+/*
+ * client logoff
+ *
+ * @param session
+ * @param error (out)
+ */
+ public void clientLogoff( Session bye, YalpErrorHolder err) {
+ logger.debug("clientLogoff");
+ srv.remClient( bye.ip, bye.me.name );
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * get user list
+ *
+ * @param user list (out)
+ * @param error (out)
+ */
+ public void getUser(UsersHolder list, YalpErrorHolder err) {
+ logger.debug("getUser()");
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * change user details
+ *
+ * @param user
+ * @param password
+ * @param action (create, delete, alter)
+ * @param error (out)
+ */
+ public void changeUser(YalpUser usr, String passwd, Action todo,
+ YalpErrorHolder err) {
+ logger.debug("changeUser()");
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * alter media informations
+ *
+ * @param media to change
+ * @param action (update, delete, create)
+ * @param error (out)
+ */
+ public void changeMedia( Media toChange, Action todo, YalpErrorHolder err ) {
+ logger.debug("changeMedia()");
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * count yalp medias
+ *
+ * @param num (out)
+ * @param error (out)
+ */
+ public void getNumOfMedias( IntHolder num, YalpErrorHolder err ) {
+ logger.debug("getNumOfMedias()");
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * control yalp medias
+ *
+ * @param control description (inout)
+ * @param error (out)
+ */
+ public void control( OutputHolder ctlOutput, YalpErrorHolder err ) {
+ logger.debug("control()");
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * search yalp media
+ *
+ * @param search string
+ * @param list of mediatypes
+ * @param result as list of medias (out)
+ */
+ public void search( String str, MediaType[] types, MediasHolder result,
+ YalpErrorHolder err ) {
+ logger.debug("search()");
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * register new output plugin
+ *
+ * @param plugin which should be registered
+ * @param error
+ */
+ public void registerOutputPlugin( OutputPluginInterface itf,
+ PluginInfoHolder info, YalpErrorHolder err )
+ {
+ logger.debug("registerOutputPlugin()");
+ /* t.b.d. itf handling */
+ System.out.println("registering output plugin: " + info.value.name );
+ YalpError error = new YalpError();
+ error.msg = "huhu";
+ error.descr = "hihi";
+ error.code = YalpErrorCode.OK;
+ error.level = YalpErrorLevel.ERROR_LEVEL_INFO;
+ err.value = error;
+ PluginInfo inf = new PluginInfo();
+ inf.id = 666;
+ inf.name = info.value.name;
+ inf.description = info.value.description;
+ inf.type = info.value.type;
+ inf.supportedTypes= info.value.supportedTypes;
+ inf.access = info.value.access;
+ inf.maxClients = info.value.maxClients;
+ inf.actClients = info.value.actClients;
+ info.value = inf;
+ }
+
+/*
+ * remove output plugin
+ *
+ * @param plugin which should be registered
+ * @param error
+ */
+ public void removeOutputPlugin( PluginInfo itf, YalpErrorHolder err )
+ {
+ logger.debug("removeOutputPlugin()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * get all registered output plugins
+ *
+ * @param plugin list
+ * @param error
+ */
+ public void getOutputPlugins( PluginInfosHolder itfs, String name,
+ YalpErrorHolder err )
+ {
+ logger.debug("getOutputPlugins()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * register new input plugin
+ *
+ * @param plugin which should be registered
+ * @param error
+ */
+ public void registerInputPlugin( org.omg.CORBA.Object itf,
+ PluginInfoHolder info, YalpErrorHolder err )
+ {
+ logger.debug("registerInputPlugins()");
+ /* t.b.d. itf handling */
+ System.out.println("registering input plugin: " + info.value.name );
+ YalpError error = new YalpError();
+ error.msg = "huhu";
+ error.descr = "hihi";
+ error.code = YalpErrorCode.OK;
+ error.level = YalpErrorLevel.ERROR_LEVEL_INFO;
+ err.value = error;
+ PluginInfo inf = new PluginInfo();
+ inf.id = 666;
+ inf.name = info.value.name;
+ inf.description = info.value.description;
+ inf.type = info.value.type;
+ inf.supportedTypes= info.value.supportedTypes;
+ inf.access = info.value.access;
+ inf.maxClients = info.value.maxClients;
+ inf.actClients = info.value.actClients;
+ info.value = inf; }
+
+/*
+ * remove input plugin
+ *
+ * @param plugin which should be registered
+ * @param error
+ */
+ public void removeInputPlugin( PluginInfo itf, YalpErrorHolder err )
+ {
+ logger.debug("removeInputPlugin()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * get all registered input plugins
+ *
+ * @param plugin list
+ * @param error
+ */
+ public void getInputPlugins( PluginInfosHolder itfs,
+ String name, YalpErrorHolder err )
+ {
+ logger.debug("getInputPlugins()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * register new auth plugin
+ *
+ * @param plugin which should be registered
+ * @param error
+ */
+ public void registerAuthPlugin( org.omg.CORBA.Object itf,
+ PluginInfoHolder info, YalpErrorHolder err )
+ {
+ logger.debug("registerAuthPlugin()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * remove input plugin
+ *
+ * @param plugin which should be registered
+ * @param error
+ */
+ public void removeAuthPlugin( PluginInfo itf,
+ YalpErrorHolder err )
+ {
+ logger.debug("removeAuthPlugin()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * get all registered auth plugins
+ *
+ * @param plugin list
+ * @param error
+ */
+ public void getAuthPlugins( PluginInfosHolder itfs,
+ String name, YalpErrorHolder err )
+ {
+ logger.debug("getAuthPlugins()");
+ /* t.b.d. itf handling */
+ YalpError error = new YalpError();
+ error.code = YalpErrorCode.OK;
+ err = new YalpErrorHolder(error);
+ }
+
+/*
+ * to check if server is still ok
+ *
+ * @return Boolean true - if ok
+ */
+ public void ping(YalpErrorHolder pong) {
+ logger.debug("ping()");
+ YalpError err = new YalpError();
+ err.descr = "PONG";
+ err.msg = "huhu";
+ err.level = YalpErrorLevel.ERROR_LEVEL_INFO;
+ err.code = YalpErrorCode.OK;
+ pong.value = err;
+ System.out.println("pong");
+ }
+
+/*
+ * server shutdown
+ */
+ public void serverShutdown()
+ {
+ logger.debug("server shutdown()");
+ /* t.b.d. clear server shutdown */
+ }
+}
diff --git a/src/YalpServer/ServerSettings.java b/src/YalpServer/ServerSettings.java new file mode 100755 index 0000000..313e875 --- /dev/null +++ b/src/YalpServer/ServerSettings.java @@ -0,0 +1,68 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+
+package YalpServer;
+
+/*
+ * Class ServerSettings
+ *
+ * <em></em>
+ *
+ * @author Manuel Traut
+ *
+ * @version 0.1 27-03-2006<br>
+ *
+ * @see server.InitServer
+ */
+
+public class ServerSettings{
+
+ static final long serialVersionUID = 0;
+
+ public String imageDir = "/media/image";
+ public String videoDir = "/media/video";
+ public String soundDir = "/media/sound";
+
+ /**
+ * set Directories which contains media Files
+ * @param startDir
+ */
+ public void setImageDir(String startDir){
+ this.imageDir = startDir;
+ }
+
+ /**
+ * set Directories which contains media Files
+ * @param startDir
+ */
+ public void setVideoDir(String startDir){
+ this.videoDir = startDir;
+ }
+
+ /**
+ * set Directories which contains media Files
+ * @param startDir
+ */
+ public void setSoundDir(String startDir){
+ this.soundDir = startDir;
+ }
+
+ public String getVideoDir(){
+ return this.videoDir;
+ }
+
+ public String getImageDir(){
+ return this.imageDir;
+ }
+
+ public String getSoundDir(){
+ return this.soundDir;
+ }
+}
diff --git a/src/YalpServer/YalpServer.java b/src/YalpServer/YalpServer.java new file mode 100755 index 0000000..0ddbe00 --- /dev/null +++ b/src/YalpServer/YalpServer.java @@ -0,0 +1,40 @@ +/*
+ * Copyright (c) 2006 Manuel Traut and Volker Dahnke
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors: Manuel Traut and Volker Dahnke
+ */
+package YalpServer;
+
+/*
+ * Class Server
+ *
+ * <em>static main method</em>
+ *
+ * @author Volker Dahnke / Manuel Traut
+ *
+ * @version 0.1 20-11-2005<br>
+ */
+public class YalpServer{
+
+/*
+ * starts Server initialization
+ *
+ * @param argv
+ * arguments which are not used
+ */
+ public static void main (String[] argv) {
+ try{
+ System.setProperty("java.security.policy","server.policy");
+ } catch (Exception e) {//DEBUG
+ System.out.println ("Server SecurityManagerExeptions not caught jet " + e);
+ System.exit(0);
+ }
+ InitServer yalpServer = new InitServer(argv);
+ return;
+ }
+
+}
diff --git a/src/yalp.idl b/src/yalp.idl new file mode 100644 index 0000000..6fb5203 --- /dev/null +++ b/src/yalp.idl @@ -0,0 +1,265 @@ +module YalpInterfaces +{ + +enum YalpErrorCode { + OK, + ERROR_SQL, + ERROR_UNDEFINED +}; + +enum YalpErrorLevel { + ERROR_LEVEL_DEBUG, + ERROR_LEVEL_INFO, + ERROR_LEVEL_ERROR, + ERROR_LEVEL_CRITICAL +}; + +struct YalpError { + string msg; + YalpErrorCode code; + YalpErrorLevel level; + string descr; +}; + +struct YalpFile { + boolean isDir; + string name; + string parent; +}; +typedef sequence<YalpFile> YalpFiles; + +struct StreamCounter { + unsigned long actualStreams; + unsigned long allStreams; +}; + +enum AccessRights { + ADMIN, + USER, + NO_YALP_SERVER, + DENY +}; + +struct YalpUser { + unsigned long id; + string name; + string realName; + AccessRights level; +}; +typedef sequence<YalpUser> Users; + +enum MediaType { + IMAGE, + VIDEO, + SOUND, + OTHER +}; +typedef sequence<MediaType> MediaTypes; + +struct StringProperty { + string property; + string value; +}; +typedef sequence<StringProperty> StringProperties; + +struct IntProperty { + string property; + long value; +}; +typedef sequence<IntProperty> IntProperties; + +typedef sequence<string> MediaTags; + +struct Media { + /* mandatory */ + string name; + unsigned long id; + MediaType type; + unsigned long inputPluginId; + /* optional */ + YalpUser owner; + string lastEdit; + string path; + string fileName; + string duration; + StringProperties stringProps; + IntProperties intProps; + MediaTags tags; +}; +typedef sequence<Media> Medias; + +enum Action { + START, + PLAY, + PAUSE, + STOP, + FORWARD, + BACKWARD, + CREATE, + EDIT, + DELETE +}; +typedef sequence<Action> Actions; + +enum AccessType { + FILE, + FILES, + STREAM +}; + +enum EncodingType { + UNKNOWN, + MP3, + MPG, + MPEG, + AVI, + MOV, + M2T, + JPEG, + JPG, + TIFF +}; + +struct AccessInfo { + string name; + string description; + string executable; + string params; + AccessType type; +}; + +struct Output { + unsigned long id; + AccessInfo info; + Medias playlist; + Action outputAction; + string destIp; +}; + +enum PluginType { + INPUT_PLUGIN, + OUTPUT_PLUGIN, + AUTH_PLUGIN +}; + +struct PluginInfo { + /* mandatory */ + unsigned long id; + string name; + string description; + PluginType type; + /* optional */ + MediaTypes supportedTypes; + AccessInfo access; + unsigned short maxClients; + unsigned short actClients; +}; +typedef sequence<PluginInfo> PluginInfos; + +struct Session { + unsigned long id; + YalpUser me; + string ip; + PluginInfos availablePlugins; +}; + +/* YALP startup + * + * 1) CORBA - NameService + * 2) YALP - ServerControl (connects to Db via NameService) + * 4) YALP - all Plugins (connecting to ServerControl via NS) + * 5) YALP - Clients (connecting to ServerControl via NS, getting handles) + * (to available OutputPlugins via ServerControl ) + */ + +/* implemented by OutputPlugins */ +interface OutputPluginInterface { + void getInfo(out PluginInfo info, out YalpError err); + void control(inout Output ctlOutput, out YalpError err); + oneway void shutdown(); +}; + +/* implemented by InputPlugins */ +interface InputPluginInterface { + void getInfo(out PluginInfo info, out YalpError err); + void changeMedia(in Media toChange, in Action todo, out YalpError err); + + void search(in string str, in MediaTypes types, out Medias result, + out YalpError err); + + void getNumOfMedias(out unsigned long num, out YalpError err); +}; + +/* implemented by UserIdentificationPlugin */ +interface UserIdentificationInterface { + void getInfo(out PluginInfo info, out YalpError err); + void userVerify(in string user, in string passwd, out YalpError err, + out YalpUser acc); + + void getUser(out Users list, out YalpError err); + + void changeUser(in YalpUser usr, in string passwd, in Action todo, + out YalpError err); +}; + +/* implemented by YALP */ +interface ServerControlInterface { + +/* User Handling */ + + void clientLogon(in string userName, in string pass, in string ipAdress, + out Session hej, out YalpError err); + + void clientLogoff(in Session bye, out YalpError err); + + void getUser(out Users list, out YalpError err); + + void changeUser(in YalpUser usr, in string passwd, in Action todo, + out YalpError err); + +/* Media Handling */ + + void changeMedia(in Media toChange, in Action todo, out YalpError err); + void getNumOfMedias(out unsigned long num, out YalpError err); + void control(inout Output ctlOutput, out YalpError err); + + void search(in string str, in MediaTypes types, out Medias result, + out YalpError err); + + +/* Outputplugin Handling */ + + void registerOutputPlugin(in OutputPluginInterface itf, inout PluginInfo info, + out YalpError err); + + void removeOutputPlugin(in PluginInfo itf, out YalpError err); + + void getOutputPlugins(out PluginInfos itfs, in string name, + out YalpError err); + + +/* Inputplugin Handling */ + + void registerInputPlugin(in Object itf, inout PluginInfo info, + out YalpError err); + + void removeInputPlugin(in PluginInfo itf, out YalpError err); + + void getInputPlugins(out PluginInfos itfs, in string name, + out YalpError err); + + +/* Identificationplugin Handling */ + + void registerAuthPlugin(in Object itf, inout PluginInfo info, + out YalpError err); + + void removeAuthPlugin(in PluginInfo itf, out YalpError err); + void getAuthPlugins(out PluginInfos itfs, in string name, out YalpError err); + + /* Server related */ + void ping(out YalpError pong); + oneway void serverShutdown(); +}; + +}; diff --git a/svn-commit.tmp b/svn-commit.tmp new file mode 100644 index 0000000..82b4cd3 --- /dev/null +++ b/svn-commit.tmp @@ -0,0 +1,4 @@ +initial import +--This line, and those below, will be ignored-- + +A . |
