diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | build.xml | 79 | ||||
-rw-r--r-- | src/com/isode/stroke/network/PlatformDomainNameResolver.java | 15 | ||||
-rw-r--r-- | src/com/isode/stroke/network/PlatformDomainNameServiceQuery.java | 88 |
5 files changed, 96 insertions, 96 deletions
@@ -1,63 +1,67 @@ all: dist/lib/stroke.jar -DEFINES = -Dxpp-dir=third-party/xpp -Djzlib-dir=third-party/jzlib -Dicu4j-dir=third-party/ -Dstax2-dir=third-party/stax2/ -Daalto-dir=third-party/aalto/ +DEFINES = -Dxpp-dir=third-party/xpp -Djzlib-dir=third-party/jzlib -Dicu4j-dir=third-party/ -Dstax2-dir=third-party/stax2/ -Daalto-dir=third-party/aalto/ -Ddnsjava-dir=third-party/dnsjava JUNIT ?= /usr/share/junit/junit.jar .PHONY : clean clean: ant clean .PHONY : distclean distclean: clean ant distclean rm -rf third-party .PHONY : dist/lib/stroke.jar -dist/lib/stroke.jar: third-party/jzlib/jzlib.jar third-party/icu4j.jar third-party/aalto/aalto-xml.jar third-party/stax2/stax2-api.jar +dist/lib/stroke.jar: third-party/jzlib/jzlib.jar third-party/icu4j.jar third-party/aalto/aalto-xml.jar third-party/stax2/stax2-api.jar third-party/dnsjava/dnsjava.jar ant ${DEFINES} .PHONY : test test: dist/lib/stroke.jar third-party/cobertura/cobertura.jar third-party/findbugs/lib/findbugs.jar third-party/pmd/lib/pmd-5.0.0.jar ant ${DEFINES} -DJUNIT_JAR=${JUNIT} -Dcobertura-jar=third-party/cobertura/cobertura.jar -Djakarta-oro-jar=third-party/cobertura/lib/jakarta-oro-2.0.8.jar -Dlog4j-jar=third-party/cobertura/lib/log4j-1.2.9.jar -Dasm-jar=third-party/cobertura/lib/asm-3.0.jar -Dasm-tree-jar=third-party/cobertura/lib/asm-tree-3.0.jar -Dfindbugs.home=third-party/findbugs -Dpmd.home=third-party/pmd test third-party/aalto/aalto-xml.jar: mkdir -p third-party/aalto curl http://repo2.maven.org/maven2/com/fasterxml/aalto-xml/0.9.8/aalto-xml-0.9.8.jar -o third-party/aalto/aalto-xml.jar third-party/stax2/stax2-api.jar: mkdir -p third-party/stax2 curl http://repository.codehaus.org/org/codehaus/woodstox/stax2-api/3.0.3/stax2-api-3.0.3.jar -o third-party/stax2/stax2-api.jar third-party/jzlib/jzlib.jar: mkdir -p third-party curl http://www.jcraft.com/jzlib/jzlib-1.0.7.tar.gz -o third-party/jzlib-1.0.7.tar.gz tar -xvzf third-party/jzlib-1.0.7.tar.gz -C third-party/ mv third-party/jzlib-1.0.7 third-party/jzlib cp build-jzlib.xml third-party/jzlib/build.xml ant -f third-party/jzlib/build.xml third-party/icu4j.jar: mkdir -p third-party curl http://download.icu-project.org/files/icu4j/4.8.1/icu4j-4_8_1.jar -o third-party/icu4j.jar +third-party/dnsjava/dnsjava.jar: + mkdir -p third-party/dnsjava + curl http://www.dnsjava.org/download/dnsjava-2.1.6.jar -o third-party/dnsjava/dnsjava.jar + third-party/cobertura/cobertura.jar: mkdir -p third-party curl -L 'http://sourceforge.net/projects/cobertura/files/cobertura/1.9.4.1/cobertura-1.9.4.1-bin.tar.bz2/download' -o third-party/cobertura-1.9.4.1-bin.tar.bz2 tar -xvjf third-party/cobertura-1.9.4.1-bin.tar.bz2 -C third-party/ mv third-party/cobertura-1.9.4.1 third-party/cobertura third-party/findbugs/lib/findbugs.jar: mkdir -p third-party curl -L 'http://prdownloads.sourceforge.net/findbugs/findbugs-2.0.1.tar.gz?download' -o third-party/findbugs-2.0.1.tar.gz tar -xvzf third-party/findbugs-2.0.1.tar.gz -C third-party/ mv third-party/findbugs-2.0.1 third-party/findbugs third-party/pmd/lib/pmd-5.0.0.jar: mkdir -p third-party curl -L 'http://sourceforge.net/projects/pmd/files/pmd/5.0.0/pmd-bin-5.0.0.zip/download' -o third-party/pmd-bin-5.0.0.zip unzip third-party/pmd-bin-5.0.0.zip -d third-party mv third-party/pmd-bin-5.0.0 third-party/pmd .git/hooks/commit-msg: curl -k https://git.swift.im/review/tools/hooks/commit-msg -o .git/hooks/commit-msg chmod u+x .git/hooks/commit-msg @@ -1,22 +1,24 @@ Stroke Stroke is a port of the C++ Swift library ( http://swift.im/swiften/ ) The source is available from the Git repository at http://swift.im/git/stroke/ For XML parsing, Stroke depends on the Aalto XML Parser and the STAX2 API, from http://wiki.fasterxml.com/AaltoHome It also depends upon http://www.jcraft.com/jzlib/, which is passed to ant in the jzlib-dir parameter. The passed folder should contain a jar called jzlib.jar. It also depends upon icu4j from http://site.icu-project.org/ +It also depends upon dnsjava from http://www.dnsjava.org/ + To build, run: ant -Dxpp-dir=third-party/xpp -Djzlib-dir=third-party/jzlib -Dicu4j-dir=third-party/ -Dstax2-dir=third-party/stax2/ -Daalto-dir=third-party/aalto/ Changing the paths to the relevant paths for the dependencies on your system Easy version: The included Makefile should, on Unixes with make/curl installed, grab the dependencies (once only) and build. For development: If you want to commit changes to Stroke, first run `make .git/hooks/commit-msg` to download a script that will generate change-ids needed by our review system. @@ -1,227 +1,228 @@ <!-- - * Copyright (c) 2010, Isode Limited, London, England. + * Copyright (c) 2010-2013, Isode Limited, London, England. * All rights reserved. --> <project name="Stroke" default="dist" basedir="."> <description> XMPP Library porting Swiften to Java. </description> <property name="src" location="src"/> <property name="doc" location="doc"/> <property name="src.tests" location="test"/> <property name="test.results" location="test-results"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <property name="jar" value="${dist}/lib/stroke.jar"/> <property name="main-class" value="com.isode.stroke.examples.gui.StrokeGUI"/> <property name="compile.debug" value="true"/> <property name="testsuiteclass" value="com.isode.stroke.unittest.StrokeTestSuite" /> <property name="aalto-dir" value="../third-party/aalto"/> <property name="stax2-dir" value="../third-party/stax2"/> <property name="jzlib-dir" value="../third-party/jzlib"/> <property name="icu4j-dir" value="../third-party/icu4j"/> + <property name="dnsjava-dir" value="../third-party/dnsjava"/> <property name="cobertura.dir" value="instrumented"/> <property name="coveragereport.dir" value="coverage"/> <path id="cobertura.classpath"> - <pathelement path="${cobertura-jar}"/> - <pathelement path="${jakarta-oro-jar}"/> - <pathelement path="${log4j-jar}"/> - <pathelement path="${asm-jar}"/> - <pathelement path="${asm-tree-jar}"/> + <pathelement path="${cobertura-jar}"/> + <pathelement path="${jakarta-oro-jar}"/> + <pathelement path="${log4j-jar}"/> + <pathelement path="${asm-jar}"/> + <pathelement path="${asm-tree-jar}"/> </path> <taskdef classpathref="cobertura.classpath" resource="tasks.properties"/> <path id="classpath"> <fileset dir="${aalto-dir}" includes="aalto-xml.jar"/> <fileset dir="${stax2-dir}" includes="stax2-api.jar"/> <fileset dir="${jzlib-dir}" includes="jzlib.jar"/> <fileset dir="${icu4j-dir}" includes="icu4j.jar"/> + <fileset dir="${dnsjava-dir}" includes="dnsjava.jar"/> </path> <target name="init"> <tstamp/> <mkdir dir="${build}"/> </target> <target name="-compile-with-examples" depends="init" description="compile the source, including examples " unless="noexamples"> <javac srcdir="${src}" destdir="${build}" classpathref="classpath" debug="${compile.debug}" source="1.6" target="1.6"> <compilerarg line="-encoding utf-8"/> </javac> </target> <target name="-compile-without-examples" depends="init" description="compile the source, excluding examples " if="noexamples"> <javac srcdir="${src}" destdir="${build}" classpathref="classpath" debug="${compile.debug}" source="1.6" target="1.6"> <exclude name="com/isode/stroke/examples/**"/> <compilerarg line="-encoding utf-8"/> </javac> </target> <target name="dist" depends="-dist-with-examples,-dist-without-examples"/> <target name="-dist-with-examples" depends="-compile-with-examples" description="generate the distribution including examples" unless="noexamples"> <mkdir dir="${dist}/lib"/> <jar jarfile="${jar}" basedir="${build}"> <manifest> <attribute name="Main-Class" value="${main-class}"/> </manifest> </jar> </target> <target name="-dist-without-examples" depends="-compile-without-examples" description="generate the distribution excluding examples" if="noexamples"> <mkdir dir="${dist}/lib"/> <jar jarfile="${jar}" basedir="${build}"> </jar> </target> -<target name="compile-tests" depends="dist" + <target name="compile-tests" depends="dist" description="compile the test sources " > <javac srcdir="${src.tests}" destdir="${src.tests}" debug="${compile.debug}" source="1.6" target="1.6"> <compilerarg line="-encoding utf-8"/> <classpath> <pathelement location="${jar}"/> <pathelement location="${JUNIT_JAR}"/> </classpath> </javac> </target> <target name="instrument" if="cobertura-jar" depends="compile-tests"> <delete dir="${cobertura.dir}"/> <mkdir dir="${cobertura.dir}"/> <cobertura-instrument todir="${cobertura.dir}"> <fileset dir="test"> <include name="**/*.class"/> </fileset> </cobertura-instrument> </target> <target name="run-tests" depends="compile-tests"> <delete dir="${test.results}"/> <mkdir dir="${test.results}"/> <junit fork="yes"> - <formatter type="xml"/> - <classpath> - <pathelement location="${cobertura.dir}"/> - <path refid="cobertura.classpath"/> - </classpath> - <classpath> - <pathelement location="${JUNIT_JAR}"/> - <pathelement location="${jar}"/> - <pathelement location="${src.tests}"/> - <path refid="classpath"/> - </classpath> - <batchtest todir="${test.results}"> - <fileset dir="${src.tests}"> - <include name="**/*Test.java"/> - <!--<exclude name="**/AllTests.java"/>--> - </fileset> - </batchtest> + <formatter type="xml"/> + <classpath> + <pathelement location="${cobertura.dir}"/> + <path refid="cobertura.classpath"/> + </classpath> + <classpath> + <pathelement location="${JUNIT_JAR}"/> + <pathelement location="${jar}"/> + <pathelement location="${src.tests}"/> + <path refid="classpath"/> + </classpath> + <batchtest todir="${test.results}"> + <fileset dir="${src.tests}"> + <include name="**/*Test.java"/> + <!--<exclude name="**/AllTests.java"/>--> + </fileset> + </batchtest> </junit> - </target> <target name="coverage" if="cobertura-jar" depends="instrument, run-tests"> <delete dir="${coveragereport.dir}"/> <mkdir dir="${coveragereport.dir}"/> <cobertura-report format="xml" destdir="${coveragereport.dir}"> - <fileset dir="${src}"> - <include name="**/*.java"/> - </fileset> - <fileset dir="${src.tests}"> - <include name="**/*.java"/> - </fileset> + <fileset dir="${src}"> + <include name="**/*.java"/> + </fileset> + <fileset dir="${src.tests}"> + <include name="**/*.java"/> + </fileset> </cobertura-report> </target> <target name="findbugs" if="findbugs.home" depends="dist"> <path id="findbugs-jar"> <pathelement path="${findbugs.home}/lib/findbugs-ant.jar" /> </path> <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask" classpathref="findbugs-jar" /> <findbugs home="${findbugs.home}" output="xml" outputFile="findbugs.xml" > <auxClasspath> <path refid="classpath" /> </auxClasspath> <sourcePath path="${src}" /> <class location="${jar}" /> </findbugs> </target> <target name="pmd"> <path id="pmd-jar"> <fileset dir="${pmd.home}/lib"> <include name="*.jar" /> </fileset> </path> <taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd-jar"/> <pmd shortFilenames="true"> <ruleset>pmd-ruleset.xml</ruleset> <formatter type="xml" toFile="pmd.xml" /> <fileset dir="${src}"> <include name="**/*.java"/> </fileset> </pmd> </target> <target name="test" depends="compile-tests, instrument, run-tests, coverage, findbugs, pmd"> </target> <target name="clean" - description="clean up" > + description="clean up" > <delete dir="${build}"/> <delete dir="${test.results}"/> <delete dir="${dist}"/> <delete dir="${doc}"/> <delete dir="${coveragereport.dir}"/> <delete dir="${cobertura.dir}"/> </target> <target name="javadoc" depends="init"> <!-- Note that this may stall if no network connection is available to the Oracle website --> <javadoc packagenames="com.isode.**.**" sourcepath="${src}" destdir="${doc}" windowtitle="Stroke"> <!--<classpath> <fileset dir="${xpp-dir}" includes="xpp.jar"/> </classpath>--> - <link href="http://docs.oracle.com/javase/6/docs/api/"/> + <link href="http://docs.oracle.com/javase/6/docs/api/"/> </javadoc> </target> <target name="run" description="Run the demo" depends="dist"> - <java fork="true" classname="${main-class}"> - <classpath> - <path refid="classpath"/> - <path location="${jar}"/> - </classpath> - </java> + <java fork="true" classname="${main-class}"> + <classpath> + <path refid="classpath"/> + <path location="${jar}"/> + </classpath> + </java> </target> </project> diff --git a/src/com/isode/stroke/network/PlatformDomainNameResolver.java b/src/com/isode/stroke/network/PlatformDomainNameResolver.java index 3eef682..32f466d 100644 --- a/src/com/isode/stroke/network/PlatformDomainNameResolver.java +++ b/src/com/isode/stroke/network/PlatformDomainNameResolver.java @@ -1,69 +1,72 @@ /* - * Copyright (c) 2010-2012, Isode Limited, London, England. + * Copyright (c) 2010-2013, Isode Limited, London, England. * All rights reserved. */ /* * Copyright (c) 2010, Remko Tronçon. * All rights reserved. */ package com.isode.stroke.network; import com.isode.stroke.eventloop.Event.Callback; import com.isode.stroke.eventloop.EventLoop; import com.isode.stroke.eventloop.EventOwner; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; +import org.xbill.DNS.Address; + public class PlatformDomainNameResolver extends DomainNameResolver { private class AddressQuery extends DomainNameAddressQuery implements EventOwner { private class AddressQueryThread extends Thread { @Override public void run() { final Collection<HostAddress> results = new ArrayList<HostAddress>(); try { - for (InetAddress result : InetAddress.getAllByName(hostname)) { + for (InetAddress result : Address.getAllByName(hostname)) { results.add(new HostAddress(result)); } } catch (UnknownHostException ex) { + /* results remains empty */ } eventLoop.postEvent(new Callback() { public void run() { onResult.emit(results, results.isEmpty() ? new DomainNameResolveError() : null); } }); } } AddressQuery(String host, EventLoop eventLoop) { hostname = host; this.eventLoop = eventLoop; } public void run() { AddressQueryThread thread = new AddressQueryThread(); thread.setDaemon(true); thread.start(); } final String hostname; final EventLoop eventLoop; } public PlatformDomainNameResolver(EventLoop eventLoop) { - this.eventLoop = eventLoop; + this.eventLoop_ = eventLoop; } @Override public DomainNameServiceQuery createServiceQuery(String name) { - return new PlatformDomainNameServiceQuery(getNormalized(name), eventLoop); + return new PlatformDomainNameServiceQuery(getNormalized(name), eventLoop_); } @Override public DomainNameAddressQuery createAddressQuery(String name) { - return new AddressQuery(getNormalized(name), eventLoop); + return new AddressQuery(getNormalized(name), eventLoop_); } - private final EventLoop eventLoop; + private final EventLoop eventLoop_; } diff --git a/src/com/isode/stroke/network/PlatformDomainNameServiceQuery.java b/src/com/isode/stroke/network/PlatformDomainNameServiceQuery.java index 0fc7976..37cf1f2 100644 --- a/src/com/isode/stroke/network/PlatformDomainNameServiceQuery.java +++ b/src/com/isode/stroke/network/PlatformDomainNameServiceQuery.java @@ -1,87 +1,77 @@ /* - * Copyright (c) 2010-2012, Isode Limited, London, England. + * Copyright (c) 2010-2013, Isode Limited, London, England. * All rights reserved. */ /* * Copyright (c) 2010 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ package com.isode.stroke.network; +import java.util.ArrayList; +import java.util.Collection; + +import org.xbill.DNS.Lookup; +import org.xbill.DNS.Record; +import org.xbill.DNS.SRVRecord; +import org.xbill.DNS.TextParseException; +import org.xbill.DNS.Type; import com.isode.stroke.eventloop.Event.Callback; import com.isode.stroke.eventloop.EventLoop; -import com.isode.stroke.eventloop.EventOwner; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Hashtable; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; +import com.isode.stroke.network.DomainNameServiceQuery; -public class PlatformDomainNameServiceQuery extends DomainNameServiceQuery implements EventOwner { +public class PlatformDomainNameServiceQuery extends DomainNameServiceQuery { + private final String service; + private final EventLoop eventLoop; - private class QueryThread extends Thread { + public PlatformDomainNameServiceQuery(final String service, final EventLoop eventLoop) { + this.service = service; + this.eventLoop = eventLoop; + } + private class QueryThread extends Thread { @Override public void run() { final Collection<Result> results = new ArrayList<Result>(); - Hashtable env = new Hashtable(); - env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); - env.put("java.naming.provider.url", "dns:"); - DirContext ctx = null; + Lookup request; try { - ctx = new InitialDirContext(env); - Attributes attrs = ctx.getAttributes(service, new String[]{"SRV"}); - Attribute attribute = attrs.get("SRV"); - for (int i = 0; attribute != null && i < attribute.size(); i++) { - /* SRV results are going to be returned in the space-separated format - * Priority Weight Port Target - * (See RFC2782) - */ - String[] srvParts = ((String) attribute.get(i)).split(" "); - String host = srvParts[3]; - if (host.endsWith(".")) { - host = host.substring(0, host.length() - 1); + request = new Lookup(service, Type.SRV); + final Record[] records = request.run(); + if (records != null) { + for (final Record record : records) { + /* It's only anticipated that SRVRecords will be + * returned, but check first + */ + if (record instanceof SRVRecord) { + final SRVRecord srv = (SRVRecord) record; + final Result result = new Result(srv.getTarget() + .toString(), srv.getPort(), srv.getPriority(), + srv.getWeight()); + results.add(result); + } } - Result result = new Result(host, Integer.parseInt(srvParts[2]), Integer.parseInt(srvParts[0]), Integer.parseInt(srvParts[1])); - results.add(result); } - } catch (NamingException ex) { - /* Turns out that you get the exception just for not finding a result, so we want to fall through to A lookups and ignore.*/ + } catch (final TextParseException e) { + /* Lookup failed because "service" was not a valid DNS name; + * leave "results" empty + */ } eventLoop.postEvent(new Callback() { + @Override public void run() { onResult.emit(results); } }); - //close the context as otherwise this will lead to open sockets in - //CLOSE_WAIT condition - if(ctx != null) { - try { - ctx.close(); - } catch (NamingException e) { - //at least we try to close the context - } - } } } - public PlatformDomainNameServiceQuery(String service, EventLoop eventLoop) { - this.service = service; - this.eventLoop = eventLoop; - } - @Override public void run() { - QueryThread thread = new QueryThread(); + final QueryThread thread = new QueryThread(); thread.setDaemon(true); thread.start(); } - private final String service; - private final EventLoop eventLoop; } |