Implement spring Conduit bean registry and lots of cleanup
Stefan Bund [Mon, 20 Sep 2010 20:14:19 +0000 (22:14 +0200)]
22 files changed:
.classpath
.gitmodules [new file with mode: 0644]
.springBeans
build.xml
conduits.xml [new file with mode: 0644]
libs/README.txt [new file with mode: 0644]
libs/commons-logging [new submodule]
libs/spring [new submodule]
src/de/j32/avmfritz/FritzBox.java
src/de/j32/avmfritz/LoginXML.java
src/de/j32/httplib/HttpRequest.java
src/de/j32/pimstuff/Main.java
src/de/j32/pimstuff/conduit/Conduit.java [new file with mode: 0644]
src/de/j32/pimstuff/conduit/ConduitException.java [new file with mode: 0644]
src/de/j32/pimstuff/conduit/Config.java [new file with mode: 0644]
src/de/j32/pimstuff/conduit/ConfigurationException.java [new file with mode: 0644]
src/de/j32/pimstuff/conduit/FritzAddressbookConduit.java [new file with mode: 0644]
src/de/j32/pimstuff/conduit/FritzAddressbookExporter.java
src/de/j32/pimstuff/conduit/FritzAddressbookImporter.java
src/de/j32/pimstuff/conduit/Registry.java [new file with mode: 0644]
src/de/j32/util/SimpleXmlGenerator.java
src/de/j32/util/XmlUtil.java

index 0cbf9cd..eabe221 100644 (file)
@@ -2,5 +2,29 @@
 <classpath>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="src" path="src"/>
+       <classpathentry kind="lib" path="libs/commons-logging/commons-logging-1.1.1.jar"/>
+       <classpathentry kind="lib" path="libs/commons-logging/commons-logging-adapters-1.1.1.jar"/>
+       <classpathentry kind="lib" path="libs/commons-logging/commons-logging-api-1.1.1.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.aop-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.asm-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.aspects-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.beans-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.context-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.context.support-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.core-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.expression-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.instrument-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.instrument.tomcat-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.jdbc-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.jms-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.orm-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.oxm-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.spring-library-3.0.4.RELEASE.libd"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.test-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.transaction-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.web-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.web.portlet-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.web.servlet-3.0.4.RELEASE.jar"/>
+       <classpathentry kind="lib" path="libs/spring/dist/org.springframework.web.struts-3.0.4.RELEASE.jar"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..54d4eb9
--- /dev/null
@@ -0,0 +1,6 @@
+[submodule "libs/commons-logging"]
+       path = libs/commons-logging
+       url = git://g0dil.de/java-logging.git
+[submodule "libs/spring"]
+       path = libs/spring
+       url = git://g0dil.de/java-spring.git
index 4dff647..710c746 100644 (file)
@@ -7,6 +7,7 @@
        </configSuffixes>
        <enableImports><![CDATA[false]]></enableImports>
        <configs>
+               <config>conduits.xml</config>
        </configs>
        <configSets>
        </configSets>
index a0c6ac6..a6a3342 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1,27 +1,33 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project name="PIMStuff" default="build" basedir=".">
 
-       <property name="src" location="src"/>
-       <property name="build" location="bin"/>
-       <property name="main" value="de.j32.pimstuff.Main"/>
-
+       <property name="src" location="src" />
+       <property name="build" location="bin" />
+       <property name="main" value="de.j32.pimstuff.Main" />
+       <property name="lib" value="libs" />
+       
        <target name="makedirs">
-               <mkdir dir="${build}"/>
+               <mkdir dir="${build}" />
        </target>
+
+       <path id="classpath.lib">
+               <fileset dir="${lib}">
+                       <include name="**/*.jar" />
+               </fileset>
+       </path>
        
-       <target name="build" depends="makedirs"
-                       description="Compile project to ${build} directory">
-               <javac srcdir="${src}" destdir="${build}"/>
+       <target name="build" depends="makedirs" description="Compile project to ${build} directory">
+               <javac srcdir="${src}" destdir="${build}" />
        </target>
-       
-       <target name="clean"
-                       description="Clean up ${build} directory">
-               <delete><fileset dir="${build}"/></delete>
+
+       <target name="clean" description="Clean up ${build} directory">
+               <delete>
+                       <fileset dir="${build}" />
+               </delete>
        </target>
 
-       <target name="run" depends="build"
-                       description="Start main class">
-               <java fork="true" classpath="${build}" classname="${main}"/>
+       <target name="run" depends="build" description="Start main class">
+               <java fork="true" classpath="${build}" classpathref="classpath.lib" classname="${main}" />
        </target>
 
 </project>
diff --git a/conduits.xml b/conduits.xml
new file mode 100644 (file)
index 0000000..49ad034
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+       <bean class="de.j32.pimstuff.conduit.FritzAddressbookConduit"
+               name="fritzbox" scope="prototype">
+       </bean>
+
+
+</beans>
diff --git a/libs/README.txt b/libs/README.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/libs/commons-logging b/libs/commons-logging
new file mode 160000 (submodule)
index 0000000..6fb36bd
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 6fb36bd41f967baf1e314ffbcb3af81a0799258d
diff --git a/libs/spring b/libs/spring
new file mode 160000 (submodule)
index 0000000..51cae33
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 51cae333d72082426093c9dd91ff4d2c4e1ef813
index de8e63f..c1852e7 100644 (file)
@@ -74,7 +74,6 @@ public class FritzBox
                        public void close()
                                throws IOException
                        {
-                               System.out.println("sending to fritzbox");
                                httpPostMultipart("cgi-bin/firmwarecfg")
                                        .addParameter("sid", sid_)
                                        .addParameter("PhonebookId", "0")
index c50f80a..82766c3 100644 (file)
@@ -66,10 +66,9 @@ public class LoginXML
                        md.update((c + "-" + password).getBytes("UTF-16LE"));
                        return c + "-" + new HexBinaryAdapter().marshal(md.digest()).toLowerCase();
                } catch (NoSuchAlgorithmException e) {
-                       // Is it at all feasible for this to happen ?
-                       throw new RuntimeException("missing MD5 implementation");
+                       throw new AssertionError("missing MD5 implementation");
                } catch (UnsupportedEncodingException e) {
-                       throw new RuntimeException("missing UTF-16LE encoding");
+                       throw new AssertionError("missing UTF-16LE encoding");
                }
        }
 }
index 7f9c32e..473690b 100644 (file)
@@ -63,26 +63,18 @@ public abstract class HttpRequest
                if (query_.length() > 0)
                        url_.append("?");
                        url_.append(query_);
-               System.out.println("Opening: " + url_);
                HttpURLConnection connection = 
                        (HttpURLConnection) new URL(new String(url_)).openConnection();
-               System.out.println("Request method: " + method_);
                connection.setRequestMethod(method_);
                if (contentType_ != null) {
-                       System.out.println("Content-Type: " + contentType_);
                        connection.setRequestProperty("Content-Type", contentType_);
                        connection.setDoOutput(true);
-                       System.out.println("Body size: " + body_.size());
                        connection.setFixedLengthStreamingMode(body_.size());
-                       System.out.println("Body:");
-                       System.out.println(body_.toString());
                        connection.getOutputStream().write(body_.toByteArray());
-                       System.out.println("done...");
                }
                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
                        throw new IOException("HTTP request failed: " 
                                        + connection.getResponseCode() + " " + connection.getResponseMessage());
-               System.out.println("response ok");
                return new HttpResponse(connection);
        }
        
index 09da5f9..089eee9 100644 (file)
@@ -1,18 +1,12 @@
 package de.j32.pimstuff;
 
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Properties;
 
-import org.xml.sax.SAXException;
-
-import de.j32.avmfritz.FritzBox;
-import de.j32.pimstuff.conduit.FritzAddressbookImporter;
-import de.j32.pimstuff.conduit.FritzAddressbookExporter;
+import de.j32.pimstuff.conduit.Conduit;
+import de.j32.pimstuff.conduit.ConduitException;
+import de.j32.pimstuff.conduit.Exporter;
+import de.j32.pimstuff.conduit.Importer;
+import de.j32.pimstuff.conduit.Registry;
 import de.j32.pimstuff.data.Addressbook;
 import de.j32.util.Util;
 
@@ -21,76 +15,36 @@ public class Main {
        public static void main(String[] args)
        {       
                try {
-                       
-                       System.out.println("Launching pimstuff ...");
-                       Properties config = new Properties();
-                       
-                       try {
-                               config.loadFromXML(new FileInputStream("config.xml"));
-                       }
-                       catch (FileNotFoundException e) {
-                               config.setProperty("password", "password");
-                               config.setProperty("url", "http://fritz.box");
-                               
-                               config.storeToXML(new FileOutputStream("config.xml"), null, "UTF-8");
-                       }
-                       
-                       String pw, url;
-
-                       try {
-                               pw = Util.nonnull(config.getProperty("password"));
-                               url = Util.nonnull(config.getProperty("url"));
-                       }
-                       catch (NullPointerException e) {
-                               throw new RuntimeException("Missing configuration parameter");
-                       }
-
                        Addressbook ab = new Addressbook();
-                       FritzBox fb = new FritzBox(pw, url);
+                       Conduit conduit = Registry.get("fritzbox");
 
-                       System.out.println("loading ...");
-                       // Load Addressbook from FritzBox
-                       InputStream is = null;
-                       FritzAddressbookImporter reader = null;
+                       Importer i = null;
                        try {
-                               ab = new Addressbook();
-                               is = fb.exportAddressbook();
-                               reader = new FritzAddressbookImporter(is);
-                               reader.sendTo(ab);
-                               is.close();
-                               is = null;
-                               reader.close();
-                               reader = null;
+                               i = conduit.importer();
+                               i.sendTo(ab);
+                               i.close();
+                               i = null;
                        }
                        finally {
-                               Util.nothrowClose(is);
+                               Util.nothrowClose(i);
                        }
                        
-                       System.out.println("saving ...");
-                       // Save Addressbook back to FritzBox
-                       FritzAddressbookExporter writer = null;
-                       OutputStream os = null;
+                       Exporter e = null;
                        try {
-                               os = fb.importAddressbook();
-                               writer = new FritzAddressbookExporter(os);
-                               ab.sendTo(writer);
-                               writer.close();
-                               writer = null;
-                               os.close();
-                               os = null;
+                               e = conduit.exporter();
+                               ab.sendTo(e);
+                               e.close();
+                               e = null;
                        }
                        finally {
-                               Util.nothrowClose(writer);
-                               Util.nothrowClose(os);
+                               Util.nothrowClose(e);
                        }
-
-               } catch (SAXException e) {
-                       // TODO Auto-generated catch block
+               }
+               catch (ConduitException e) {
                        e.printStackTrace();
-               } catch (IOException e) {
-                       // TODO Auto-generated catch block
+               }
+               catch (IOException e) {
                        e.printStackTrace();
                }
        }
-
 }
diff --git a/src/de/j32/pimstuff/conduit/Conduit.java b/src/de/j32/pimstuff/conduit/Conduit.java
new file mode 100644 (file)
index 0000000..82963ed
--- /dev/null
@@ -0,0 +1,7 @@
+package de.j32.pimstuff.conduit;
+
+public interface Conduit
+{
+       public Exporter exporter() throws ConduitException;
+       public Importer importer() throws ConduitException;
+}
diff --git a/src/de/j32/pimstuff/conduit/ConduitException.java b/src/de/j32/pimstuff/conduit/ConduitException.java
new file mode 100644 (file)
index 0000000..261281c
--- /dev/null
@@ -0,0 +1,21 @@
+package de.j32.pimstuff.conduit;
+
+public class ConduitException
+       extends Exception
+{
+       private static final long serialVersionUID = 1L;
+
+       public ConduitException()
+       {}
+       
+       public ConduitException(String message)
+       {
+               super(message);
+       }
+       
+       public ConduitException(Exception e)
+       {
+               super(e);
+       }
+
+}
diff --git a/src/de/j32/pimstuff/conduit/Config.java b/src/de/j32/pimstuff/conduit/Config.java
new file mode 100644 (file)
index 0000000..54708ce
--- /dev/null
@@ -0,0 +1,53 @@
+package de.j32.pimstuff.conduit;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Properties;
+
+public class Config
+{
+       static Config instance;
+       Properties config = new Properties();
+       
+       public static String get(String key, String defaultValue)
+       {
+               load();
+               
+               if (instance == null)
+                       return defaultValue;
+               else {
+                       String rv = instance.config.getProperty(key);
+                       if (rv == null)
+                               return defaultValue;
+                       return rv;
+               }
+       }
+
+       public static String get(String key)
+       {
+               String rv = get(key, null);
+               if (rv == null)
+                       throw new ConfigurationException("missing configuration parameter: " + key);
+               return rv;
+       }
+       
+       static void load()
+       {
+                       if (instance == null)
+                               try {
+                                       instance = new Config();
+                               }
+                               catch (InvalidPropertiesFormatException e) {}
+                               catch (FileNotFoundException e) {}
+                               catch (IOException e) {}
+       }
+       
+       Config() 
+               throws InvalidPropertiesFormatException, FileNotFoundException, IOException
+       {
+               config.loadFromXML(new FileInputStream("config.xml"));
+       }
+       
+}
diff --git a/src/de/j32/pimstuff/conduit/ConfigurationException.java b/src/de/j32/pimstuff/conduit/ConfigurationException.java
new file mode 100644 (file)
index 0000000..95b83a3
--- /dev/null
@@ -0,0 +1,12 @@
+package de.j32.pimstuff.conduit;
+
+public class ConfigurationException
+       extends RuntimeException
+{
+       private static final long serialVersionUID = 1L;
+
+       public ConfigurationException(String msg)
+       {
+               super(msg);
+       }
+}
diff --git a/src/de/j32/pimstuff/conduit/FritzAddressbookConduit.java b/src/de/j32/pimstuff/conduit/FritzAddressbookConduit.java
new file mode 100644 (file)
index 0000000..d894ae0
--- /dev/null
@@ -0,0 +1,53 @@
+package de.j32.pimstuff.conduit;
+
+import java.io.IOException;
+
+import org.xml.sax.SAXException;
+
+import de.j32.avmfritz.FritzBox;
+
+public class FritzAddressbookConduit
+       implements Conduit
+{
+       FritzBox fb_;
+       
+       public FritzAddressbookConduit()
+               throws ConduitException
+       {
+               try {
+                       fb_ = new FritzBox(
+                                               Config.get("fritzbox-password"),
+                                               Config.get("fritzbox-url","http://fritz.box"));
+               } catch (SAXException e) {
+                       throw new ConduitException(e);
+               } catch (IOException e) {
+                       throw new ConduitException(e);
+               }
+       }
+
+       @Override
+       public Exporter exporter()
+               throws ConduitException
+       {
+               try {
+                       return new FritzAddressbookExporter(fb_.importAddressbook());
+               }
+               catch (IOException e) {
+                       throw new ConduitException(e);
+               }
+       }
+
+       @Override
+       public Importer importer()
+               throws ConduitException
+       {
+               try {
+                       return new FritzAddressbookImporter(fb_.exportAddressbook());
+               }
+               catch (IOException e) {
+                       throw new ConduitException(e);
+               } catch (SAXException e) {
+                       throw new ConduitException(e);
+               }
+       }
+}
index 0e86005..59c8a1d 100644 (file)
@@ -26,12 +26,15 @@ public class FritzAddressbookExporter
                        gen_.start("phonebooks"); gen_.nl();
                        gen_.start("phonebook"); gen_.nl();
                }
-               catch (SAXException e)
-               {
+               catch (SAXException e) {
                        throw new AssertionError("Invalid XML/SAX document generated.");
-               } catch (UnsupportedEncodingException e) {
+               }
+               catch (UnsupportedEncodingException e) {
                        throw new AssertionError("Unsopported encoding iso-8859-1 ??");
                }
+               finally {
+                       Util.nothrowClose(os);
+               }
        }
 
        @Override
@@ -84,11 +87,17 @@ public class FritzAddressbookExporter
                        gen_.end(); gen_.nl();
                        gen_.end();
                        gen_.endDocument();
+                       os_.close();
+                       os_ = null;
                }
                catch (SAXException e)
                {
                        throw new AssertionError("Invalid XML/SAX document generated.");
                }
+               finally
+               {
+                       Util.nothrowClose(os_);
+               }
        }
        
 }
index 6a65a88..5330cc6 100644 (file)
@@ -9,6 +9,7 @@ import org.xml.sax.SAXException;
 
 import de.j32.pimstuff.data.Entry;
 import de.j32.pimstuff.data.EntryConsumer;
+import de.j32.util.Util;
 import de.j32.util.XmlUtil;
 
 public class FritzAddressbookImporter
@@ -19,7 +20,14 @@ public class FritzAddressbookImporter
        public FritzAddressbookImporter(InputStream is)
                throws SAXException, IOException
        {
-               xml_ = XmlUtil.parse(is);
+               try {
+                       xml_ = XmlUtil.parse(is);
+                       is.close();
+                       is = null;
+               }
+               finally {
+                       Util.nothrowClose(is);
+               }
        }
        
        @Override
diff --git a/src/de/j32/pimstuff/conduit/Registry.java b/src/de/j32/pimstuff/conduit/Registry.java
new file mode 100644 (file)
index 0000000..6c10e97
--- /dev/null
@@ -0,0 +1,15 @@
+package de.j32.pimstuff.conduit;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+
+public class Registry
+{
+       static ApplicationContext context_ = new FileSystemXmlApplicationContext("conduits.xml");
+       
+       public static Conduit get(String k)
+       {
+               return context_.getBean(k, Conduit.class);
+       }
+               
+}
index cc8356d..fbddb0a 100644 (file)
@@ -30,10 +30,10 @@ public class SimpleXmlGenerator
                        handler_ = factory.newTransformerHandler();
                }
                catch (TransformerConfigurationException e) {
-                       throw new RuntimeException("XML/SAX transformer configuration error");
+                       throw new AssertionError("XML/SAX transformer configuration error");
                }
                catch (TransformerFactoryConfigurationError e) {
-                       throw new RuntimeException("XML/SAX transformer factory configuration error");
+                       throw new AssertionError("XML/SAX transformer factory configuration error");
                }
                Transformer tf = handler_.getTransformer();
                tf.setOutputProperty(OutputKeys.ENCODING,encoding);
index 2ec9086..693e402 100644 (file)
@@ -36,7 +36,7 @@ public class XmlUtil
                        return builder.parse(is);
                }
                catch (ParserConfigurationException e) {
-                       throw new RuntimeException("SAX/DOM parser configuration error");
+                       throw new AssertionError("SAX/DOM parser configuration error");
                }
        }