mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-04 15:45:58 +01:00
Merge branch '3.4.0' into master
Conflicts: source/org/jivesoftware/smack/SmackConfiguration.java
This commit is contained in:
commit
b18a43920a
154 changed files with 3460 additions and 1650 deletions
BIN
build/ant-contrib-1.0b2.jar
Normal file
BIN
build/ant-contrib-1.0b2.jar
Normal file
Binary file not shown.
Binary file not shown.
183
build/build.xml
183
build/build.xml
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
|
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="${basedir}/build/ant-contrib.jar"/>
|
<pathelement location="${basedir}/build/ant-contrib-1.0b2.jar"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
</taskdef>
|
</taskdef>
|
||||||
|
|
||||||
|
@ -26,29 +26,36 @@
|
||||||
|
|
||||||
<!-- Smack Version -->
|
<!-- Smack Version -->
|
||||||
<property name="version.major" value="3" />
|
<property name="version.major" value="3" />
|
||||||
<property name="version.minor" value="3" />
|
<property name="version.minor" value="4" />
|
||||||
<property name="version.revision" value="1" />
|
<property name="version.revision" value="1" />
|
||||||
<property name="version.extra" value="" />
|
<property name="version.extra" value="SNAPSHOT" />
|
||||||
|
|
||||||
|
<var name="mutable-version" value="${version.major}.${version.minor}.${version.revision}"/>
|
||||||
|
<var name="mutable-experimental-version" value="0.1"/>
|
||||||
|
|
||||||
<if>
|
<if>
|
||||||
<equals arg1="${version.extra}" arg2=""/>
|
<length string="${version.extra}" when="greater" length="0"/>
|
||||||
<then>
|
<then>
|
||||||
<property name="version"
|
<var name="mutable-version" value="${mutable-version}.${version.extra}"/>
|
||||||
value="${version.major}.${version.minor}.${version.revision}"/>
|
<var name="mutable-experimental-version" value="${mutable-experimental-version}.${version.extra}" />
|
||||||
<property name="version.filename"
|
|
||||||
value="${version.major}_${version.minor}_${version.revision}"/>
|
|
||||||
</then>
|
</then>
|
||||||
<else>
|
|
||||||
<property name="version"
|
|
||||||
value="${version.major}.${version.minor}.${version.revision}.${version.extra}"/>
|
|
||||||
<property name="version.filename"
|
|
||||||
value="${version.major}_${version.minor}_${version.revision}_${version.extra}"/>
|
|
||||||
</else>
|
|
||||||
</if>
|
</if>
|
||||||
<tstamp>
|
|
||||||
<format property="builddate" pattern="MM/dd/yyyy"/>
|
|
||||||
</tstamp>
|
|
||||||
|
|
||||||
|
<if>
|
||||||
|
<equals arg1="${dailybuild}" arg2="true" />
|
||||||
|
<then>
|
||||||
|
<tstamp>
|
||||||
|
<format property="build.date" pattern="yyyyMMdd" locale="en"/>
|
||||||
|
</tstamp>
|
||||||
|
<var name="mutable-version" value="${mutable-version}-${build.date}" />
|
||||||
|
<var name="mutable-experimental-version" value="${mutable-experimental-version}-${build.date}" />
|
||||||
|
</then>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<property name="version" value="${mutable-version}" />
|
||||||
|
<property name="experimental.version" value="${mutable-experimental-version}" />
|
||||||
|
|
||||||
|
<property name="bundle.name" value="org.igniterealtime.smack" />
|
||||||
<property file="${basedir}/build/build.properties" />
|
<property file="${basedir}/build/build.properties" />
|
||||||
<property name="compile.dir" value="${basedir}/target/classes" />
|
<property name="compile.dir" value="${basedir}/target/classes" />
|
||||||
<property name="compile.test.dir" value="${basedir}/target/classes-test" />
|
<property name="compile.test.dir" value="${basedir}/target/classes-test" />
|
||||||
|
@ -132,6 +139,40 @@
|
||||||
<pathelement path="${compile.dir}"/>
|
<pathelement path="${compile.dir}"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
</javac>
|
</javac>
|
||||||
|
|
||||||
|
<mkdir dir="${compile.dir}/workgroup" />
|
||||||
|
<javac
|
||||||
|
destdir="${compile.dir}/workgroup"
|
||||||
|
includeAntRuntime="no"
|
||||||
|
debug="on"
|
||||||
|
source="1.6"
|
||||||
|
target="1.6"
|
||||||
|
>
|
||||||
|
<src path="${basedir}/workgroup/source" />
|
||||||
|
<classpath>
|
||||||
|
<fileset dir="${merge.lib.dir}">
|
||||||
|
<include name="*.jar"/>
|
||||||
|
</fileset>
|
||||||
|
<pathelement path="${compile.dir}"/>
|
||||||
|
</classpath>
|
||||||
|
</javac>
|
||||||
|
|
||||||
|
<mkdir dir="${compile.dir}/experimental" />
|
||||||
|
<javac
|
||||||
|
destdir="${compile.dir}/experimental"
|
||||||
|
includeAntRuntime="no"
|
||||||
|
debug="on"
|
||||||
|
source="1.6"
|
||||||
|
target="1.6"
|
||||||
|
>
|
||||||
|
<src path="${basedir}/experimental/source" />
|
||||||
|
<classpath>
|
||||||
|
<fileset dir="${merge.lib.dir}">
|
||||||
|
<include name="*.jar"/>
|
||||||
|
</fileset>
|
||||||
|
<pathelement path="${compile.dir}"/>
|
||||||
|
</classpath>
|
||||||
|
</javac>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- compile-test -->
|
<!-- compile-test -->
|
||||||
|
@ -170,54 +211,68 @@
|
||||||
<!-- jar -->
|
<!-- jar -->
|
||||||
<!-- ======================================================================================= -->
|
<!-- ======================================================================================= -->
|
||||||
<target name="jar" depends="compile" unless="jar.uptodate" description="Produces smack.jar">
|
<target name="jar" depends="compile" unless="jar.uptodate" description="Produces smack.jar">
|
||||||
|
<copy todir="${compile.dir}/META-INF" file="${basedir}/build/resources/META-INF/jul.properties" />
|
||||||
<copy todir="${compile.dir}/META-INF" file="${basedir}/build/resources/META-INF/smack-config.xml" />
|
<copy todir="${compile.dir}/META-INF" file="${basedir}/build/resources/META-INF/smack-config.xml" />
|
||||||
<jar destfile="${jar.dest.dir}/smack.jar"
|
<copy todir="${compile.dir}/META-INF" file="${basedir}/build/resources/META-INF/core.providers" />
|
||||||
|
<property name="smack.jar.name" value="${jar.dest.dir}/smack-${version}.jar" />
|
||||||
|
<jar destfile="${smack.jar.name}"
|
||||||
basedir="${compile.dir}"
|
basedir="${compile.dir}"
|
||||||
includes="org/jivesoftware/smack/**/*.class, **/smack-config.xml">
|
includes="org/jivesoftware/smack/**/*.class, **/smack-config.xml, **/core.providers, **/jul.properties">
|
||||||
<zipfileset src="${merge.lib.dir}/xpp.jar"/>
|
<zipfileset src="${merge.lib.dir}/xpp.jar"/>
|
||||||
</jar>
|
</jar>
|
||||||
<taskdef resource="aQute/bnd/ant/taskdef.properties" classpath="${basedir}/build/build/biz.aQute.bnd.jar"/>
|
<taskdef resource="aQute/bnd/ant/taskdef.properties" classpath="${basedir}/build/build/biz.aQute.bnd.jar"/>
|
||||||
<bndwrap jars="${jar.dest.dir}/smack.jar" output="${jar.dest.dir}/smack.jar" />
|
<bndwrap jars="${smack.jar.name}" output="${smack.jar.name}" />
|
||||||
<jar file="${jar.dest.dir}/smack.jar" update="true">
|
<jar file="${smack.jar.name}" update="true">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Bundle-SymbolicName" value="org.igniterealtime.smack" />
|
<attribute name="Bundle-SymbolicName" value="${bundle.name}" />
|
||||||
|
<attribute name="Bundle-Version" value="${version}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
<copy todir="${compile.dir}/META-INF" file="${basedir}/build/resources/META-INF/smack.providers" />
|
|
||||||
<jar destfile="${jar.dest.dir}/smackx.jar"
|
<property name="smackx.jar.name" value="${jar.dest.dir}/smackx-${version}.jar" />
|
||||||
|
<copy todir="${compile.dir}/META-INF" file="${basedir}/build/resources/META-INF/extension.providers" />
|
||||||
|
<jar destfile="${smackx.jar.name}"
|
||||||
basedir="${compile.dir}"
|
basedir="${compile.dir}"
|
||||||
includes="org/jivesoftware/smackx/**/*.class, **/*.providers"
|
includes="org/jivesoftware/smackx/**/*.class, **/extension.providers"
|
||||||
excludes="org/jivesoftware/smackx/debugger/*.class">
|
excludes="org/jivesoftware/smackx/debugger/*.class">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Class-Path" value="smack.jar" />
|
<attribute name="Class-Path" value="smack.jar" />
|
||||||
</manifest>
|
</manifest>
|
||||||
<zipfileset src="${merge.lib.dir}/jzlib.jar"/>
|
<zipfileset src="${merge.lib.dir}/jzlib.jar"/>
|
||||||
</jar>
|
</jar>
|
||||||
<bndwrap jars="${jar.dest.dir}/smackx.jar" output="${jar.dest.dir}/smackx.jar" />
|
<bndwrap jars="${smackx.jar.name}" output="${smackx.jar.name}" />
|
||||||
<jar file="${jar.dest.dir}/smackx.jar" update="true">
|
<jar file="${smackx.jar.name}" update="true">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Bundle-SymbolicName" value="org.igniterealtime.smack-ext" />
|
<attribute name="Bundle-SymbolicName" value="${bundle.name}-ext" />
|
||||||
|
<attribute name="Bundle-Version" value="${version}" />
|
||||||
|
<attribute name="Fragment-Host" value="${bundle.name};bundle-version=${version}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
|
|
||||||
|
<property name="debug.jar.name" value="${jar.dest.dir}/smackx-debug-${version}.jar" />
|
||||||
<copy todir="${compile.dir}/images">
|
<copy todir="${compile.dir}/images">
|
||||||
<fileset dir="${basedir}/build/resources/images">
|
<fileset dir="${basedir}/build/resources/images">
|
||||||
<include name="*.png"/>
|
<include name="*.png"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
</copy>
|
</copy>
|
||||||
<jar destfile="${jar.dest.dir}/smackx-debug.jar"
|
<jar destfile="${debug.jar.name}"
|
||||||
basedir="${compile.dir}"
|
basedir="${compile.dir}"
|
||||||
includes="org/jivesoftware/smackx/debugger/*.class, **/*.png">
|
includes="org/jivesoftware/smackx/debugger/*.class, **/*.png">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Class-Path" value="smack.jar" />
|
<attribute name="Class-Path" value="smack.jar" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
<bndwrap jars="${jar.dest.dir}/smackx-debug.jar" output="${jar.dest.dir}/smackx-debug.jar" />
|
<bndwrap jars="${debug.jar.name}" output="${debug.jar.name}" />
|
||||||
<jar file="${jar.dest.dir}/smackx-debug.jar" update="true">
|
<jar file="${debug.jar.name}" update="true">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Bundle-SymbolicName" value="org.igniterealtime.smack-ext-debug" />
|
<attribute name="Bundle-SymbolicName" value="${bundle.name}-debug" />
|
||||||
|
<attribute name="Bundle-Version" value="${version}" />
|
||||||
|
<attribute name="Fragment-Host" value="${bundle.name};bundle-version=${version}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
<jar destfile="${jar.dest.dir}/smackx-jingle.jar"
|
|
||||||
|
<property name="jingle.jar.name" value="${jar.dest.dir}/smackx-jingle-${version}.jar" />
|
||||||
|
<jar destfile="${jingle.jar.name}"
|
||||||
basedir="${compile.dir}/jingle/extension"
|
basedir="${compile.dir}/jingle/extension"
|
||||||
includes="org/jivesoftware/smackx/**/*.class">
|
includes="org/jivesoftware/smackx/**/*.class">
|
||||||
<manifest>
|
<manifest>
|
||||||
|
@ -225,35 +280,79 @@
|
||||||
</manifest>
|
</manifest>
|
||||||
<zipfileset src="${jingle.extension.merge.lib.dir}/jstun.jar"/>
|
<zipfileset src="${jingle.extension.merge.lib.dir}/jstun.jar"/>
|
||||||
</jar>
|
</jar>
|
||||||
<bndwrap jars="${jar.dest.dir}/smackx-jingle.jar" output="${jar.dest.dir}/smackx-jingle.jar" />
|
<bndwrap jars="${jingle.jar.name}" output="${jingle.jar.name}" />
|
||||||
<jar file="${jar.dest.dir}/smackx-jingle.jar" update="true">
|
<jar file="${jingle.jar.name}" update="true">
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Bundle-SymbolicName" value="org.igniterealtime.smack-ext-jingle" />
|
<attribute name="Bundle-SymbolicName" value="${bundle.name}-jingle" />
|
||||||
|
<attribute name="Bundle-Version" value="${version}" />
|
||||||
|
<attribute name="Fragment-Host" value="${bundle.name};bundle-version=${version}" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
|
|
||||||
|
<property name="workgroup.jar.name" value="${jar.dest.dir}/smackx-workgroup-${version}.jar" />
|
||||||
|
<copy todir="${compile.dir}/workgroup/META-INF" file="${basedir}/workgroup/resources/META-INF/workgroup.providers" />
|
||||||
|
<jar destfile="${workgroup.jar.name}"
|
||||||
|
basedir="${compile.dir}/workgroup"
|
||||||
|
includes="org/jivesoftware/smackx/workgroup/**/*.class, **/workgroup.providers">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Class-Path" value="smack.jar, smackx.jar" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
<bndwrap jars="${workgroup.jar.name}" output="${workgroup.jar.name}" />
|
||||||
|
<jar file="${workgroup.jar.name}" update="true">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Bundle-SymbolicName" value="${bundle.name}-workgroup" />
|
||||||
|
<attribute name="Bundle-Version" value="${version}" />
|
||||||
|
<attribute name="Fragment-Host" value="${bundle.name};bundle-version=${version}" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
|
||||||
|
<property name="experimental.jar.name" value="${jar.dest.dir}/smackx-experimental-${experimental.version}.jar" />
|
||||||
|
<copy todir="${compile.dir}/experimental/META-INF" file="${basedir}/experimental/resources/META-INF/experimental.providers" />
|
||||||
|
<jar destfile="${experimental.jar.name}"
|
||||||
|
basedir="${compile.dir}/experimental"
|
||||||
|
includes="org/jivesoftware/smackx/**/*.class, **/experimental.providers">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Class-Path" value="smack.jar, smackx.jar" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
<bndwrap jars="${experimental.jar.name}" output="${experimental.jar.name}" />
|
||||||
|
<jar file="${experimental.jar.name}" update="true">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Bundle-SymbolicName" value="${bundle.name}-experimental" />
|
||||||
|
<attribute name="Bundle-Version" value="${version}" />
|
||||||
|
<attribute name="Fragment-Host" value="${bundle.name};bundle-version=${experimental.version}" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
|
||||||
|
<!--
|
||||||
<delete file="${compile.dir}/META-INF/smack-config.xml" />
|
<delete file="${compile.dir}/META-INF/smack-config.xml" />
|
||||||
<delete file="${compile.dir}/META-INF/smack.providers" />
|
<delete file="${compile.dir}/META-INF/*.providers" />
|
||||||
<delete>
|
<delete>
|
||||||
<fileset dir="${compile.dir}/images">
|
<fileset dir="${compile.dir}/images">
|
||||||
<include name="*.png"/>
|
<include name="*.png"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
</delete>
|
</delete>
|
||||||
|
-->
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- jar -->
|
<!-- jar -->
|
||||||
<!-- ======================================================================================= -->
|
<!-- ======================================================================================= -->
|
||||||
<target name="jar-test" depends="compile-test" description="Produces jar of test code">
|
<target name="jar-test" depends="compile-test" description="Produces jar of test code">
|
||||||
|
<copy todir="${compile.test.dir}/META-INF" file="${basedir}/build/resources/META-INF/jul.properties" />
|
||||||
|
<copy todir="${compile.test.dir}/META-INF" file="${basedir}/build/resources/META-INF/smack-config.xml" />
|
||||||
|
<copy todir="${compile.test.dir}/META-INF" file="${basedir}/build/resources/META-INF/core.providers" />
|
||||||
<jar destfile="${jar.dest.dir}/smack-test.jar"
|
<jar destfile="${jar.dest.dir}/smack-test.jar"
|
||||||
basedir="${compile.test.dir}"
|
basedir="${compile.test.dir}"
|
||||||
includes="org/jivesoftware/smack/**/*.class"
|
includes="org/jivesoftware/smack/**/*.class, **/smack-config.xml, **/core.providers, **/jul.properties"
|
||||||
/>
|
/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="jar-test-smackx" depends="compile-test" description="Produces jar of test code">
|
<target name="jar-test-smackx" depends="compile-test" description="Produces jar of test code">
|
||||||
|
<copy todir="${compile.test.dir}/META-INF" file="${basedir}/build/resources/META-INF/extension.providers" />
|
||||||
<jar destfile="${jar.dest.dir}/smack-test-smackx.jar"
|
<jar destfile="${jar.dest.dir}/smack-test-smackx.jar"
|
||||||
basedir="${compile.test.dir}"
|
basedir="${compile.test.dir}"
|
||||||
includes="org/jivesoftware/smackx/**/*.class
|
includes="org/jivesoftware/smackx/**/*.class, org/jivesoftware/util/**/*.class, **/extension.providers"
|
||||||
org/jivesoftware/util/**/*.class"
|
|
||||||
/>
|
/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
@ -283,7 +382,7 @@
|
||||||
<link href="http://java.sun.com/j2se/1.3/docs/api/" />
|
<link href="http://java.sun.com/j2se/1.3/docs/api/" />
|
||||||
<link href="http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/" />
|
<link href="http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/" />
|
||||||
</javadoc>
|
</javadoc>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
||||||
<!-- test -->
|
<!-- test -->
|
||||||
|
@ -365,7 +464,7 @@
|
||||||
<!-- ======================================================================================= -->
|
<!-- ======================================================================================= -->
|
||||||
<target name="test-unit" depends="compile, jar-test, jar-test-smackx" unless="no.test">
|
<target name="test-unit" depends="compile, jar-test, jar-test-smackx" unless="no.test">
|
||||||
<junit printsummary="on"
|
<junit printsummary="on"
|
||||||
fork="true"
|
fork="false"
|
||||||
haltonfailure="false"
|
haltonfailure="false"
|
||||||
failureproperty="tests.failed"
|
failureproperty="tests.failed"
|
||||||
showoutput="true">
|
showoutput="true">
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
<classpathentry kind="src" path="source"/>
|
<classpathentry kind="src" path="source"/>
|
||||||
<classpathentry kind="src" path="test"/>
|
<classpathentry kind="src" path="test"/>
|
||||||
<classpathentry kind="src" path="test-unit"/>
|
<classpathentry kind="src" path="test-unit"/>
|
||||||
<classpathentry kind="lib" path="build/ant-contrib.jar"/>
|
<classpathentry kind="src" path="workgroup/source"/>
|
||||||
|
<classpathentry kind="src" path="experimental/source"/>
|
||||||
|
<classpathentry kind="src" path="experimental/test"/>
|
||||||
|
<classpathentry kind="src" path="workgroup/resources"/>
|
||||||
|
<classpathentry kind="src" path="experimental/resources"/>
|
||||||
<classpathentry kind="lib" path="build/asm.jar"/>
|
<classpathentry kind="lib" path="build/asm.jar"/>
|
||||||
<classpathentry kind="lib" path="build/build/java-xmlbuilder-0.3.jar"/>
|
<classpathentry kind="lib" path="build/build/java-xmlbuilder-0.3.jar"/>
|
||||||
<classpathentry kind="lib" path="build/build/xmlunit.jar"/>
|
<classpathentry kind="lib" path="build/build/xmlunit.jar"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>smack-3.3.x</name>
|
<name>smack-3.4.x</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<!-- Include Ant Optional Tasks -->
|
<!-- Include Ant Optional Tasks -->
|
||||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
|
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="${basedir}/build/ant-contrib.jar"/>
|
<pathelement location="${basedir}/build/ant-contrib-1.0b2.jar"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
</taskdef>
|
</taskdef>
|
||||||
|
|
||||||
|
@ -28,155 +28,66 @@
|
||||||
<!-- ======================================================================================= -->
|
<!-- ======================================================================================= -->
|
||||||
<target name="all">
|
<target name="all">
|
||||||
<!-- create release properties -->
|
<!-- create release properties -->
|
||||||
<if>
|
<property name="release.dir" value="${basedir}/target/release/${version}" />
|
||||||
<equals arg1="${dailybuild}" arg2="true" />
|
<property name="release.samples.dir" value="${release.dir}/samples" />
|
||||||
<then>
|
|
||||||
<tstamp>
|
<tstamp>
|
||||||
<format property="build.date" pattern="yyyy-MM-dd" locale="en"/>
|
<format property="release.date" pattern="dd/MM/yyyy" locale="en"/>
|
||||||
</tstamp>
|
</tstamp>
|
||||||
<property name="release.name" value="smack-${build.date}" />
|
|
||||||
<property name="release-dev.name" value="smack_src_${build.date}" />
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
<property name="release.name" value="smack_${version.filename}" />
|
|
||||||
<property name="release-dev.name" value="smack_src_${version.filename}" />
|
|
||||||
</else>
|
|
||||||
</if>
|
|
||||||
<property name="release.dir" value="${basedir}/target/release/${release.name}" />
|
|
||||||
<property name="release-dev.dir" value="${basedir}/target/release/${release-dev.name}" />
|
|
||||||
<!-- create release dirs -->
|
<!-- create release dirs -->
|
||||||
<mkdir dir="${release.dir}" />
|
<mkdir dir="${release.dir}" />
|
||||||
<mkdir dir="${release-dev.dir}" />
|
<mkdir dir="${release.samples.dir}" />
|
||||||
|
|
||||||
<!-- Copy smack.jar -->
|
<!-- Copy smack.jar -->
|
||||||
<copy todir="${release.dir}">
|
<copy todir="${release.dir}">
|
||||||
<fileset dir="${jar.dest.dir}" includes="smack.jar" />
|
<fileset dir="${jar.dest.dir}" includes="smack-${version}.jar" />
|
||||||
<fileset dir="${jar.dest.dir}" includes="smackx.jar" />
|
<fileset dir="${jar.dest.dir}" includes="smackx-${version}.jar" />
|
||||||
<fileset dir="${jar.dest.dir}" includes="smackx-debug.jar" />
|
<fileset dir="${jar.dest.dir}" includes="smackx-debug-${version}.jar" />
|
||||||
<fileset dir="${jar.dest.dir}" includes="smackx-jingle.jar" />
|
<fileset dir="${jar.dest.dir}" includes="smackx-jingle-${version}.jar" />
|
||||||
|
<fileset dir="${jar.dest.dir}" includes="smackx-workgroup-${version}.jar" />
|
||||||
|
<fileset dir="${jar.dest.dir}" includes="smackx-experimental-${experimental.version}.jar" />
|
||||||
</copy>
|
</copy>
|
||||||
<copy todir="${release-dev.dir}">
|
<copy todir="${release.samples.dir}">
|
||||||
<fileset dir="${jar.dest.dir}" includes="smack.jar" />
|
<fileset dir="${basedir}/build/resources/META-INF" includes="sample.providers" />
|
||||||
<fileset dir="${jar.dest.dir}" includes="smackx.jar" />
|
<fileset dir="${basedir}/build/resources/META-INF" includes="smack-config.xml" />
|
||||||
<fileset dir="${jar.dest.dir}" includes="smackx-debug.jar" />
|
|
||||||
<fileset dir="${jar.dest.dir}" includes="smackx-jingle.jar" />
|
|
||||||
</copy>
|
|
||||||
<!-- Copy build dir -->
|
|
||||||
<copy todir="${release-dev.dir}/build">
|
|
||||||
<fileset dir="${basedir}/build">
|
|
||||||
<include name="ant*" />
|
|
||||||
<include name="junit.jar" />
|
|
||||||
<include name="build.xml" />
|
|
||||||
<include name="README.html" />
|
|
||||||
<include name="lib/*.jar" />
|
|
||||||
<include name="merge/*.jar" />
|
|
||||||
<include name="build/*.jar" />
|
|
||||||
</fileset>
|
|
||||||
</copy>
|
|
||||||
<copy todir="${release-dev.dir}/jingle/extension/build">
|
|
||||||
<fileset dir="${basedir}/jingle/extension/build">
|
|
||||||
<include name="ant*" />
|
|
||||||
<include name="junit.jar" />
|
|
||||||
<include name="build.xml" />
|
|
||||||
<include name="README.html" />
|
|
||||||
<include name="lib/*.jar" />
|
|
||||||
<include name="merge/*.jar" />
|
|
||||||
</fileset>
|
|
||||||
</copy>
|
</copy>
|
||||||
|
|
||||||
|
|
||||||
<!-- Copy Javadocs -->
|
<!-- Copy Javadocs -->
|
||||||
<copy todir="${release.dir}/javadoc">
|
<copy todir="${release.dir}/javadoc">
|
||||||
<fileset dir="${basedir}/target/javadoc" includes="**/*.*" />
|
<fileset dir="${basedir}/target/javadoc" includes="**/*.*" />
|
||||||
</copy>
|
</copy>
|
||||||
<copy todir="${release-dev.dir}/javadoc">
|
|
||||||
<fileset dir="${basedir}/target/javadoc" includes="**/*.*" />
|
|
||||||
</copy>
|
|
||||||
<!-- Copy documentation -->
|
<!-- Copy documentation -->
|
||||||
<copy todir="${release.dir}/documentation">
|
<copy todir="${release.dir}/documentation">
|
||||||
<fileset dir="${basedir}/documentation" includes="**/*.*" />
|
<fileset dir="${basedir}/documentation" includes="**/*.*" />
|
||||||
</copy>
|
</copy>
|
||||||
<copy todir="${release-dev.dir}/documentation">
|
|
||||||
<fileset dir="${basedir}/documentation" includes="**/*.*" />
|
|
||||||
</copy>
|
|
||||||
<!-- Copy source -->
|
|
||||||
<copy todir="${release-dev.dir}/source">
|
|
||||||
<fileset dir="${basedir}/source" includes="**/*.java" />
|
|
||||||
<fileset dir="${basedir}/source" includes="**/*.html" />
|
|
||||||
</copy>
|
|
||||||
<copy todir="${release-dev.dir}/jingle/extension/source">
|
|
||||||
<fileset dir="${basedir}/jingle/extension/source" includes="**/*.java" />
|
|
||||||
<fileset dir="${basedir}/jingle/extension/source" includes="**/*.html" />
|
|
||||||
</copy>
|
|
||||||
<copy todir="${release-dev.dir}/test">
|
|
||||||
<fileset dir="${basedir}/test" includes="**/*.java" />
|
|
||||||
</copy>
|
|
||||||
<!-- Copy resources -->
|
|
||||||
<copy todir="${release-dev.dir}/build/resources">
|
|
||||||
<fileset dir="${basedir}/build/resources" includes="META-INF/smack.providers" />
|
|
||||||
<fileset dir="${basedir}/build/resources" includes="META-INF/smack-config.xml" />
|
|
||||||
</copy>
|
|
||||||
<copy todir="${release-dev.dir}/build/resources/images">
|
|
||||||
<fileset dir="${basedir}/build/resources/images">
|
|
||||||
<include name="*.png"/>
|
|
||||||
</fileset>
|
|
||||||
</copy>
|
|
||||||
<!-- Copy readme.html and changelog.html -->
|
<!-- Copy readme.html and changelog.html -->
|
||||||
<copy todir="${release.dir}">
|
<copy todir="${release.dir}">
|
||||||
<fileset dir="${basedir}/build/resources/releasedocs" includes="*.html" />
|
<fileset dir="${basedir}/build/resources/releasedocs" includes="*.html" />
|
||||||
<filterset>
|
<filterset>
|
||||||
<filter token="builddate" value="${builddate}"/>
|
<filter token="releasedate" value="${release.date}"/>
|
||||||
<filter token="version" value="${version}"/>
|
<filter token="version" value="${version}"/>
|
||||||
</filterset>
|
</filterset>
|
||||||
</copy>
|
</copy>
|
||||||
<copy todir="${release-dev.dir}">
|
|
||||||
<fileset dir="${basedir}/build/resources/releasedocs" includes="*.html" />
|
|
||||||
<filterset>
|
|
||||||
<filter token="builddate" value="${builddate}"/>
|
|
||||||
<filter token="version" value="${version}"/>
|
|
||||||
</filterset>
|
|
||||||
</copy>
|
|
||||||
<!-- Package -->
|
|
||||||
<if>
|
|
||||||
<equals arg1="${dailybuild}" arg2="true" />
|
|
||||||
<then>
|
|
||||||
<zip destfile="${basedir}/target/release/${release-dev.name}.zip"
|
|
||||||
basedir="${release-dev.dir}/.."
|
|
||||||
includes="${release-dev.name}/**/*.*"
|
|
||||||
/>
|
|
||||||
<tar destfile="${basedir}/target/release/${release-dev.name}.tar.gz"
|
|
||||||
basedir="${release-dev.dir}/.."
|
|
||||||
includes="${release-dev.name}/**/*.*"
|
|
||||||
compression="gzip"
|
|
||||||
/>
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
<zip destfile="${basedir}/target/release/${release.name}.zip"
|
|
||||||
basedir="${release.dir}/.."
|
|
||||||
includes="${release.name}/**/*.*"
|
|
||||||
/>
|
|
||||||
<tar destfile="${basedir}/target/release/${release.name}.tar.gz"
|
|
||||||
basedir="${release.dir}/.."
|
|
||||||
includes="${release.name}/**/*.*"
|
|
||||||
compression="gzip"
|
|
||||||
/>
|
|
||||||
<zip destfile="${basedir}/target/release/${release-dev.name}.zip"
|
|
||||||
basedir="${release-dev.dir}/.."
|
|
||||||
includes="${release-dev.name}/**/*.*"
|
|
||||||
/>
|
|
||||||
<tar destfile="${basedir}/target/release/${release-dev.name}.tar.gz"
|
|
||||||
basedir="${release-dev.dir}/.."
|
|
||||||
includes="${release-dev.name}/**/*.*"
|
|
||||||
compression="gzip"
|
|
||||||
/>
|
|
||||||
</else>
|
|
||||||
</if>
|
|
||||||
|
|
||||||
|
<!-- Package -->
|
||||||
|
<zip destfile="${basedir}/target/release/smack-${version}.zip"
|
||||||
|
basedir="${release.dir}"
|
||||||
|
includes="**/*.*"
|
||||||
|
/>
|
||||||
|
<tar destfile="${basedir}/target/release/smack-${version}.tar.gz"
|
||||||
|
basedir="${release.dir}"
|
||||||
|
includes="**/*.*"
|
||||||
|
compression="gzip"
|
||||||
|
/>
|
||||||
<echo>
|
<echo>
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
Release made, testing Ant targets of release...
|
Release made
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
</echo>
|
</echo>
|
||||||
|
|
||||||
<!-- call the release tester -->
|
|
||||||
<antcall target="test" />
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- test -->
|
<!-- test -->
|
||||||
|
|
19
build/resources/META-INF/core.providers
Normal file
19
build/resources/META-INF/core.providers
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Providers file for default Smack extensions -->
|
||||||
|
<smackProviders>
|
||||||
|
|
||||||
|
<!-- Privacy -->
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>query</elementName>
|
||||||
|
<namespace>jabber:iq:privacy</namespace>
|
||||||
|
<className>org.jivesoftware.smack.provider.PrivacyProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<!-- Ping (XEP-199) Manager -->
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>ping</elementName>
|
||||||
|
<namespace>urn:xmpp:ping</namespace>
|
||||||
|
<className>org.jivesoftware.smack.ping.provider.PingProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
</smackProviders>
|
|
@ -223,13 +223,6 @@
|
||||||
<className>org.jivesoftware.smackx.bytestreams.ibb.provider.DataPacketProvider</className>
|
<className>org.jivesoftware.smackx.bytestreams.ibb.provider.DataPacketProvider</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
<!-- Privacy -->
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>query</elementName>
|
|
||||||
<namespace>jabber:iq:privacy</namespace>
|
|
||||||
<className>org.jivesoftware.smack.provider.PrivacyProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<!-- Ad-Hoc Command -->
|
<!-- Ad-Hoc Command -->
|
||||||
<iqProvider>
|
<iqProvider>
|
||||||
<elementName>command</elementName>
|
<elementName>command</elementName>
|
||||||
|
@ -273,217 +266,6 @@
|
||||||
<className>org.jivesoftware.smackx.provider.AdHocCommandDataProvider$SessionExpiredError</className>
|
<className>org.jivesoftware.smackx.provider.AdHocCommandDataProvider$SessionExpiredError</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
|
|
||||||
<!-- Fastpath providers -->
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>offer</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.OfferRequestProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>offer-revoke</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.OfferRevokeProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>agent-status-request</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>transcripts</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.TranscriptsProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>transcript</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.TranscriptProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>workgroups</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.AgentWorkgroups$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>agent-info</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.AgentInfo$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>transcript-search</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.TranscriptSearch$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>occupants-info</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.OccupantsInfo$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>chat-settings</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.settings.ChatSettings$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>chat-notes</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.ext.notes.ChatNotes$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>chat-sessions</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.ext.history.AgentChatHistory$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>offline-settings</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.settings.OfflineSettings$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>sound-settings</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.settings.SoundSettings$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>workgroup-properties</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.settings.WorkgroupProperties$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>search-settings</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.settings.SearchSettings$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>workgroup-form</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.ext.forms.WorkgroupForm$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>macros</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.ext.macros.Macros$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>chat-metadata</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.ext.history.ChatMetadata$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
org.jivesoftware.smackx.workgroup.site is missing ...
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>site-user</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.site.SiteUser$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>site-invite</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.site.SiteInvitation$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>site-user-history</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.site.SiteUserHistory$Provider</className>
|
|
||||||
</iqProvider>
|
|
||||||
-->
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>generic-metadata</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.settings.GenericSettings$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<iqProvider>
|
|
||||||
<elementName>monitor</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.MonitorPacket$InternalProvider</className>
|
|
||||||
</iqProvider>
|
|
||||||
|
|
||||||
<!-- Packet Extension Providers -->
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>queue-status</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.QueueUpdate$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>workgroup</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.WorkgroupInformation$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>metadata</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.MetaDataProvider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>session</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.SessionID$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>user</elementName>
|
|
||||||
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.UserID$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>agent-status</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.AgentStatus$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>notify-queue-details</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.QueueDetails$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>notify-queue</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.QueueOverview$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>invite</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.RoomInvitation$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<extensionProvider>
|
|
||||||
<elementName>transfer</elementName>
|
|
||||||
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
|
||||||
<className>org.jivesoftware.smackx.workgroup.packet.RoomTransfer$Provider</className>
|
|
||||||
</extensionProvider>
|
|
||||||
|
|
||||||
<!-- SHIM -->
|
<!-- SHIM -->
|
||||||
<extensionProvider>
|
<extensionProvider>
|
||||||
<elementName>headers</elementName>
|
<elementName>headers</elementName>
|
||||||
|
@ -653,11 +435,11 @@
|
||||||
<className>org.jivesoftware.smackx.entitycaps.provider.CapsExtensionProvider</className>
|
<className>org.jivesoftware.smackx.entitycaps.provider.CapsExtensionProvider</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
<!-- Ping (XEP-199) Manager -->
|
<!-- XEP-0297 Stanza Forwarding -->
|
||||||
<iqProvider>
|
<extensionProvider>
|
||||||
<elementName>ping</elementName>
|
<elementName>forwarded</elementName>
|
||||||
<namespace>urn:xmpp:ping</namespace>
|
<namespace>urn:xmpp:forward:0</namespace>
|
||||||
<className>org.jivesoftware.smack.ping.provider.PingProvider</className>
|
<className>org.jivesoftware.smackx.forward.provider.ForwardedProvider</className>
|
||||||
</iqProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
</smackProviders>
|
</smackProviders>
|
3
build/resources/META-INF/jul.properties
Normal file
3
build/resources/META-INF/jul.properties
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Java Util Logging configuration for Smack.
|
||||||
|
handlers = java.util.logging.ConsoleHandler
|
||||||
|
.level = WARNING
|
17
build/resources/META-INF/sample.providers
Normal file
17
build/resources/META-INF/sample.providers
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Sample providers file -->
|
||||||
|
<smackProviders>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>element</elementName>
|
||||||
|
<namespace>ns</namespace>
|
||||||
|
<className>com.myco.MyIQProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>elem</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/whoknows</namespace>
|
||||||
|
<className>com.myco.MyExtProvider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
</smackProviders>
|
|
@ -22,9 +22,12 @@
|
||||||
|
|
||||||
<!-- Classes that will be loaded when Smack starts -->
|
<!-- Classes that will be loaded when Smack starts -->
|
||||||
<startupClasses>
|
<startupClasses>
|
||||||
<className>org.jivesoftware.smackx.ServiceDiscoveryManager</className>
|
<className>org.jivesoftware.smack.provider.CoreInitializer</className>
|
||||||
|
<className>org.jivesoftware.smack.provider.VmArgInitializer</className>
|
||||||
<className>org.jivesoftware.smack.PrivacyListManager</className>
|
<className>org.jivesoftware.smack.PrivacyListManager</className>
|
||||||
<className>org.jivesoftware.smack.keepalive.KeepAliveManager</className>
|
<className>org.jivesoftware.smack.keepalive.KeepAliveManager</className>
|
||||||
|
<className>org.jivesoftware.smackx.provider.ExtensionInitializer</className>
|
||||||
|
<className>org.jivesoftware.smackx.ServiceDiscoveryManager</className>
|
||||||
<className>org.jivesoftware.smackx.XHTMLManager</className>
|
<className>org.jivesoftware.smackx.XHTMLManager</className>
|
||||||
<className>org.jivesoftware.smackx.muc.MultiUserChat</className>
|
<className>org.jivesoftware.smackx.muc.MultiUserChat</className>
|
||||||
<className>org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager</className>
|
<className>org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager</className>
|
||||||
|
|
|
@ -148,7 +148,7 @@ hr {
|
||||||
<td><b>@version@</b></td>
|
<td><b>@version@</b></td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td align="right">released:</td>
|
<td align="right">released:</td>
|
||||||
<td><b>@builddate@</b></td>
|
<td><b>@releasedate@</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,47 @@ hr {
|
||||||
|
|
||||||
<div id="pageBody">
|
<div id="pageBody">
|
||||||
|
|
||||||
|
<h2>3.4.0 -- <span style="font-weight: normal;">Feb 2, 2014</span></h2>
|
||||||
|
|
||||||
|
<h2>Bug Fixes</h2>
|
||||||
|
<ul>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-442'>SMACK-442</a>] - Manager's should also handle connectionClosedOnError()</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-443'>SMACK-443</a>] - ReconnectionSuccessful listeners are invoked twice on reconnection if connect() failed before</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-452'>SMACK-452</a>] - PacketParserUtils.parseStreamError() is not aware of optional text element and therefore failes to parse stream error's correctly. Prevents ReconnectionManager from reconnecting.</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-458'>SMACK-458</a>] - Smack's Managers should not remove itself when the connection is closed or should re-add themselfs if the connection get reconnected</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-462'>SMACK-462</a>] - Prevent duplicate manager instances by using the manager's constructor in the ConnectionCreationListener's connectionCreated</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-463'>SMACK-463</a>] - packet listeners silently fail when preceding listener caused exception</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-524'>SMACK-524</a>] - Use correct block-size definition for IBB transfers</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-525'>SMACK-525</a>] - NPE in XMPPConnection.notifyConnectionError</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-529'>SMACK-529</a>] - Add support for XEP-0280 "Message Carbons"</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-530'>SMACK-530</a>] - DNSUtilTest requires an internet connection to work, it should be moved to integration tests.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>New Feature</h2>
|
||||||
|
<ul>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-286'>SMACK-286</a>] - Need to change ProviderManager to support loading smack.providers from alternative locations</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-387'>SMACK-387</a>] - Allow configuration of ChatManager to be able to allow message handling to be customized.</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-403'>SMACK-403</a>] - Add support for XEP-0297 "Stanza Forwarding"</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-434'>SMACK-434</a>] - Create a project to contain non production ready implementations of specifications</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Improvement</h2>
|
||||||
|
<ul>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-343'>SMACK-343</a>] - Make Smack jar an OSGi bundle.</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-381'>SMACK-381</a>] - Separate the configuration for smack extension related classes from the smack jar.</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-444'>SMACK-444</a>] - Allow 'null' for TruststorePath and TruststorePassword in ServerTrustManager</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-456'>SMACK-456</a>] - Add the causing exception to the XMPPExceptions thrown in XMPPConnection</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-457'>SMACK-457</a>] - Remove unnecessary printStackTrace() in XMPPConnection</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-460'>SMACK-460</a>] - ServiceDiscoveryManager should not use the constructor in connectionCreated()</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-461'>SMACK-461</a>] - Remove incorrect deprecated marker for DiscoverInfo.Identity.setType()</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-464'>SMACK-464</a>] - Make it clear that PacketListener's added with Connection.addPacketListener() are only for received packets</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-534'>SMACK-534</a>] - Convert all System.out and printStackTrace calls to use Java util logging.</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-339'>SMACK-339</a>] - Allow ConnectionListeners to be added before Connection is connected. Currently throws exception</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-373'>SMACK-373</a>] - Don't remove listeners after a disconnect() , keep state of Connection between disconnect() and connect()/login()</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-434'>SMACK-434</a>] - Create a project to contain non production ready implementations of specifications</li>
|
||||||
|
<li>[<a href='http://issues.igniterealtime.org/browse/SMACK-526'>SMACK-526</a>] - Deprecate all PEP related classes.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<h2>3.3.1 -- <span style="font-weight: normal;">Oct 6, 2013</span></h2>
|
<h2>3.3.1 -- <span style="font-weight: normal;">Oct 6, 2013</span></h2>
|
||||||
|
|
||||||
<h2>Bug Fixes</h2>
|
<h2>Bug Fixes</h2>
|
||||||
|
|
|
@ -40,6 +40,37 @@ over which features applications require:
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="subheader">Configuration</p>
|
||||||
|
Smack has an initialization process that involves 2 phases.
|
||||||
|
<ul>
|
||||||
|
<li>Initializing system properties - Initializing all the system properties accessible through the class
|
||||||
|
<b>SmackConfiguration</b>. These properties are retrieve by the <i>getXXX</i> methods on that class.
|
||||||
|
<li>Initializing startup classes - Initializing any classes meant to be active at startup by instantiating
|
||||||
|
the class, and then calling the <i>initialize</i> method on that class if it extends <b>SmackInitializer</b>.
|
||||||
|
If it does not extend this interface, then initialization will have to take place in a static block of code
|
||||||
|
which is automatically executed when the class is loaded.
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Initialization is accomplished via a configuration file. By default, Smack will load the one embedded in
|
||||||
|
the Smack jar at <i>META-INF/smack-config.xml</i>. This particular configuration contains all the default
|
||||||
|
property values as well as a list of initializer classes to load. All manager type classes are contained
|
||||||
|
in this list of initializers. If your application does not use all the features provided by Smack via the
|
||||||
|
aforementioned managers, you may want to 'turn them off' by providing a custom config file that does not
|
||||||
|
include that feature.
|
||||||
|
<p>
|
||||||
|
If you want to change the configuration file used, you have two options:
|
||||||
|
<ul>
|
||||||
|
<li>Programmatically - Call the <i>setConfigFileUrl</i> method of <b>SmackConfiguration</b> with the location
|
||||||
|
of a new config file.
|
||||||
|
<pre>SmackConfiguration.setConfigFileUrl("classpath:test/smack-config.xml", null)</pre>
|
||||||
|
<li>VM Argument - Set the VM argument <i>smack.config.file</i> to the location of a new config file.
|
||||||
|
<pre>-Dsmack.config.file=file:///c:/com/myco/provider/myco_custom_config.xml</pre>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please note, there is a copy of the <b>smack-config.xml</b> in the <i>samples</i> directory of the deployment
|
||||||
|
archive file (zip or tar).
|
||||||
|
|
||||||
<p class="subheader">
|
<p class="subheader">
|
||||||
Establishing a Connection
|
Establishing a Connection
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -15,44 +15,68 @@ Provider Architecture: Packet Extensions and Custom IQ's
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
<p class="subheader">Introduction</p>
|
||||||
|
|
||||||
The Smack provider architecture is a system for plugging in
|
The Smack provider architecture is a system for plugging in
|
||||||
custom XML parsing of packet extensions and IQ packets. The
|
custom XML parsing of packet extensions and IQ packets. The
|
||||||
standard <a href="extensions/index.html">Smack Extensions</a>
|
standard <a href="extensions/index.html">Smack Extensions</a>
|
||||||
are built using the provider architecture. Two types of
|
are built using the provider architecture. There are two types of
|
||||||
providers exist:<ul>
|
providers:<ul>
|
||||||
<li><tt>IQProvider</tt> -- parses IQ requests into Java objects.
|
<li><tt>IQProvider</tt> -- parses IQ requests into Java objects.
|
||||||
<li><tt>PacketExtension</tt> -- parses XML sub-documents attached to
|
<li><tt>Extension Provider</tt> -- parses XML sub-documents attached to
|
||||||
packets into PacketExtension instances.</ul>
|
packets into PacketExtension instances.</ul>
|
||||||
|
|
||||||
<p class="subheader">IQProvider</p>
|
By default, Smack only knows how to process a few standard packets and sub-packets
|
||||||
|
that are in a few namespaces such as:<ul>
|
||||||
By default, Smack only knows how to process IQ packets with sub-packets that
|
|
||||||
are in a few namespaces such as:<ul>
|
|
||||||
<li>jabber:iq:auth
|
<li>jabber:iq:auth
|
||||||
<li>jabber:iq:roster
|
<li>jabber:iq:roster
|
||||||
<li>jabber:iq:register</ul>
|
<li>jabber:iq:register</ul>
|
||||||
|
|
||||||
Because many more IQ types are part of XMPP and its extensions, a pluggable IQ parsing
|
There are many more IQ types and extensions that are part of XMPP standards, and of
|
||||||
mechanism is provided. IQ providers are registered programatically or by creating a
|
course an endless number that can be added as custom extensions. To support this, an
|
||||||
smack.providers file in the META-INF directory of your JAR file. The file is an XML
|
extensible parsing mechanism is provided via Smack and user build providers.
|
||||||
document that contains one or more iqProvider entries, as in the following example:
|
<p>
|
||||||
|
Whenever a packet extension is found in a packet, parsing will
|
||||||
|
be passed to the correct provider. Each provider can either implement the
|
||||||
|
PacketExtensionProvider interface or be a standard Java Bean. In the
|
||||||
|
former case, each extension provider is responsible for parsing the raw
|
||||||
|
XML stream, via the <a href="http://www.xmlpull.org/">XML Pull Parser</a>, to contruct an object. In the latter case, bean introspection
|
||||||
|
is used to try to automatically set the properties of the class using
|
||||||
|
the values in the packet extension sub-element.
|
||||||
|
<p>
|
||||||
|
When no extension provider is registered for an element name and
|
||||||
|
namespace combination, Smack will store all top-level elements of the
|
||||||
|
sub-packet in the DefaultPacketExtension object and then attach it to the packet.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Management of these providers is accomplished via the <a href="">ProviderManager</a>
|
||||||
|
class. There are multiple ways to add providers to the manager.<ul>
|
||||||
|
<li>Call addXXProvider methods - You can call the appropriate add methods directly.
|
||||||
|
<pre>
|
||||||
|
ProviderManager.getInstance().addIQProvider("element", "namespace", new MyIQProvider());
|
||||||
|
ProviderManager.getInstance().addExtensionProvider("element", "namespace", new MyExtProvider());
|
||||||
|
</pre>
|
||||||
|
<li>Add a loader - You can add a ProviderLoader which will inject a means of loading multiple
|
||||||
|
providers (both types) into the manager. This is the mechanism used by Smack to load from the
|
||||||
|
Smack specific file format (via ProviderFileLoader). Implementers can provide the means to load
|
||||||
|
providers from any source they wish, or simply reuse the ProviderFileLoader to load from
|
||||||
|
their own provider files.
|
||||||
|
<pre>
|
||||||
|
ProviderManager.getInstance().addLoader(new ProviderFileLoader(FileUtils.getStreamForUrl("classpath:com/myco/provider/myco_custom.providers", null)));
|
||||||
|
</pre>
|
||||||
|
<li>VM Argument - You can add a provider file via the VM argument <i>smack.provider.file</i>.
|
||||||
|
This will load the file at the specified URL during startup when Smack initializes.
|
||||||
|
This also assumes the default configuration, since it requires that the <b>VmArgInitializer</b> was
|
||||||
|
part of the startup configuration.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<?xml version="1.0"?>
|
-Dsmack.provider.file=classpath:com/myco/provider/myco_custom.providers
|
||||||
<smackProviders>
|
or
|
||||||
<iqProvider>
|
-Dsmack.provider.file=file:///c:/myco/provider/myco_custom.providers
|
||||||
<elementName>query</elementName>
|
</pre>
|
||||||
<namespace>jabber:iq:time</namespace>
|
</ul>
|
||||||
<className>org.jivesoftware.smack.packet.Time</className>
|
|
||||||
</iqProvider>
|
|
||||||
</smackProviders></pre>
|
|
||||||
|
|
||||||
Each IQ provider is associated with an element name and a namespace. In the
|
<p class="subheader">IQ Providers</p>
|
||||||
example above, the element name is <tt>query</tt> and the namespace is
|
|
||||||
<tt>abber:iq:time</tt>. If multiple provider entries attempt to register to
|
|
||||||
handle the same namespace, the first entry loaded from the classpath will
|
|
||||||
take precedence. <p>
|
|
||||||
|
|
||||||
The IQ provider class can either implement the IQProvider
|
The IQ provider class can either implement the IQProvider
|
||||||
interface, or extend the IQ class. In the former case, each IQProvider is
|
interface, or extend the IQ class. In the former case, each IQProvider is
|
||||||
|
@ -61,54 +85,191 @@ the latter case, bean introspection is used to try to automatically set
|
||||||
properties of the IQ instance using the values found in the IQ packet XML.
|
properties of the IQ instance using the values found in the IQ packet XML.
|
||||||
For example, an XMPP time packet resembles the following:
|
For example, an XMPP time packet resembles the following:
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<i>Introspection</i>
|
||||||
|
<p>
|
||||||
|
<u>Time Packet</u>
|
||||||
<pre>
|
<pre>
|
||||||
<iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'>
|
<iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'>
|
||||||
<query xmlns='jabber:iq:time'>
|
<query xmlns='jabber:iq:time'>
|
||||||
<utc>20020910T17:58:35</utc>
|
<utc>20020910T17:58:35</utc>
|
||||||
<tz>MDT</tz>
|
<tz>MDT</tz>
|
||||||
<display>Tue Sep 10 12:58:35 2002</display>
|
<display>Tue Sep 10 12:58:35 2002</display>
|
||||||
</query>
|
</query>
|
||||||
</iq></pre>
|
</iq>
|
||||||
|
</pre>
|
||||||
|
|
||||||
In order for this packet to be automatically mapped to the Time object listed in the
|
<p>
|
||||||
providers file above, it must have the methods setUtc(String), setTz(String), and
|
<u>Time IQ Class</u>
|
||||||
setDisplay(String). The introspection service will automatically try to convert the String
|
<pre>
|
||||||
|
class Time extends IQ {
|
||||||
|
private Date utc;
|
||||||
|
private TimeZone timeZone;
|
||||||
|
private String display;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUtc(String utcString) {
|
||||||
|
try {
|
||||||
|
utc = StringUtils.parseDate(utcString);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZone(String zone) {
|
||||||
|
timeZone = TimeZone.getTimeZone(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplay(String timeDisplay) {
|
||||||
|
display = timeDisplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The introspection service will automatically try to convert the String
|
||||||
value from the XML into a boolean, int, long, float, double, or Class depending on the
|
value from the XML into a boolean, int, long, float, double, or Class depending on the
|
||||||
type the IQ instance expects.<p>
|
type the IQ instance expects.
|
||||||
|
|
||||||
<p class="subheader">PacketExtensionProvider</p>
|
<p>
|
||||||
|
<i>IQProvider Implementation</i>
|
||||||
|
<p>
|
||||||
|
<u>Disco Items Packet</u>
|
||||||
|
<pre>
|
||||||
|
<iq type='result' from='shakespeare.lit' to='romeo@montague.net/orchard' id='items1'>
|
||||||
|
<query xmlns='http://jabber.org/protocol/disco#items'>
|
||||||
|
<item jid='people.shakespeare.lit' name='Directory of Characters'/>
|
||||||
|
<item jid='plays.shakespeare.lit' name='Play-Specific Chatrooms'/>
|
||||||
|
<item jid='mim.shakespeare.lit' name='Gateway to Marlowe IM'/>
|
||||||
|
<item jid='words.shakespeare.lit' name='Shakespearean Lexicon'/>
|
||||||
|
<item jid='globe.shakespeare.lit' name='Calendar of Performances'/>
|
||||||
|
<item jid='headlines.shakespeare.lit' name='Latest Shakespearean News'/>
|
||||||
|
<item jid='catalog.shakespeare.lit' name='Buy Shakespeare Stuff!'/>
|
||||||
|
<item jid='en2fr.shakespeare.lit' name='French Translation Service'/>
|
||||||
|
</query>
|
||||||
|
</iq>
|
||||||
|
</pre>
|
||||||
|
|
||||||
Packet extension providers provide a pluggable system for
|
<p>
|
||||||
packet extensions, which are child elements in a custom namespace
|
<u>Disco Items IQProvider</u>
|
||||||
of IQ, message and presence packets.
|
<pre>
|
||||||
Each extension provider is registered with an element name and namespace
|
public class DiscoverItemsProvider implements IQProvider {
|
||||||
in the smack.providers file as in the following example:
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
DiscoverItems discoverItems = new DiscoverItems();
|
||||||
|
boolean done = false;
|
||||||
|
DiscoverItems.Item item;
|
||||||
|
String jid = "";
|
||||||
|
String name = "";
|
||||||
|
String action = "";
|
||||||
|
String node = "";
|
||||||
|
discoverItems.setNode(parser.getAttributeValue("", "node"));
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
|
||||||
|
if (eventType == XmlPullParser.START_TAG && "item".equals(parser.getName())) {
|
||||||
|
// Initialize the variables from the parsed XML
|
||||||
|
jid = parser.getAttributeValue("", "jid");
|
||||||
|
name = parser.getAttributeValue("", "name");
|
||||||
|
node = parser.getAttributeValue("", "node");
|
||||||
|
action = parser.getAttributeValue("", "action");
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "item".equals(parser.getName())) {
|
||||||
|
// Create a new Item and add it to DiscoverItems.
|
||||||
|
item = new DiscoverItems.Item(jid);
|
||||||
|
item.setName(name);
|
||||||
|
item.setNode(node);
|
||||||
|
item.setAction(action);
|
||||||
|
discoverItems.addItem(item);
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && "query".equals(parser.getName())) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return discoverItems;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p class="subheader">Extension Providers</p>
|
||||||
|
|
||||||
|
Packet extension providers are responsible for parsing packet extensions, which are
|
||||||
|
child elements in a custom namespace of IQ, message and presence packets.
|
||||||
|
<p>
|
||||||
|
<u>Pubsub Subscription Packet</u>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<?xml version="1.0"?>
|
<iq type='result' from='pubsub.shakespeare.lit' to='francisco@denmark.lit/barracks' id='sub1'>
|
||||||
<smackProviders>
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
||||||
|
<subscription node='princely_musings' jid='francisco@denmark.lit' subscription='unconfigured'>
|
||||||
|
<subscribe-options>
|
||||||
|
<required/>
|
||||||
|
</subscribe-options>
|
||||||
|
</subscription>
|
||||||
|
</pubsub>
|
||||||
|
</iq>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<u>Subscription PacketExtensionProvider Implementation</u>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
public class SubscriptionProvider implements PacketExtensionProvider {
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
String jid = parser.getAttributeValue(null, "jid");
|
||||||
|
String nodeId = parser.getAttributeValue(null, "node");
|
||||||
|
String subId = parser.getAttributeValue(null, "subid");
|
||||||
|
String state = parser.getAttributeValue(null, "subscription");
|
||||||
|
boolean isRequired = false;
|
||||||
|
|
||||||
|
int tag = parser.next();
|
||||||
|
|
||||||
|
if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("subscribe-options")) {
|
||||||
|
tag = parser.next();
|
||||||
|
|
||||||
|
if ((tag == XmlPullParser.START_TAG) && parser.getName().equals("required"))
|
||||||
|
isRequired = true;
|
||||||
|
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG && parser.getName() != "subscribe-options");
|
||||||
|
}
|
||||||
|
while (parser.getEventType() != XmlPullParser.END_TAG) parser.next();
|
||||||
|
return new Subscription(jid, nodeId, subId, (state == null ? null : Subscription.State.valueOf(state)), isRequired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p class="subheader">Provider file format</p>
|
||||||
|
|
||||||
|
This is the format for a provider file which can be parsed by the <b>ProviderFileLoader</b>.
|
||||||
|
<pre>
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<smackProviders>
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>query</elementName>
|
||||||
|
<namespace>jabber:iq:time</namespace>
|
||||||
|
<className>org.jivesoftware.smack.packet.Time</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>query</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/disco#items</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.provider.DiscoverItemsProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
<extensionProvider>
|
<extensionProvider>
|
||||||
<elementName>x</elementName>
|
<elementName>subscription</elementName>
|
||||||
<namespace>jabber:iq:event</namespace>
|
<namespace>http://jabber.org/protocol/pubsub</namespace>
|
||||||
<className>org.jivesoftware.smack.packet.MessageEvent</className>
|
<className>org.jivesoftware.smackx.pubsub.provider.SubscriptionProvider</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
</smackProviders></pre>
|
</smackProviders></pre>
|
||||||
|
|
||||||
If multiple provider entries attempt to register to handle the same element
|
Each provider is associated with an element name and a namespace. If multiple provider entries attempt to register to
|
||||||
name and namespace, the first entry loaded from the classpath will take
|
handle the same namespace, the last entry added to the <b>ProviderManager</b> will overwrite any other that was loaded
|
||||||
precedence.<p>
|
before it.
|
||||||
|
<p>
|
||||||
|
|
||||||
Whenever a packet extension is found in a packet, parsing will
|
|
||||||
be passed to the correct provider. Each provider can either implement the
|
|
||||||
PacketExtensionProvider interface or be a standard Java Bean. In the
|
|
||||||
former case, each extension provider is responsible for parsing the raw
|
|
||||||
XML stream to contruct an object. In the latter case, bean introspection
|
|
||||||
is used to try to automatically set the properties of the class using
|
|
||||||
the values in the packet extension sub-element.<p>
|
|
||||||
|
|
||||||
When an extension provider is not registered for an element name and
|
|
||||||
namespace combination, Smack will store all top-level elements of the
|
|
||||||
sub-packet in DefaultPacketExtension object and then attach it to the packet.
|
|
||||||
|
|
||||||
|
|
||||||
<br clear="all" /><br><br>
|
<br clear="all" /><br><br>
|
||||||
|
|
17
experimental/resources/META-INF/experimental.providers
Normal file
17
experimental/resources/META-INF/experimental.providers
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Providers for workgroup extensions -->
|
||||||
|
<smackProviders>
|
||||||
|
|
||||||
|
<!-- XEP-0280 Message Carbons -->
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>sent</elementName>
|
||||||
|
<namespace>urn:xmpp:carbons:2</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.carbons.provider.CarbonManagerProvider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>received</elementName>
|
||||||
|
<namespace>urn:xmpp:carbons:2</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.carbons.provider.CarbonManagerProvider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
</smackProviders>
|
117
experimental/source/org/jivesoftware/smackx/carbons/Carbon.java
Normal file
117
experimental/source/org/jivesoftware/smackx/carbons/Carbon.java
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.carbons;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for XEP-0280: Message Carbons. The extension
|
||||||
|
* <a href="http://xmpp.org/extensions/xep-0280.html">XEP-0280</a> is
|
||||||
|
* meant to synchronize a message flow to multiple presences of a user.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It accomplishes this by wrapping a {@link Forwarded} packet in a <b>sent</b>
|
||||||
|
* or <b>received</b> element
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class Carbon implements PacketExtension {
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:carbons:2";
|
||||||
|
|
||||||
|
private Direction dir;
|
||||||
|
private Forwarded fwd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Carbon message extension.
|
||||||
|
*
|
||||||
|
* @param dir Determines if the carbon is being sent/received
|
||||||
|
* @param fwd The forwarded message.
|
||||||
|
*/
|
||||||
|
public Carbon(Direction dir, Forwarded fwd) {
|
||||||
|
this.dir = dir;
|
||||||
|
this.fwd = fwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the direction (sent or received) of the carbon.
|
||||||
|
*
|
||||||
|
* @return the {@link Direction} of the carbon.
|
||||||
|
*/
|
||||||
|
public Direction getDirection() {
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the forwarded packet.
|
||||||
|
*
|
||||||
|
* @return the {@link Forwarded} message contained in this Carbon.
|
||||||
|
*/
|
||||||
|
public Forwarded getForwarded() {
|
||||||
|
return fwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return dir.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(getElementName()).append(" xmlns=\"")
|
||||||
|
.append(getNamespace()).append("\">");
|
||||||
|
|
||||||
|
buf.append(fwd.toXML());
|
||||||
|
|
||||||
|
buf.append("</").append(getElementName()).append(">");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the direction of a {@link Carbon} message.
|
||||||
|
*/
|
||||||
|
public static enum Direction {
|
||||||
|
received,
|
||||||
|
sent
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension indicating that a message may not be carbon-copied. Adding this
|
||||||
|
* extension to any message will disallow that message from being copied.
|
||||||
|
*/
|
||||||
|
public static class Private implements PacketExtension {
|
||||||
|
public static final String ELEMENT = "private";
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return Carbon.NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toXML() {
|
||||||
|
return "<" + ELEMENT + " xmlns=\"" + Carbon.NAMESPACE + "\"/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.carbons;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.Connection;
|
||||||
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.PacketListener;
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for XEP-0280: Message Carbons. This class implements
|
||||||
|
* the manager for registering {@link Carbon} support, enabling and disabling
|
||||||
|
* message carbons.
|
||||||
|
*
|
||||||
|
* You should call enableCarbons() before sending your first undirected
|
||||||
|
* presence.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class CarbonManager {
|
||||||
|
|
||||||
|
private static Map<Connection, CarbonManager> instances =
|
||||||
|
Collections.synchronizedMap(new WeakHashMap<Connection, CarbonManager>());
|
||||||
|
|
||||||
|
static {
|
||||||
|
Connection.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
public void connectionCreated(Connection connection) {
|
||||||
|
new CarbonManager(connection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
private volatile boolean enabled_state = false;
|
||||||
|
|
||||||
|
private CarbonManager(Connection connection) {
|
||||||
|
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
|
sdm.addFeature(Carbon.NAMESPACE);
|
||||||
|
this.connection = connection;
|
||||||
|
instances.put(connection, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the CarbonManager responsible for a connection.
|
||||||
|
*
|
||||||
|
* @param connection the connection object.
|
||||||
|
*
|
||||||
|
* @return a CarbonManager instance
|
||||||
|
*/
|
||||||
|
public static CarbonManager getInstanceFor(Connection connection) {
|
||||||
|
CarbonManager carbonManager = instances.get(connection);
|
||||||
|
|
||||||
|
if (carbonManager == null) {
|
||||||
|
carbonManager = new CarbonManager(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return carbonManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IQ carbonsEnabledIQ(final boolean new_state) {
|
||||||
|
IQ setIQ = new IQ() {
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return "<" + (new_state? "enable" : "disable") + " xmlns='" + Carbon.NAMESPACE + "'/>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setIQ.setType(IQ.Type.SET);
|
||||||
|
return setIQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if XMPP Carbons are supported by the server.
|
||||||
|
*
|
||||||
|
* @return true if supported
|
||||||
|
*/
|
||||||
|
public boolean isSupportedByServer() {
|
||||||
|
try {
|
||||||
|
DiscoverInfo result = ServiceDiscoveryManager
|
||||||
|
.getInstanceFor(connection).discoverInfo(connection.getServiceName());
|
||||||
|
return result.containsFeature(Carbon.NAMESPACE);
|
||||||
|
}
|
||||||
|
catch (XMPPException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify server to change the carbons state. This method returns
|
||||||
|
* immediately and changes the variable when the reply arrives.
|
||||||
|
*
|
||||||
|
* You should first check for support using isSupportedByServer().
|
||||||
|
*
|
||||||
|
* @param new_state whether carbons should be enabled or disabled
|
||||||
|
*/
|
||||||
|
public void sendCarbonsEnabled(final boolean new_state) {
|
||||||
|
IQ setIQ = carbonsEnabledIQ(new_state);
|
||||||
|
|
||||||
|
connection.addPacketListener(new PacketListener() {
|
||||||
|
public void processPacket(Packet packet) {
|
||||||
|
IQ result = (IQ)packet;
|
||||||
|
if (result.getType() == IQ.Type.RESULT) {
|
||||||
|
enabled_state = new_state;
|
||||||
|
}
|
||||||
|
connection.removePacketListener(this);
|
||||||
|
}
|
||||||
|
}, new PacketIDFilter(setIQ.getPacketID()));
|
||||||
|
|
||||||
|
connection.sendPacket(setIQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify server to change the carbons state. This method blocks
|
||||||
|
* some time until the server replies to the IQ and returns true on
|
||||||
|
* success.
|
||||||
|
*
|
||||||
|
* You should first check for support using isSupportedByServer().
|
||||||
|
*
|
||||||
|
* @param new_state whether carbons should be enabled or disabled
|
||||||
|
*
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
public boolean setCarbonsEnabled(final boolean new_state) {
|
||||||
|
if (enabled_state == new_state)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
IQ setIQ = carbonsEnabledIQ(new_state);
|
||||||
|
|
||||||
|
PacketCollector collector =
|
||||||
|
connection.createPacketCollector(new PacketIDFilter(setIQ.getPacketID()));
|
||||||
|
connection.sendPacket(setIQ);
|
||||||
|
IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
collector.cancel();
|
||||||
|
|
||||||
|
if (result != null && result.getType() == IQ.Type.RESULT) {
|
||||||
|
enabled_state = new_state;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to enable carbons.
|
||||||
|
*
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
public boolean enableCarbons() {
|
||||||
|
return setCarbonsEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to disable carbons.
|
||||||
|
*
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
public boolean disableCarbons() {
|
||||||
|
return setCarbonsEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if carbons are enabled on this connection.
|
||||||
|
*/
|
||||||
|
public boolean getCarbonsEnabled() {
|
||||||
|
return this.enabled_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a Carbon from a message, if available.
|
||||||
|
*
|
||||||
|
* @param msg Message object to check for carbons
|
||||||
|
*
|
||||||
|
* @return a Carbon if available, null otherwise.
|
||||||
|
*/
|
||||||
|
public static Carbon getCarbon(Message msg) {
|
||||||
|
Carbon cc = (Carbon)msg.getExtension("received", Carbon.NAMESPACE);
|
||||||
|
if (cc == null)
|
||||||
|
cc = (Carbon)msg.getExtension("sent", Carbon.NAMESPACE);
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a message as "private", so it will not be carbon-copied.
|
||||||
|
*
|
||||||
|
* @param msg Message object to mark private
|
||||||
|
*/
|
||||||
|
public static void disableCarbons(Message msg) {
|
||||||
|
msg.addExtension(new Carbon.Private());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.carbons.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.jivesoftware.smackx.carbons.Carbon;
|
||||||
|
import org.jivesoftware.smackx.carbons.Carbon.Direction;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the {@link PacketExtensionProvider} to parse
|
||||||
|
* cabon copied messages from a packet. It will return a {@link Carbon} packet extension.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CarbonManagerProvider implements PacketExtensionProvider {
|
||||||
|
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
Direction dir = Direction.valueOf(parser.getName());
|
||||||
|
Forwarded fwd = null;
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG && parser.getName().equals("forwarded")) {
|
||||||
|
fwd = (Forwarded) PacketParserUtils.parsePacketExtension(Forwarded.ELEMENT_NAME, Forwarded.NAMESPACE, parser);
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && dir == Direction.valueOf(parser.getName()))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
if (fwd == null)
|
||||||
|
throw new Exception("sent/received must contain exactly one <forwarded> tag");
|
||||||
|
return new Carbon(dir, fwd);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Robin Collier
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.experimental;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.provider.UrlProviderFileInitializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the providers in the experimental code stream.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExperimentalProviderInitializer extends UrlProviderFileInitializer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFilePath() {
|
||||||
|
return "classpath:META-INF/experimental.providers";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/**
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.carbons;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
|
import org.jivesoftware.smackx.carbons.provider.CarbonManagerProvider;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
import org.jivesoftware.smackx.forward.provider.ForwardedProvider;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import com.jamesmurty.utils.XMLBuilder;
|
||||||
|
|
||||||
|
public class CarbonTest {
|
||||||
|
|
||||||
|
private static Properties outputProperties = new Properties();
|
||||||
|
static {
|
||||||
|
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
ProviderManager.getInstance().addExtensionProvider("forwarded", "urn:xmpp:forward:0", new ForwardedProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void carbonSentTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
Carbon cc;
|
||||||
|
Forwarded fwd;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("sent")
|
||||||
|
.e("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.e("message")
|
||||||
|
.a("from", "romeo@montague.com")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = TestUtils.getParser(control, "sent");
|
||||||
|
cc = (Carbon) new CarbonManagerProvider().parseExtension(parser);
|
||||||
|
fwd = cc.getForwarded();
|
||||||
|
|
||||||
|
// meta
|
||||||
|
assertEquals(Carbon.Direction.sent, cc.getDirection());
|
||||||
|
|
||||||
|
// no delay in packet
|
||||||
|
assertEquals(null, fwd.getDelayInfo());
|
||||||
|
|
||||||
|
// check message
|
||||||
|
assertEquals("romeo@montague.com", fwd.getForwardedPacket().getFrom());
|
||||||
|
|
||||||
|
// check end of tag
|
||||||
|
assertEquals(XmlPullParser.END_TAG, parser.getEventType());
|
||||||
|
assertEquals("sent", parser.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void carbonReceivedTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
Carbon cc;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("received")
|
||||||
|
.e("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.e("message")
|
||||||
|
.a("from", "romeo@montague.com")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = TestUtils.getParser(control, "received");
|
||||||
|
cc = (Carbon) new CarbonManagerProvider().parseExtension(parser);
|
||||||
|
|
||||||
|
assertEquals(Carbon.Direction.received, cc.getDirection());
|
||||||
|
|
||||||
|
// check end of tag
|
||||||
|
assertEquals(XmlPullParser.END_TAG, parser.getEventType());
|
||||||
|
assertEquals("received", parser.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=Exception.class)
|
||||||
|
public void carbonEmptyTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("sent")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = TestUtils.getParser(control, "sent");
|
||||||
|
new CarbonManagerProvider().parseExtension(parser);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,8 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows creation and management of accounts on an XMPP server.
|
* Allows creation and management of accounts on an XMPP server.
|
||||||
|
@ -40,6 +42,7 @@ import java.util.Map;
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
*/
|
*/
|
||||||
public class AccountManager {
|
public class AccountManager {
|
||||||
|
private static Logger logger = Logger.getLogger(AccountManager.class.getName());
|
||||||
|
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
private Registration info = null;
|
private Registration info = null;
|
||||||
|
@ -134,7 +137,7 @@ public class AccountManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (XMPPException xe) {
|
catch (XMPPException xe) {
|
||||||
xe.printStackTrace();
|
logger.log(Level.SEVERE, "Error retrieving account attributes from server", xe);
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
@ -155,7 +158,7 @@ public class AccountManager {
|
||||||
return info.getAttributes().get(name);
|
return info.getAttributes().get(name);
|
||||||
}
|
}
|
||||||
catch (XMPPException xe) {
|
catch (XMPPException xe) {
|
||||||
xe.printStackTrace();
|
logger.log(Level.SEVERE, "Error retrieving account attribute " + name + " info from server", xe);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +178,7 @@ public class AccountManager {
|
||||||
return info.getInstructions();
|
return info.getInstructions();
|
||||||
}
|
}
|
||||||
catch (XMPPException xe) {
|
catch (XMPPException xe) {
|
||||||
|
logger.log(Level.SEVERE, "Error retrieving account instructions from server", xe);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,6 +170,18 @@ public class Chat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Chat [(participant=" + participant + "), (thread=" + threadID + ")]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 1;
|
||||||
|
hash = hash * 31 + threadID.hashCode();
|
||||||
|
hash = hash * 31 + participant.hashCode();
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
@ -33,38 +34,58 @@ import org.jivesoftware.smack.filter.PacketFilter;
|
||||||
import org.jivesoftware.smack.filter.ThreadFilter;
|
import org.jivesoftware.smack.filter.ThreadFilter;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.packet.Message.Type;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smack.util.collections.ReferenceMap;
|
import org.jivesoftware.smack.util.collections.ReferenceMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The chat manager keeps track of references to all current chats. It will not hold any references
|
* The chat manager keeps track of references to all current chats. It will not hold any references
|
||||||
* in memory on its own so it is neccesary to keep a reference to the chat object itself. To be
|
* in memory on its own so it is necessary to keep a reference to the chat object itself. To be
|
||||||
* made aware of new chats, register a listener by calling {@link #addChatListener(ChatManagerListener)}.
|
* made aware of new chats, register a listener by calling {@link #addChatListener(ChatManagerListener)}.
|
||||||
*
|
*
|
||||||
* @author Alexander Wenckus
|
* @author Alexander Wenckus
|
||||||
*/
|
*/
|
||||||
public class ChatManager {
|
public class ChatManager {
|
||||||
|
/*
|
||||||
|
* Sets the default behaviour for allowing 'normal' messages to be used in chats. As some clients don't set
|
||||||
|
* the message type to chat, the type normal has to be accepted to allow chats with these clients.
|
||||||
|
*/
|
||||||
|
private static boolean defaultIsNormalInclude = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the default behaviour for how to match chats when there is NO thread id in the incoming message.
|
||||||
|
*/
|
||||||
|
private static MatchMode defaultMatchMode = MatchMode.BARE_JID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next unique id. Each id made up of a short alphanumeric
|
* Defines the different modes under which a match will be attempted with an existing chat when
|
||||||
* prefix along with a unique numeric value.
|
* the incoming message does not have a thread id.
|
||||||
*
|
|
||||||
* @return the next id.
|
|
||||||
*/
|
*/
|
||||||
private static synchronized String nextID() {
|
public enum MatchMode {
|
||||||
return prefix + Long.toString(id++);
|
/**
|
||||||
|
* Will not attempt to match, always creates a new chat.
|
||||||
|
*/
|
||||||
|
NONE,
|
||||||
|
/**
|
||||||
|
* Will match on the JID in the from field of the message.
|
||||||
|
*/
|
||||||
|
SUPPLIED_JID,
|
||||||
|
/**
|
||||||
|
* Will attempt to match on the JID in the from field, and then attempt the base JID if no match was found.
|
||||||
|
* This is the most lenient matching.
|
||||||
|
*/
|
||||||
|
BARE_JID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* A prefix helps to make sure that ID's are unique across mutliple instances.
|
* Determines whether incoming messages of type normal can create chats.
|
||||||
*/
|
*/
|
||||||
private static String prefix = StringUtils.randomString(5);
|
private boolean normalIncluded = defaultIsNormalInclude;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Keeps track of the current increment, which is appended to the prefix to
|
* Determines how incoming message with no thread will be matched to existing chats.
|
||||||
* forum a unique ID.
|
|
||||||
*/
|
*/
|
||||||
private static long id = 0;
|
private MatchMode matchMode = defaultMatchMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps thread ID to chat.
|
* Maps thread ID to chat.
|
||||||
|
@ -101,11 +122,11 @@ public class ChatManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Message.Type messageType = ((Message) packet).getType();
|
Message.Type messageType = ((Message) packet).getType();
|
||||||
return messageType != Message.Type.groupchat &&
|
return (messageType == Type.chat) || (normalIncluded ? messageType == Type.normal : false);
|
||||||
messageType != Message.Type.headline;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Add a listener for all message packets so that we can deliver errant
|
|
||||||
|
// Add a listener for all message packets so that we can deliver
|
||||||
// messages to the best Chat instance available.
|
// messages to the best Chat instance available.
|
||||||
connection.addPacketListener(new PacketListener() {
|
connection.addPacketListener(new PacketListener() {
|
||||||
public void processPacket(Packet packet) {
|
public void processPacket(Packet packet) {
|
||||||
|
@ -116,10 +137,6 @@ public class ChatManager {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
chat = getThreadChat(message.getThread());
|
chat = getThreadChat(message.getThread());
|
||||||
if (chat == null) {
|
|
||||||
// Try to locate the chat based on the sender of the message
|
|
||||||
chat = getUserChat(message.getFrom());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chat == null) {
|
if(chat == null) {
|
||||||
|
@ -130,6 +147,44 @@ public class ChatManager {
|
||||||
}, filter);
|
}, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether incoming messages of type <i>normal</i> will be used for creating new chats or matching
|
||||||
|
* a message to existing ones.
|
||||||
|
*
|
||||||
|
* @return true if normal is allowed, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isNormalIncluded() {
|
||||||
|
return normalIncluded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to allow incoming messages of type <i>normal</i> to be used for creating new chats or matching
|
||||||
|
* a message to an existing one.
|
||||||
|
*
|
||||||
|
* @param normalIncluded true to allow normal, false otherwise.
|
||||||
|
*/
|
||||||
|
public void setNormalIncluded(boolean normalIncluded) {
|
||||||
|
this.normalIncluded = normalIncluded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current mode for matching messages with <b>NO</b> thread id to existing chats.
|
||||||
|
*
|
||||||
|
* @return The current mode.
|
||||||
|
*/
|
||||||
|
public MatchMode getMatchMode() {
|
||||||
|
return matchMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the mode for matching messages with <b>NO</b> thread id to existing chats.
|
||||||
|
*
|
||||||
|
* @param matchMode The mode to set.
|
||||||
|
*/
|
||||||
|
public void setMatchMode(MatchMode matchMode) {
|
||||||
|
this.matchMode = matchMode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new chat and returns it.
|
* Creates a new chat and returns it.
|
||||||
*
|
*
|
||||||
|
@ -138,12 +193,7 @@ public class ChatManager {
|
||||||
* @return the created chat.
|
* @return the created chat.
|
||||||
*/
|
*/
|
||||||
public Chat createChat(String userJID, MessageListener listener) {
|
public Chat createChat(String userJID, MessageListener listener) {
|
||||||
String threadID;
|
return createChat(userJID, null, listener);
|
||||||
do {
|
|
||||||
threadID = nextID();
|
|
||||||
} while (threadChats.get(threadID) != null);
|
|
||||||
|
|
||||||
return createChat(userJID, threadID, listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,7 +205,7 @@ public class ChatManager {
|
||||||
* @return the created chat.
|
* @return the created chat.
|
||||||
*/
|
*/
|
||||||
public Chat createChat(String userJID, String thread, MessageListener listener) {
|
public Chat createChat(String userJID, String thread, MessageListener listener) {
|
||||||
if(thread == null) {
|
if (thread == null) {
|
||||||
thread = nextID();
|
thread = nextID();
|
||||||
}
|
}
|
||||||
Chat chat = threadChats.get(thread);
|
Chat chat = threadChats.get(thread);
|
||||||
|
@ -191,17 +241,22 @@ public class ChatManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to get a matching chat for the given user JID. Try the full
|
* Try to get a matching chat for the given user JID, based on the {@link MatchMode}.
|
||||||
* JID map first, the try to match on the base JID if no match is
|
* <li>NONE - return null
|
||||||
* found.
|
* <li>SUPPLIED_JID - match the jid in the from field of the message exactly.
|
||||||
|
* <li>BARE_JID - if not match for from field, try the bare jid.
|
||||||
*
|
*
|
||||||
* @param userJID
|
* @param userJID jid in the from field of message.
|
||||||
* @return
|
* @return Matching chat, or null if no match found.
|
||||||
*/
|
*/
|
||||||
private Chat getUserChat(String userJID) {
|
private Chat getUserChat(String userJID) {
|
||||||
|
if (matchMode == MatchMode.NONE) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Chat match = jidChats.get(userJID);
|
Chat match = jidChats.get(userJID);
|
||||||
|
|
||||||
if (match == null) {
|
if (match == null && (matchMode == MatchMode.BARE_JID)) {
|
||||||
match = baseJidChats.get(StringUtils.parseBareAddress(userJID));
|
match = baseJidChats.get(StringUtils.parseBareAddress(userJID));
|
||||||
}
|
}
|
||||||
return match;
|
return match;
|
||||||
|
@ -278,4 +333,21 @@ public class ChatManager {
|
||||||
interceptors.put(packetInterceptor, filter);
|
interceptors.put(packetInterceptor, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a unique id.
|
||||||
|
*
|
||||||
|
* @return the next id.
|
||||||
|
*/
|
||||||
|
private static String nextID() {
|
||||||
|
return UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefaultMatchMode(MatchMode mode) {
|
||||||
|
defaultMatchMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefaultIsNormalIncluded(boolean allowNormal) {
|
||||||
|
defaultIsNormalInclude = allowNormal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.compression.JzlibInputOutputStream;
|
import org.jivesoftware.smack.compression.JzlibInputOutputStream;
|
||||||
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
||||||
|
@ -83,6 +84,7 @@ import org.jivesoftware.smack.packet.Presence;
|
||||||
* @author Guenther Niess
|
* @author Guenther Niess
|
||||||
*/
|
*/
|
||||||
public abstract class Connection {
|
public abstract class Connection {
|
||||||
|
private static Logger log = Logger.getLogger(Connection.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counter to uniquely identify connections that are created.
|
* Counter to uniquely identify connections that are created.
|
||||||
|
@ -593,10 +595,14 @@ public abstract class Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a packet listener with this connection. A packet filter determines
|
* Registers a packet listener with this connection. A packet listener will be invoked only
|
||||||
|
* when an incoming packet is received. A packet filter determines
|
||||||
* which packets will be delivered to the listener. If the same packet listener
|
* which packets will be delivered to the listener. If the same packet listener
|
||||||
* is added again with a different filter, only the new filter will be used.
|
* is added again with a different filter, only the new filter will be used.
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* NOTE: If you want get a similar callback for outgoing packets, see {@link #addPacketInterceptor(PacketInterceptor, PacketFilter)}.
|
||||||
|
*
|
||||||
* @param packetListener the packet listener to notify of new received packets.
|
* @param packetListener the packet listener to notify of new received packets.
|
||||||
* @param packetFilter the packet filter to use.
|
* @param packetFilter the packet filter to use.
|
||||||
*/
|
*/
|
||||||
|
@ -682,6 +688,9 @@ public abstract class Connection {
|
||||||
* may modify the packet to be sent. A packet filter determines which packets
|
* may modify the packet to be sent. A packet filter determines which packets
|
||||||
* will be delivered to the interceptor.
|
* will be delivered to the interceptor.
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* NOTE: For a similar functionality on incoming packets, see {@link #addPacketListener(PacketListener, PacketFilter)}.
|
||||||
|
*
|
||||||
* @param packetInterceptor the packet interceptor to notify of packets about to be sent.
|
* @param packetInterceptor the packet interceptor to notify of packets about to be sent.
|
||||||
* @param packetFilter the packet filter to use.
|
* @param packetFilter the packet filter to use.
|
||||||
*/
|
*/
|
||||||
|
@ -757,7 +766,7 @@ public abstract class Connection {
|
||||||
debuggerClass = Class.forName(className);
|
debuggerClass = Class.forName(className);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warning("Unabled to instantiate debugger class " + className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debuggerClass == null) {
|
if (debuggerClass == null) {
|
||||||
|
@ -771,7 +780,7 @@ public abstract class Connection {
|
||||||
Class.forName("org.jivesoftware.smack.debugger.LiteDebugger");
|
Class.forName("org.jivesoftware.smack.debugger.LiteDebugger");
|
||||||
}
|
}
|
||||||
catch (Exception ex2) {
|
catch (Exception ex2) {
|
||||||
ex2.printStackTrace();
|
log.warning("Unabled to instantiate either Smack debugger class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
source/org/jivesoftware/smack/LoggingInitializer.java
Normal file
28
source/org/jivesoftware/smack/LoggingInitializer.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package org.jivesoftware.smack;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.LogManager;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Java logging system.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LoggingInitializer implements SmackInitializer {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(LoggingInitializer.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
try {
|
||||||
|
LogManager.getLogManager().readConfiguration(FileUtils.getStreamForUrl("classpath:META-INF/jul.properties", null));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log .log(Level.WARNING, "Could not initialize Java Logging from default file.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,8 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for XML traffic from the XMPP server and parses it into packet objects.
|
* Listens for XML traffic from the XMPP server and parses it into packet objects.
|
||||||
|
@ -45,6 +47,8 @@ import java.util.concurrent.*;
|
||||||
*/
|
*/
|
||||||
class PacketReader {
|
class PacketReader {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(PacketReader.class.getName());
|
||||||
|
|
||||||
private Thread readerThread;
|
private Thread readerThread;
|
||||||
private ExecutorService listenerExecutor;
|
private ExecutorService listenerExecutor;
|
||||||
|
|
||||||
|
@ -134,7 +138,7 @@ class PacketReader {
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
// Catch and print any exception so we can recover
|
// Catch and print any exception so we can recover
|
||||||
// from a faulty listener and finish the shutdown process
|
// from a faulty listener and finish the shutdown process
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error in listener while closing connection", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +160,7 @@ class PacketReader {
|
||||||
parser.setInput(connection.reader);
|
parser.setInput(connection.reader);
|
||||||
}
|
}
|
||||||
catch (XmlPullParserException xppe) {
|
catch (XmlPullParserException xppe) {
|
||||||
xppe.printStackTrace();
|
log.log(Level.WARNING, "Error while resetting parser", xppe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,8 +455,7 @@ class PacketReader {
|
||||||
try {
|
try {
|
||||||
listenerWrapper.notifyListener(packet);
|
listenerWrapper.notifyListener(packet);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("Exception in packet listener: " + e);
|
log.log(Level.SEVERE, "Exception in packet listener", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes packets to a XMPP server. Packets are sent using a dedicated thread. Packet
|
* Writes packets to a XMPP server. Packets are sent using a dedicated thread. Packet
|
||||||
|
@ -38,6 +40,7 @@ import java.util.concurrent.BlockingQueue;
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
*/
|
*/
|
||||||
class PacketWriter {
|
class PacketWriter {
|
||||||
|
private static Logger log = Logger.getLogger(PacketWriter.class.getName());
|
||||||
|
|
||||||
private Thread writerThread;
|
private Thread writerThread;
|
||||||
private Writer writer;
|
private Writer writer;
|
||||||
|
@ -88,7 +91,7 @@ class PacketWriter {
|
||||||
queue.put(packet);
|
queue.put(packet);
|
||||||
}
|
}
|
||||||
catch (InterruptedException ie) {
|
catch (InterruptedException ie) {
|
||||||
ie.printStackTrace();
|
log.log(Level.SEVERE, "Failed to queue packet to send to server: " + packet.toString(), ie);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
synchronized (queue) {
|
synchronized (queue) {
|
||||||
|
@ -172,7 +175,7 @@ class PacketWriter {
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warning("Error flushing queue during shutdown, ignore and continue");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the queue contents (hopefully nothing is left).
|
// Delete the queue contents (hopefully nothing is left).
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smack;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.StreamError;
|
import org.jivesoftware.smack.packet.StreamError;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.logging.Logger;
|
||||||
/**
|
/**
|
||||||
* Handles the automatic reconnection process. Every time a connection is dropped without
|
* Handles the automatic reconnection process. Every time a connection is dropped without
|
||||||
* the application explictly closing it, the manager automatically tries to reconnect to
|
* the application explictly closing it, the manager automatically tries to reconnect to
|
||||||
|
@ -34,6 +35,7 @@ import java.util.Random;
|
||||||
* @author Francisco Vives
|
* @author Francisco Vives
|
||||||
*/
|
*/
|
||||||
public class ReconnectionManager implements ConnectionListener {
|
public class ReconnectionManager implements ConnectionListener {
|
||||||
|
private static Logger log = Logger.getLogger(ReconnectionManager.class.getName());
|
||||||
|
|
||||||
// Holds the connection to the server
|
// Holds the connection to the server
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
@ -133,7 +135,7 @@ public class ReconnectionManager implements ConnectionListener {
|
||||||
.notifyAttemptToReconnectIn(remainingSeconds);
|
.notifyAttemptToReconnectIn(remainingSeconds);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e1) {
|
catch (InterruptedException e1) {
|
||||||
e1.printStackTrace();
|
log.warning("Sleeping thread interrupted");
|
||||||
// Notify the reconnection has failed
|
// Notify the reconnection has failed
|
||||||
ReconnectionManager.this.notifyReconnectionFailed(e1);
|
ReconnectionManager.this.notifyReconnectionFailed(e1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateParsingException;
|
import java.security.cert.CertificateParsingException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ import java.util.regex.Pattern;
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
class ServerTrustManager implements X509TrustManager {
|
class ServerTrustManager implements X509TrustManager {
|
||||||
|
private static Logger log = Logger.getLogger(ServerTrustManager.class.getName());
|
||||||
|
|
||||||
private static Pattern cnPattern = Pattern.compile("(?i)(cn=)([^,]*)");
|
private static Pattern cnPattern = Pattern.compile("(?i)(cn=)([^,]*)");
|
||||||
|
|
||||||
|
@ -153,8 +155,7 @@ class ServerTrustManager implements X509TrustManager {
|
||||||
trusted = trustStore.getCertificateAlias(x509Certificates[nSize - 1]) != null;
|
trusted = trustStore.getCertificateAlias(x509Certificates[nSize - 1]) != null;
|
||||||
if (!trusted && nSize == 1 && configuration.isSelfSignedCertificateEnabled())
|
if (!trusted && nSize == 1 && configuration.isSelfSignedCertificateEnabled())
|
||||||
{
|
{
|
||||||
System.out.println("Accepting self-signed certificate of remote server: " +
|
log.info("Accepting self-signed certificate of remote server: " + peerIdentities);
|
||||||
peerIdentities);
|
|
||||||
trusted = true;
|
trusted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +269,7 @@ class ServerTrustManager implements X509TrustManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Other types are not good for XMPP so ignore them
|
// Other types are not good for XMPP so ignore them
|
||||||
System.out.println("SubjectAltName of invalid type found: " + certificate);
|
log.info("SubjectAltName of invalid type found: " + certificate);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
catch (CertificateParsingException e) {
|
catch (CertificateParsingException e) {
|
||||||
|
|
|
@ -20,16 +20,18 @@
|
||||||
|
|
||||||
package org.jivesoftware.smack;
|
package org.jivesoftware.smack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Enumeration;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.parsing.ExceptionThrowingCallback;
|
import org.jivesoftware.smack.parsing.ExceptionThrowingCallback;
|
||||||
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
||||||
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
import org.xmlpull.mxp1.MXParser;
|
import org.xmlpull.mxp1.MXParser;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
@ -49,17 +51,23 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public final class SmackConfiguration {
|
public final class SmackConfiguration {
|
||||||
|
private static final String SMACK_VERSION = "3.4.0";
|
||||||
|
private static final String DEFAULT_CONFIG_FILE = "classpath:META-INF/smack-config.xml";
|
||||||
|
|
||||||
private static final String SMACK_VERSION = "3.3.1";
|
private static final Logger log = Logger.getLogger(SmackConfiguration.class.getName());
|
||||||
|
|
||||||
|
private static InputStream configFileStream;
|
||||||
|
|
||||||
private static int packetReplyTimeout = 5000;
|
private static int packetReplyTimeout = 5000;
|
||||||
private static int keepAliveInterval = 30000;
|
private static int keepAliveInterval = 30000;
|
||||||
private static Vector<String> defaultMechs = new Vector<String>();
|
private static List<String> defaultMechs = new ArrayList<String>();
|
||||||
|
|
||||||
private static boolean localSocks5ProxyEnabled = true;
|
private static boolean localSocks5ProxyEnabled = true;
|
||||||
private static int localSocks5ProxyPort = 7777;
|
private static int localSocks5ProxyPort = 7777;
|
||||||
private static int packetCollectorSize = 5000;
|
private static int packetCollectorSize = 5000;
|
||||||
|
|
||||||
|
private static boolean initialized = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default parsing exception callback is {@link ExceptionThrowingCallback} which will
|
* The default parsing exception callback is {@link ExceptionThrowingCallback} which will
|
||||||
* throw an exception and therefore disconnect the active connection.
|
* throw an exception and therefore disconnect the active connection.
|
||||||
|
@ -81,20 +89,336 @@ public final class SmackConfiguration {
|
||||||
* 1) a set of classes will be loaded in order to execute their static init block
|
* 1) a set of classes will be loaded in order to execute their static init block
|
||||||
* 2) retrieve and set the current Smack release
|
* 2) retrieve and set the current Smack release
|
||||||
*/
|
*/
|
||||||
static {
|
|
||||||
|
/**
|
||||||
|
* Sets the location of the config file on the classpath. Only required if changing from the default location of <i>classpath:META-INF/smack-config.xml</i>.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This method must be called before accessing any other class in Smack.
|
||||||
|
*
|
||||||
|
* @param configFileUrl The location of the config file.
|
||||||
|
* @param loader The classloader to use if the URL has a protocol of <b>classpath</> and the file is not located on the default classpath.
|
||||||
|
* This can be set to null to use defaults and is ignored for all other protocols.
|
||||||
|
* @throws IllegalArgumentException If the config URL is invalid in that it cannot open an {@link InputStream}
|
||||||
|
*/
|
||||||
|
public static void setConfigFileUrl(String configFileUrl, ClassLoader loader) {
|
||||||
try {
|
try {
|
||||||
// Get an array of class loaders to try loading the providers files from.
|
configFileStream = FileUtils.getStreamForUrl(configFileUrl, loader);
|
||||||
ClassLoader[] classLoaders = getClassLoaders();
|
}
|
||||||
for (ClassLoader classLoader : classLoaders) {
|
catch (Exception e) {
|
||||||
Enumeration<URL> configEnum = classLoader.getResources("META-INF/smack-config.xml");
|
throw new IllegalArgumentException("Failed to create input stream from specified file URL ["+ configFileUrl + "]", e);
|
||||||
while (configEnum.hasMoreElements()) {
|
}
|
||||||
URL url = configEnum.nextElement();
|
initialize();
|
||||||
InputStream systemStream = null;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link InputStream} representing the smack configuration file. This can be used to override the default with something that is not on the classpath.
|
||||||
|
* <p>
|
||||||
|
* This method must be called before accessing any other class in Smack.
|
||||||
|
* @param configFile
|
||||||
|
*/
|
||||||
|
public static void setConfigFileStream(InputStream configFile) {
|
||||||
|
configFileStream = configFile;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Smack version information, eg "1.3.0".
|
||||||
|
*
|
||||||
|
* @return the Smack version information.
|
||||||
|
*/
|
||||||
|
public static String getVersion() {
|
||||||
|
return SMACK_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of milliseconds to wait for a response from
|
||||||
|
* the server. The default value is 5000 ms.
|
||||||
|
*
|
||||||
|
* @return the milliseconds to wait for a response from the server
|
||||||
|
*/
|
||||||
|
public static int getPacketReplyTimeout() {
|
||||||
|
initialize();
|
||||||
|
|
||||||
|
// The timeout value must be greater than 0 otherwise we will answer the default value
|
||||||
|
if (packetReplyTimeout <= 0) {
|
||||||
|
packetReplyTimeout = 5000;
|
||||||
|
}
|
||||||
|
return packetReplyTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of milliseconds to wait for a response from
|
||||||
|
* the server.
|
||||||
|
*
|
||||||
|
* @param timeout the milliseconds to wait for a response from the server
|
||||||
|
*/
|
||||||
|
public static void setPacketReplyTimeout(int timeout) {
|
||||||
|
initialize();
|
||||||
|
|
||||||
|
if (timeout <= 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
packetReplyTimeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of milleseconds delay between sending keep-alive
|
||||||
|
* requests to the server. The default value is 30000 ms. A value of -1
|
||||||
|
* mean no keep-alive requests will be sent to the server.
|
||||||
|
*
|
||||||
|
* @return the milliseconds to wait between keep-alive requests, or -1 if
|
||||||
|
* no keep-alive should be sent.
|
||||||
|
*/
|
||||||
|
public static int getKeepAliveInterval() {
|
||||||
|
initialize();
|
||||||
|
return keepAliveInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of milleseconds delay between sending keep-alive
|
||||||
|
* requests to the server. The default value is 30000 ms. A value of -1
|
||||||
|
* mean no keep-alive requests will be sent to the server.
|
||||||
|
*
|
||||||
|
* @param interval the milliseconds to wait between keep-alive requests,
|
||||||
|
* or -1 if no keep-alive should be sent.
|
||||||
|
*/
|
||||||
|
public static void setKeepAliveInterval(int interval) {
|
||||||
|
initialize();
|
||||||
|
keepAliveInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default max size of a packet collector before it will delete
|
||||||
|
* the older packets.
|
||||||
|
*
|
||||||
|
* @return The number of packets to queue before deleting older packets.
|
||||||
|
*/
|
||||||
|
public static int getPacketCollectorSize() {
|
||||||
|
initialize();
|
||||||
|
return packetCollectorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default max size of a packet collector before it will delete
|
||||||
|
* the older packets.
|
||||||
|
*
|
||||||
|
* @param The number of packets to queue before deleting older packets.
|
||||||
|
*/
|
||||||
|
public static void setPacketCollectorSize(int collectorSize) {
|
||||||
|
initialize();
|
||||||
|
packetCollectorSize = collectorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a SASL mechanism to the list to be used.
|
||||||
|
*
|
||||||
|
* @param mech the SASL mechanism to be added
|
||||||
|
*/
|
||||||
|
public static void addSaslMech(String mech) {
|
||||||
|
initialize();
|
||||||
|
|
||||||
|
if(! defaultMechs.contains(mech) ) {
|
||||||
|
defaultMechs.add(mech);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a Collection of SASL mechanisms to the list to be used.
|
||||||
|
*
|
||||||
|
* @param mechs the Collection of SASL mechanisms to be added
|
||||||
|
*/
|
||||||
|
public static void addSaslMechs(Collection<String> mechs) {
|
||||||
|
initialize();
|
||||||
|
|
||||||
|
for(String mech : mechs) {
|
||||||
|
addSaslMech(mech);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a SASL mechanism from the list to be used.
|
||||||
|
*
|
||||||
|
* @param mech the SASL mechanism to be removed
|
||||||
|
*/
|
||||||
|
public static void removeSaslMech(String mech) {
|
||||||
|
initialize();
|
||||||
|
defaultMechs.remove(mech);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a Collection of SASL mechanisms to the list to be used.
|
||||||
|
*
|
||||||
|
* @param mechs the Collection of SASL mechanisms to be removed
|
||||||
|
*/
|
||||||
|
public static void removeSaslMechs(Collection<String> mechs) {
|
||||||
|
initialize();
|
||||||
|
defaultMechs.removeAll(mechs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of SASL mechanisms to be used. If a SASL mechanism is
|
||||||
|
* listed here it does not guarantee it will be used. The server may not
|
||||||
|
* support it, or it may not be implemented.
|
||||||
|
*
|
||||||
|
* @return the list of SASL mechanisms to be used.
|
||||||
|
*/
|
||||||
|
public static List<String> getSaslMechs() {
|
||||||
|
return Collections.unmodifiableList(defaultMechs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the local Socks5 proxy should be started. Default is true.
|
||||||
|
*
|
||||||
|
* @return if the local Socks5 proxy should be started
|
||||||
|
*/
|
||||||
|
public static boolean isLocalSocks5ProxyEnabled() {
|
||||||
|
initialize();
|
||||||
|
return localSocks5ProxyEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets if the local Socks5 proxy should be started. Default is true.
|
||||||
|
*
|
||||||
|
* @param localSocks5ProxyEnabled if the local Socks5 proxy should be started
|
||||||
|
*/
|
||||||
|
public static void setLocalSocks5ProxyEnabled(boolean localSocks5ProxyEnabled) {
|
||||||
|
initialize();
|
||||||
|
SmackConfiguration.localSocks5ProxyEnabled = localSocks5ProxyEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the port of the local Socks5 proxy. Default is 7777.
|
||||||
|
*
|
||||||
|
* @return the port of the local Socks5 proxy
|
||||||
|
*/
|
||||||
|
public static int getLocalSocks5ProxyPort() {
|
||||||
|
initialize();
|
||||||
|
return localSocks5ProxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the port of the local Socks5 proxy. Default is 7777. If you set the port to a negative
|
||||||
|
* value Smack tries the absolute value and all following until it finds an open port.
|
||||||
|
*
|
||||||
|
* @param localSocks5ProxyPort the port of the local Socks5 proxy to set
|
||||||
|
*/
|
||||||
|
public static void setLocalSocks5ProxyPort(int localSocks5ProxyPort) {
|
||||||
|
initialize();
|
||||||
|
SmackConfiguration.localSocks5ProxyPort = localSocks5ProxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if Entity Caps are enabled as default for every new connection
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean autoEnableEntityCaps() {
|
||||||
|
initialize();
|
||||||
|
return autoEnableEntityCaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if Entity Caps are enabled or disabled for every new connection
|
||||||
|
*
|
||||||
|
* @param true if Entity Caps should be auto enabled, false if not
|
||||||
|
*/
|
||||||
|
public static void setAutoEnableEntityCaps(boolean b) {
|
||||||
|
initialize();
|
||||||
|
autoEnableEntityCaps = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the default parsing exception callback for all newly created connections
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* @see ParsingExceptionCallback
|
||||||
|
*/
|
||||||
|
public static void setDefaultParsingExceptionCallback(ParsingExceptionCallback callback) {
|
||||||
|
initialize();
|
||||||
|
defaultCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default parsing exception callback
|
||||||
|
*
|
||||||
|
* @return the default parsing exception callback
|
||||||
|
* @see ParsingExceptionCallback
|
||||||
|
*/
|
||||||
|
public static ParsingExceptionCallback getDefaultParsingExceptionCallback() {
|
||||||
|
initialize();
|
||||||
|
return defaultCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseClassToLoad(XmlPullParser parser) throws Exception {
|
||||||
|
String className = parser.nextText();
|
||||||
|
// Attempt to load the class so that the class can get initialized
|
||||||
try {
|
try {
|
||||||
systemStream = url.openStream();
|
Class<?> initClass = Class.forName(className);
|
||||||
|
|
||||||
|
if (SmackInitializer.class.isAssignableFrom(initClass)) {
|
||||||
|
SmackInitializer initializer = (SmackInitializer) initClass.newInstance();
|
||||||
|
initializer.initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException cnfe) {
|
||||||
|
log.log(Level.WARNING, "A startup class [" + className + "] specified in smack-config.xml could not be loaded: ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int parseIntProperty(XmlPullParser parser, int defaultValue)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(parser.nextText());
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) {
|
||||||
|
log.log(Level.SEVERE, "Could not parse integer", nfe);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Order of precedence for config file is VM arg, setConfigXXX methods and embedded default file location.
|
||||||
|
*/
|
||||||
|
private static void initialize() {
|
||||||
|
if (initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
String configFileLocation = System.getProperty("smack.config.file");
|
||||||
|
|
||||||
|
if (configFileLocation != null) {
|
||||||
|
try {
|
||||||
|
configFileStream = FileUtils.getStreamForUrl(configFileLocation, null);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "Error creating input stream for config file [" + configFileLocation + "] from VM argument", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configFileStream == null) {
|
||||||
|
try {
|
||||||
|
configFileStream = FileUtils.getStreamForUrl(DEFAULT_CONFIG_FILE, null);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.INFO, "Could not create input stream for default config file [" + DEFAULT_CONFIG_FILE + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configFileStream != null) {
|
||||||
|
readFile(configFileStream);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.log(Level.INFO, "No configuration file found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readFile(InputStream cfgFileStream) {
|
||||||
XmlPullParser parser = new MXParser();
|
XmlPullParser parser = new MXParser();
|
||||||
|
try {
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
parser.setInput(systemStream, "UTF-8");
|
parser.setInput(cfgFileStream, "UTF-8");
|
||||||
int eventType = parser.getEventType();
|
int eventType = parser.getEventType();
|
||||||
do {
|
do {
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
@ -123,282 +447,18 @@ public final class SmackConfiguration {
|
||||||
else if (parser.getName().equals("autoEnableEntityCaps")) {
|
else if (parser.getName().equals("autoEnableEntityCaps")) {
|
||||||
autoEnableEntityCaps = Boolean.parseBoolean(parser.nextText());
|
autoEnableEntityCaps = Boolean.parseBoolean(parser.nextText());
|
||||||
}
|
}
|
||||||
else if (parser.getName().equals("autoEnableEntityCaps")) {
|
|
||||||
autoEnableEntityCaps = Boolean.parseBoolean(parser.nextText());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
eventType = parser.next();
|
eventType = parser.next();
|
||||||
}
|
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||||
while (eventType != XmlPullParser.END_DOCUMENT);
|
} catch (Exception e) {
|
||||||
}
|
log.log(Level.SEVERE, "Error occurred while reading config file", e);
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
systemStream.close();
|
cfgFileStream.close();
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (Exception e) {
|
log.log(Level.INFO, "Error while closing config file input stream", e);
|
||||||
// Ignore.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Smack version information, eg "1.3.0".
|
|
||||||
*
|
|
||||||
* @return the Smack version information.
|
|
||||||
*/
|
|
||||||
public static String getVersion() {
|
|
||||||
return SMACK_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of milliseconds to wait for a response from
|
|
||||||
* the server. The default value is 5000 ms.
|
|
||||||
*
|
|
||||||
* @return the milliseconds to wait for a response from the server
|
|
||||||
*/
|
|
||||||
public static int getPacketReplyTimeout() {
|
|
||||||
// The timeout value must be greater than 0 otherwise we will answer the default value
|
|
||||||
if (packetReplyTimeout <= 0) {
|
|
||||||
packetReplyTimeout = 5000;
|
|
||||||
}
|
|
||||||
return packetReplyTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the number of milliseconds to wait for a response from
|
|
||||||
* the server.
|
|
||||||
*
|
|
||||||
* @param timeout the milliseconds to wait for a response from the server
|
|
||||||
*/
|
|
||||||
public static void setPacketReplyTimeout(int timeout) {
|
|
||||||
if (timeout <= 0) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
packetReplyTimeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of milleseconds delay between sending keep-alive
|
|
||||||
* requests to the server. The default value is 30000 ms. A value of -1
|
|
||||||
* mean no keep-alive requests will be sent to the server.
|
|
||||||
*
|
|
||||||
* @return the milliseconds to wait between keep-alive requests, or -1 if
|
|
||||||
* no keep-alive should be sent.
|
|
||||||
*/
|
|
||||||
public static int getKeepAliveInterval() {
|
|
||||||
return keepAliveInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the number of milleseconds delay between sending keep-alive
|
|
||||||
* requests to the server. The default value is 30000 ms. A value of -1
|
|
||||||
* mean no keep-alive requests will be sent to the server.
|
|
||||||
*
|
|
||||||
* @param interval the milliseconds to wait between keep-alive requests,
|
|
||||||
* or -1 if no keep-alive should be sent.
|
|
||||||
*/
|
|
||||||
public static void setKeepAliveInterval(int interval) {
|
|
||||||
keepAliveInterval = interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default max size of a packet collector before it will delete
|
|
||||||
* the older packets.
|
|
||||||
*
|
|
||||||
* @return The number of packets to queue before deleting older packets.
|
|
||||||
*/
|
|
||||||
public static int getPacketCollectorSize() {
|
|
||||||
return packetCollectorSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the default max size of a packet collector before it will delete
|
|
||||||
* the older packets.
|
|
||||||
*
|
|
||||||
* @param The number of packets to queue before deleting older packets.
|
|
||||||
*/
|
|
||||||
public static void setPacketCollectorSize(int collectorSize) {
|
|
||||||
packetCollectorSize = collectorSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a SASL mechanism to the list to be used.
|
|
||||||
*
|
|
||||||
* @param mech the SASL mechanism to be added
|
|
||||||
*/
|
|
||||||
public static void addSaslMech(String mech) {
|
|
||||||
if(! defaultMechs.contains(mech) ) {
|
|
||||||
defaultMechs.add(mech);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a Collection of SASL mechanisms to the list to be used.
|
|
||||||
*
|
|
||||||
* @param mechs the Collection of SASL mechanisms to be added
|
|
||||||
*/
|
|
||||||
public static void addSaslMechs(Collection<String> mechs) {
|
|
||||||
for(String mech : mechs) {
|
|
||||||
addSaslMech(mech);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a SASL mechanism from the list to be used.
|
|
||||||
*
|
|
||||||
* @param mech the SASL mechanism to be removed
|
|
||||||
*/
|
|
||||||
public static void removeSaslMech(String mech) {
|
|
||||||
if( defaultMechs.contains(mech) ) {
|
|
||||||
defaultMechs.remove(mech);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a Collection of SASL mechanisms to the list to be used.
|
|
||||||
*
|
|
||||||
* @param mechs the Collection of SASL mechanisms to be removed
|
|
||||||
*/
|
|
||||||
public static void removeSaslMechs(Collection<String> mechs) {
|
|
||||||
for(String mech : mechs) {
|
|
||||||
removeSaslMech(mech);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of SASL mechanisms to be used. If a SASL mechanism is
|
|
||||||
* listed here it does not guarantee it will be used. The server may not
|
|
||||||
* support it, or it may not be implemented.
|
|
||||||
*
|
|
||||||
* @return the list of SASL mechanisms to be used.
|
|
||||||
*/
|
|
||||||
public static List<String> getSaslMechs() {
|
|
||||||
return defaultMechs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the local Socks5 proxy should be started. Default is true.
|
|
||||||
*
|
|
||||||
* @return if the local Socks5 proxy should be started
|
|
||||||
*/
|
|
||||||
public static boolean isLocalSocks5ProxyEnabled() {
|
|
||||||
return localSocks5ProxyEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets if the local Socks5 proxy should be started. Default is true.
|
|
||||||
*
|
|
||||||
* @param localSocks5ProxyEnabled if the local Socks5 proxy should be started
|
|
||||||
*/
|
|
||||||
public static void setLocalSocks5ProxyEnabled(boolean localSocks5ProxyEnabled) {
|
|
||||||
SmackConfiguration.localSocks5ProxyEnabled = localSocks5ProxyEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the port of the local Socks5 proxy. Default is 7777.
|
|
||||||
*
|
|
||||||
* @return the port of the local Socks5 proxy
|
|
||||||
*/
|
|
||||||
public static int getLocalSocks5ProxyPort() {
|
|
||||||
return localSocks5ProxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the port of the local Socks5 proxy. Default is 7777. If you set the port to a negative
|
|
||||||
* value Smack tries the absolute value and all following until it finds an open port.
|
|
||||||
*
|
|
||||||
* @param localSocks5ProxyPort the port of the local Socks5 proxy to set
|
|
||||||
*/
|
|
||||||
public static void setLocalSocks5ProxyPort(int localSocks5ProxyPort) {
|
|
||||||
SmackConfiguration.localSocks5ProxyPort = localSocks5ProxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set if Entity Caps are enabled or disabled for every new connection
|
|
||||||
*
|
|
||||||
* @param true if Entity Caps should be auto enabled, false if not
|
|
||||||
*/
|
|
||||||
public static void setAutoEnableEntityCaps(boolean b) {
|
|
||||||
autoEnableEntityCaps = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if Entity Caps are enabled as default for every new connection
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean autoEnableEntityCaps() {
|
|
||||||
return autoEnableEntityCaps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default parsing exception callback for all newly created connections
|
|
||||||
*
|
|
||||||
* @param callback
|
|
||||||
* @see ParsingExceptionCallback
|
|
||||||
*/
|
|
||||||
public static void setDefaultParsingExceptionCallback(ParsingExceptionCallback callback) {
|
|
||||||
defaultCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the default parsing exception callback
|
|
||||||
*
|
|
||||||
* @return the default parsing exception callback
|
|
||||||
* @see ParsingExceptionCallback
|
|
||||||
*/
|
|
||||||
public static ParsingExceptionCallback getDefaultParsingExceptionCallback() {
|
|
||||||
return defaultCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void parseClassToLoad(XmlPullParser parser) throws Exception {
|
|
||||||
String className = parser.nextText();
|
|
||||||
// Attempt to load the class so that the class can get initialized
|
|
||||||
try {
|
|
||||||
Class.forName(className);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException cnfe) {
|
|
||||||
System.err.println("Error! A startup class specified in smack-config.xml could " +
|
|
||||||
"not be loaded: " + className);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int parseIntProperty(XmlPullParser parser, int defaultValue)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(parser.nextText());
|
|
||||||
}
|
|
||||||
catch (NumberFormatException nfe) {
|
|
||||||
nfe.printStackTrace();
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of class loaders to load resources from.
|
|
||||||
*
|
|
||||||
* @return an array of ClassLoader instances.
|
|
||||||
*/
|
|
||||||
private static ClassLoader[] getClassLoaders() {
|
|
||||||
ClassLoader[] classLoaders = new ClassLoader[2];
|
|
||||||
classLoaders[0] = SmackConfiguration.class.getClassLoader();
|
|
||||||
classLoaders[1] = Thread.currentThread().getContextClassLoader();
|
|
||||||
// Clean up possible null values. Note that #getClassLoader may return a null value.
|
|
||||||
List<ClassLoader> loaders = new ArrayList<ClassLoader>();
|
|
||||||
for (ClassLoader classLoader : classLoaders) {
|
|
||||||
if (classLoader != null) {
|
|
||||||
loaders.add(classLoader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return loaders.toArray(new ClassLoader[loaders.size()]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
14
source/org/jivesoftware/smack/SmackInitializer.java
Normal file
14
source/org/jivesoftware/smack/SmackInitializer.java
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package org.jivesoftware.smack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an initialization class that will be instantiated and invoked by the {@link SmackConfiguration} class during initialization.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Any implementation of this class MUST have a default constructor.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface SmackInitializer {
|
||||||
|
void initialize();
|
||||||
|
}
|
|
@ -788,7 +788,6 @@ public class XMPPConnection extends Connection {
|
||||||
if(config.getCallbackHandler() == null) {
|
if(config.getCallbackHandler() == null) {
|
||||||
ks = null;
|
ks = null;
|
||||||
} else if (context == null) {
|
} else if (context == null) {
|
||||||
//System.out.println("Keystore type: "+configuration.getKeystoreType());
|
|
||||||
if(config.getKeystoreType().equals("NONE")) {
|
if(config.getKeystoreType().equals("NONE")) {
|
||||||
ks = null;
|
ks = null;
|
||||||
pcb = null;
|
pcb = null;
|
||||||
|
@ -1043,9 +1042,12 @@ public class XMPPConnection extends Connection {
|
||||||
*/
|
*/
|
||||||
synchronized void notifyConnectionError(Exception e) {
|
synchronized void notifyConnectionError(Exception e) {
|
||||||
// Listeners were already notified of the exception, return right here.
|
// Listeners were already notified of the exception, return right here.
|
||||||
if (packetReader.done && packetWriter.done) return;
|
if ((packetReader == null || packetReader.done) &&
|
||||||
|
(packetWriter == null || packetWriter.done)) return;
|
||||||
|
|
||||||
|
if (packetReader != null)
|
||||||
packetReader.done = true;
|
packetReader.done = true;
|
||||||
|
if (packetWriter != null)
|
||||||
packetWriter.done = true;
|
packetWriter.done = true;
|
||||||
// Closes the connection temporary. A reconnection is possible
|
// Closes the connection temporary. A reconnection is possible
|
||||||
shutdown(new Presence(Presence.Type.unavailable));
|
shutdown(new Presence(Presence.Type.unavailable));
|
||||||
|
|
|
@ -80,8 +80,11 @@ public class Message extends Packet {
|
||||||
*/
|
*/
|
||||||
public Message(String to, Type type) {
|
public Message(String to, Type type) {
|
||||||
setTo(to);
|
setTo(to);
|
||||||
|
|
||||||
|
if (type != null) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type of the message. If no type has been set this method will return {@link
|
* Returns the type of the message. If no type has been set this method will return {@link
|
||||||
|
|
|
@ -27,6 +27,8 @@ import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for XMPP packets. Every packet has a unique ID (which is automatically
|
* Base class for XMPP packets. Every packet has a unique ID (which is automatically
|
||||||
|
@ -41,6 +43,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
*/
|
*/
|
||||||
public abstract class Packet {
|
public abstract class Packet {
|
||||||
|
private static Logger log = Logger.getLogger(Packet.class.getName());
|
||||||
|
|
||||||
protected static final String DEFAULT_LANGUAGE =
|
protected static final String DEFAULT_LANGUAGE =
|
||||||
java.util.Locale.getDefault().getLanguage().toLowerCase();
|
java.util.Locale.getDefault().getLanguage().toLowerCase();
|
||||||
|
@ -411,7 +414,7 @@ public abstract class Packet {
|
||||||
buf.append(encodedVal).append("</value>");
|
buf.append(encodedVal).append("</value>");
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error encoding java object", e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
|
@ -452,6 +455,7 @@ public abstract class Packet {
|
||||||
return DEFAULT_LANGUAGE;
|
return DEFAULT_LANGUAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
@ -472,6 +476,7 @@ public abstract class Packet {
|
||||||
return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null);
|
return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result;
|
int result;
|
||||||
result = (xmlns != null ? xmlns.hashCode() : 0);
|
result = (xmlns != null ? xmlns.hashCode() : 0);
|
||||||
|
@ -483,4 +488,9 @@ public abstract class Packet {
|
||||||
result = 31 * result + (error != null ? error.hashCode() : 0);
|
result = 31 * result + (error != null ? error.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toXML();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,18 +20,21 @@
|
||||||
|
|
||||||
package org.jivesoftware.smack.parsing;
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple parsing exception callback that only logs the encountered parsing exception to stderr.
|
* Simple parsing exception callback that only logs the encountered parsing exception to java util logging.
|
||||||
*
|
*
|
||||||
* @author Florian Schmaus
|
* @author Florian Schmaus
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ExceptionLoggingCallback extends ParsingExceptionCallback {
|
public class ExceptionLoggingCallback extends ParsingExceptionCallback {
|
||||||
|
private static Logger log = Logger.getLogger(ExceptionLoggingCallback.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleUnparsablePacket(UnparsablePacket unparsed) throws Exception {
|
public void handleUnparsablePacket(UnparsablePacket unparsed) throws Exception {
|
||||||
System.err.print("Smack message parsing exception: " + unparsed.getParsingException().getMessage());
|
log.log(Level.SEVERE, "Smack message parsing exception: ", unparsed.getParsingException());
|
||||||
unparsed.getParsingException().printStackTrace();
|
log.severe("Unparsed content: " + unparsed.getContent());
|
||||||
System.err.println("Unparsed content: " + unparsed.getContent());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
|
||||||
|
abstract class AbstractProviderInfo {
|
||||||
|
private String element;
|
||||||
|
private String ns;
|
||||||
|
private Object provider;
|
||||||
|
|
||||||
|
AbstractProviderInfo(String elementName, String namespace, Object iqOrExtProvider) {
|
||||||
|
element = elementName;
|
||||||
|
ns = namespace;
|
||||||
|
provider = iqOrExtProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElementName() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
}
|
15
source/org/jivesoftware/smack/provider/CoreInitializer.java
Normal file
15
source/org/jivesoftware/smack/provider/CoreInitializer.java
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackInitializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the default provider file for the Smack core on initialization.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CoreInitializer extends UrlProviderFileInitializer implements SmackInitializer {
|
||||||
|
protected String getFilePath() {
|
||||||
|
return "classpath:META-INF/core.providers";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the information required to register a packet extension Provider with the {@link ProviderManager} when using the
|
||||||
|
* {@link ProviderLoader}.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class ExtensionProviderInfo extends AbstractProviderInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an extension provider which implements the <code>PacketExtensionProvider</code> interface.
|
||||||
|
*
|
||||||
|
* @param elementName Element that provider parses.
|
||||||
|
* @param namespace Namespace that provider parses.
|
||||||
|
* @param extProvider The provider implementation.
|
||||||
|
*/
|
||||||
|
public ExtensionProviderInfo(String elementName, String namespace, PacketExtensionProvider extProvider) {
|
||||||
|
super(elementName, namespace, extProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an extension provider which is adheres to the JavaBean spec for parsing the extension.
|
||||||
|
*
|
||||||
|
* @param elementName Element that provider parses.
|
||||||
|
* @param namespace Namespace that provider parses.
|
||||||
|
* @param beanClass The provider bean class.
|
||||||
|
*/
|
||||||
|
public ExtensionProviderInfo(String elementName, String namespace, Class<?> beanClass) {
|
||||||
|
super(elementName, namespace, beanClass);
|
||||||
|
}
|
||||||
|
}
|
35
source/org/jivesoftware/smack/provider/IQProviderInfo.java
Normal file
35
source/org/jivesoftware/smack/provider/IQProviderInfo.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the information required to register an IQ Provider with the {@link ProviderManager} when using the
|
||||||
|
* {@link ProviderLoader}.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class IQProviderInfo extends AbstractProviderInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an IQ provider which implements the <code>IQProvider</code> interface.
|
||||||
|
*
|
||||||
|
* @param elementName Element that provider parses.
|
||||||
|
* @param namespace Namespace that provider parses.
|
||||||
|
* @param iqProvider The provider implementation.
|
||||||
|
*/
|
||||||
|
public IQProviderInfo(String elementName, String namespace, IQProvider iqProvider) {
|
||||||
|
super(elementName, namespace, iqProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an IQ class which can be used as a provider via introspection.
|
||||||
|
*
|
||||||
|
* @param elementName Element that provider parses.
|
||||||
|
* @param namespace Namespace that provider parses.
|
||||||
|
* @param iqProviderClass The IQ class being parsed.
|
||||||
|
*/
|
||||||
|
public IQProviderInfo(String elementName, String namespace, Class<? extends IQ> iqProviderClass) {
|
||||||
|
super(elementName, namespace, iqProviderClass);
|
||||||
|
}
|
||||||
|
}
|
146
source/org/jivesoftware/smack/provider/ProviderFileLoader.java
Normal file
146
source/org/jivesoftware/smack/provider/ProviderFileLoader.java
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.xmlpull.mxp1.MXParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the {@link IQProvider} and {@link PacketExtensionProvider} information from a standard provider file in preparation
|
||||||
|
* for loading into the {@link ProviderManager}.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProviderFileLoader implements ProviderLoader {
|
||||||
|
private final static Logger log = Logger.getLogger(ProviderFileLoader.class.getName());
|
||||||
|
|
||||||
|
private Collection<IQProviderInfo> iqProviders;
|
||||||
|
private Collection<ExtensionProviderInfo> extProviders;
|
||||||
|
private InputStream providerStream;
|
||||||
|
|
||||||
|
public ProviderFileLoader(InputStream providerFileInputStream) {
|
||||||
|
setInputStream(providerFileInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProviderFileLoader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<IQProviderInfo> getIQProviderInfo() {
|
||||||
|
initialize();
|
||||||
|
return iqProviders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
|
||||||
|
initialize();
|
||||||
|
return extProviders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private synchronized void initialize() {
|
||||||
|
// Check to see if already initialized
|
||||||
|
if (iqProviders != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providerStream == null) {
|
||||||
|
throw new IllegalArgumentException("No input stream set for loader");
|
||||||
|
}
|
||||||
|
iqProviders = new ArrayList<IQProviderInfo>();
|
||||||
|
extProviders = new ArrayList<ExtensionProviderInfo>();
|
||||||
|
|
||||||
|
// Load processing providers.
|
||||||
|
try {
|
||||||
|
XmlPullParser parser = new MXParser();
|
||||||
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
|
parser.setInput(providerStream, "UTF-8");
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
String typeName = parser.getName();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!"smackProviders".equals(typeName)) {
|
||||||
|
parser.next();
|
||||||
|
parser.next();
|
||||||
|
String elementName = parser.nextText();
|
||||||
|
parser.next();
|
||||||
|
parser.next();
|
||||||
|
String namespace = parser.nextText();
|
||||||
|
parser.next();
|
||||||
|
parser.next();
|
||||||
|
String className = parser.nextText();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Attempt to load the provider class and then create
|
||||||
|
// a new instance if it's an IQProvider. Otherwise, if it's
|
||||||
|
// an IQ class, add the class object itself, then we'll use
|
||||||
|
// reflection later to create instances of the class.
|
||||||
|
if ("iqProvider".equals(typeName)) {
|
||||||
|
// Add the provider to the map.
|
||||||
|
Class<?> provider = Class.forName(className);
|
||||||
|
|
||||||
|
if (IQProvider.class.isAssignableFrom(provider)) {
|
||||||
|
iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider) provider.newInstance()));
|
||||||
|
}
|
||||||
|
else if (IQ.class.isAssignableFrom(provider)) {
|
||||||
|
iqProviders.add(new IQProviderInfo(elementName, namespace, (Class<? extends IQ>)provider));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Attempt to load the provider class and then create
|
||||||
|
// a new instance if it's an ExtensionProvider. Otherwise, if it's
|
||||||
|
// a PacketExtension, add the class object itself and
|
||||||
|
// then we'll use reflection later to create instances
|
||||||
|
// of the class.
|
||||||
|
Class<?> provider = Class.forName(className);
|
||||||
|
if (PacketExtensionProvider.class.isAssignableFrom(provider)) {
|
||||||
|
extProviders.add(new ExtensionProviderInfo(elementName, namespace, (PacketExtensionProvider) provider.newInstance()));
|
||||||
|
}
|
||||||
|
else if (PacketExtension.class.isAssignableFrom(provider)) {
|
||||||
|
extProviders.add(new ExtensionProviderInfo(elementName, namespace, provider));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException cnfe) {
|
||||||
|
log.log(Level.SEVERE, "Could not find provider class", cnfe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException illExc) {
|
||||||
|
log.log(Level.SEVERE, "Invalid provider type found [" + typeName + "] when expecting iqProvider or extensionProvider", illExc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eventType = parser.next();
|
||||||
|
}
|
||||||
|
while (eventType != XmlPullParser.END_DOCUMENT);
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
log.log(Level.SEVERE, "Unknown error occurred while parsing provider file", e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
providerStream.close();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// Ignore.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputStream(InputStream providerFileInput) {
|
||||||
|
if (providerFileInput == null) {
|
||||||
|
throw new IllegalArgumentException("InputStream cannot be null");
|
||||||
|
}
|
||||||
|
providerStream = providerFileInput;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
}
|
23
source/org/jivesoftware/smack/provider/ProviderLoader.java
Normal file
23
source/org/jivesoftware/smack/provider/ProviderLoader.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to load providers into the {@link ProviderManager}.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*/
|
||||||
|
public interface ProviderLoader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the IQ provider info for the creation of IQ providers to be added to the <code>ProviderManager</code>.
|
||||||
|
* @return The IQ provider info to load.
|
||||||
|
*/
|
||||||
|
Collection<IQProviderInfo> getIQProviderInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the extension providers for the creation of extension providers to be added to the <code>ProviderManager</code>.
|
||||||
|
* @return The extension provider info to load.
|
||||||
|
*/
|
||||||
|
Collection<ExtensionProviderInfo> getExtensionProviderInfo();
|
||||||
|
}
|
|
@ -20,16 +20,13 @@
|
||||||
|
|
||||||
package org.jivesoftware.smack.provider;
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import java.util.Collection;
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import java.util.Collections;
|
||||||
import org.xmlpull.mxp1.MXParser;
|
import java.util.Map;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages providers for parsing custom XML sub-documents of XMPP packets. Two types of
|
* Manages providers for parsing custom XML sub-documents of XMPP packets. Two types of
|
||||||
* providers exist:<ul>
|
* providers exist:<ul>
|
||||||
|
@ -102,20 +99,14 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
* can either implement the PacketExtensionProvider interface or be a standard Java Bean. In
|
* can either implement the PacketExtensionProvider interface or be a standard Java Bean. In
|
||||||
* the former case, each extension provider is responsible for parsing the raw XML stream to
|
* the former case, each extension provider is responsible for parsing the raw XML stream to
|
||||||
* contruct an object. In the latter case, bean introspection is used to try to automatically
|
* contruct an object. In the latter case, bean introspection is used to try to automatically
|
||||||
* set the properties of the class using the values in the packet extension sub-element. When an
|
* set the properties of th class using the values in the packet extension sub-element. When an
|
||||||
* extension provider is not registered for an element name and namespace combination, Smack will
|
* extension provider is not registered for an element name and namespace combination, Smack will
|
||||||
* store all top-level elements of the sub-packet in DefaultPacketExtension object and then
|
* store all top-level elements of the sub-packet in DefaultPacketExtension object and then
|
||||||
* attach it to the packet.<p>
|
* attach it to the packet.<p>
|
||||||
*
|
*
|
||||||
* It is possible to provide a custom provider manager instead of the default implementation
|
|
||||||
* provided by Smack. If you want to provide your own provider manager then you need to do it
|
|
||||||
* before creating any {@link org.jivesoftware.smack.Connection} by sending the static
|
|
||||||
* {@link #setInstance(ProviderManager)} message. Trying to change the provider manager after
|
|
||||||
* an Connection was created will result in an {@link IllegalStateException} error.
|
|
||||||
*
|
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
*/
|
*/
|
||||||
public class ProviderManager {
|
public final class ProviderManager {
|
||||||
|
|
||||||
private static ProviderManager instance;
|
private static ProviderManager instance;
|
||||||
|
|
||||||
|
@ -123,9 +114,7 @@ public class ProviderManager {
|
||||||
private Map<String, Object> iqProviders = new ConcurrentHashMap<String, Object>();
|
private Map<String, Object> iqProviders = new ConcurrentHashMap<String, Object>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the only ProviderManager valid instance. Use {@link #setInstance(ProviderManager)}
|
* Returns the ProviderManager instance.
|
||||||
* to configure your own provider manager. If non was provided then an instance of this
|
|
||||||
* class will be used.
|
|
||||||
*
|
*
|
||||||
* @return the only ProviderManager valid instance.
|
* @return the only ProviderManager valid instance.
|
||||||
*/
|
*/
|
||||||
|
@ -136,129 +125,27 @@ public class ProviderManager {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private ProviderManager() {
|
||||||
* Sets the only ProviderManager valid instance to be used by all Connections. If you
|
super();
|
||||||
* want to provide your own provider manager then you need to do it before creating
|
|
||||||
* any Connection. Otherwise an IllegalStateException will be thrown.
|
|
||||||
*
|
|
||||||
* @param providerManager the only ProviderManager valid instance to be used.
|
|
||||||
* @throws IllegalStateException if a provider manager was already configued.
|
|
||||||
*/
|
|
||||||
public static synchronized void setInstance(ProviderManager providerManager) {
|
|
||||||
if (instance != null) {
|
|
||||||
throw new IllegalStateException("ProviderManager singleton already set");
|
|
||||||
}
|
|
||||||
instance = providerManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initialize() {
|
public void addLoader(ProviderLoader loader) {
|
||||||
// Load IQ processing providers.
|
if (loader == null) {
|
||||||
try {
|
throw new IllegalArgumentException("loader cannot be null");
|
||||||
// Get an array of class loaders to try loading the providers files from.
|
|
||||||
ClassLoader[] classLoaders = getClassLoaders();
|
|
||||||
for (ClassLoader classLoader : classLoaders) {
|
|
||||||
Enumeration<URL> providerEnum = classLoader.getResources(
|
|
||||||
"META-INF/smack.providers");
|
|
||||||
while (providerEnum.hasMoreElements()) {
|
|
||||||
URL url = providerEnum.nextElement();
|
|
||||||
InputStream providerStream = null;
|
|
||||||
try {
|
|
||||||
providerStream = url.openStream();
|
|
||||||
XmlPullParser parser = new MXParser();
|
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
|
||||||
parser.setInput(providerStream, "UTF-8");
|
|
||||||
int eventType = parser.getEventType();
|
|
||||||
do {
|
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
|
||||||
if (parser.getName().equals("iqProvider")) {
|
|
||||||
parser.next();
|
|
||||||
parser.next();
|
|
||||||
String elementName = parser.nextText();
|
|
||||||
parser.next();
|
|
||||||
parser.next();
|
|
||||||
String namespace = parser.nextText();
|
|
||||||
parser.next();
|
|
||||||
parser.next();
|
|
||||||
String className = parser.nextText();
|
|
||||||
// Only add the provider for the namespace if one isn't
|
|
||||||
// already registered.
|
|
||||||
String key = getProviderKey(elementName, namespace);
|
|
||||||
if (!iqProviders.containsKey(key)) {
|
|
||||||
// Attempt to load the provider class and then create
|
|
||||||
// a new instance if it's an IQProvider. Otherwise, if it's
|
|
||||||
// an IQ class, add the class object itself, then we'll use
|
|
||||||
// reflection later to create instances of the class.
|
|
||||||
try {
|
|
||||||
// Add the provider to the map.
|
|
||||||
Class<?> provider = Class.forName(className);
|
|
||||||
if (IQProvider.class.isAssignableFrom(provider)) {
|
|
||||||
iqProviders.put(key, provider.newInstance());
|
|
||||||
}
|
}
|
||||||
else if (IQ.class.isAssignableFrom(provider)) {
|
|
||||||
iqProviders.put(key, provider);
|
if (loader.getIQProviderInfo() != null) {
|
||||||
|
for (IQProviderInfo info : loader.getIQProviderInfo()) {
|
||||||
|
iqProviders.put(getProviderKey(info.getElementName(), info.getNamespace()), info.getProvider());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
|
||||||
cnfe.printStackTrace();
|
if (loader.getExtensionProviderInfo() != null) {
|
||||||
|
for (ExtensionProviderInfo info : loader.getExtensionProviderInfo()) {
|
||||||
|
extensionProviders.put(getProviderKey(info.getElementName(), info.getNamespace()), info.getProvider());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (parser.getName().equals("extensionProvider")) {
|
|
||||||
parser.next();
|
|
||||||
parser.next();
|
|
||||||
String elementName = parser.nextText();
|
|
||||||
parser.next();
|
|
||||||
parser.next();
|
|
||||||
String namespace = parser.nextText();
|
|
||||||
parser.next();
|
|
||||||
parser.next();
|
|
||||||
String className = parser.nextText();
|
|
||||||
// Only add the provider for the namespace if one isn't
|
|
||||||
// already registered.
|
|
||||||
String key = getProviderKey(elementName, namespace);
|
|
||||||
if (!extensionProviders.containsKey(key)) {
|
|
||||||
// Attempt to load the provider class and then create
|
|
||||||
// a new instance if it's a Provider. Otherwise, if it's
|
|
||||||
// a PacketExtension, add the class object itself and
|
|
||||||
// then we'll use reflection later to create instances
|
|
||||||
// of the class.
|
|
||||||
try {
|
|
||||||
// Add the provider to the map.
|
|
||||||
Class<?> provider = Class.forName(className);
|
|
||||||
if (PacketExtensionProvider.class.isAssignableFrom(
|
|
||||||
provider)) {
|
|
||||||
extensionProviders.put(key, provider.newInstance());
|
|
||||||
}
|
|
||||||
else if (PacketExtension.class.isAssignableFrom(
|
|
||||||
provider)) {
|
|
||||||
extensionProviders.put(key, provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException cnfe) {
|
|
||||||
cnfe.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventType = parser.next();
|
|
||||||
}
|
|
||||||
while (eventType != XmlPullParser.END_DOCUMENT);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
providerStream.close();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
// Ignore.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IQ provider registered to the specified XML element name and namespace.
|
* Returns the IQ provider registered to the specified XML element name and namespace.
|
||||||
|
@ -411,28 +298,4 @@ public class ProviderManager {
|
||||||
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
|
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of class loaders to load resources from.
|
|
||||||
*
|
|
||||||
* @return an array of ClassLoader instances.
|
|
||||||
*/
|
|
||||||
private ClassLoader[] getClassLoaders() {
|
|
||||||
ClassLoader[] classLoaders = new ClassLoader[2];
|
|
||||||
classLoaders[0] = ProviderManager.class.getClassLoader();
|
|
||||||
classLoaders[1] = Thread.currentThread().getContextClassLoader();
|
|
||||||
// Clean up possible null values. Note that #getClassLoader may return a null value.
|
|
||||||
List<ClassLoader> loaders = new ArrayList<ClassLoader>();
|
|
||||||
for (ClassLoader classLoader : classLoaders) {
|
|
||||||
if (classLoader != null) {
|
|
||||||
loaders.add(classLoader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return loaders.toArray(new ClassLoader[loaders.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProviderManager() {
|
|
||||||
super();
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackInitializer;
|
||||||
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the provider file defined by the URL returned by {@link #getFilePath()}. This file will be loaded on Smack initialization.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class UrlProviderFileInitializer implements SmackInitializer {
|
||||||
|
private static final Logger log = Logger.getLogger(UrlProviderFileInitializer.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
String filePath = getFilePath();
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream is = FileUtils.getStreamForUrl(filePath, getClassLoader());
|
||||||
|
|
||||||
|
if (is != null) {
|
||||||
|
log.log(Level.INFO, "Loading providers for file [" + filePath + "]");
|
||||||
|
ProviderManager.getInstance().addLoader(new ProviderFileLoader(is));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.log(Level.WARNING, "No input stream created for " + filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "Error trying to load provider file " + filePath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String getFilePath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of class loaders to load resources from.
|
||||||
|
*
|
||||||
|
* @return an array of ClassLoader instances.
|
||||||
|
*/
|
||||||
|
protected ClassLoader getClassLoader() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
23
source/org/jivesoftware/smack/provider/VmArgInitializer.java
Normal file
23
source/org/jivesoftware/smack/provider/VmArgInitializer.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package org.jivesoftware.smack.provider;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks for a provider file location based on the VM argument <i>smack.provider.file</>. If it is supplied, its value will
|
||||||
|
* be used as a file location for a providers file and loaded into the {@link ProviderManager} on Smack initialization.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class VmArgInitializer extends UrlProviderFileInitializer {
|
||||||
|
|
||||||
|
protected String getFilePath() {
|
||||||
|
return System.getProperty("smack.provider.file");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
if (getFilePath() != null) {
|
||||||
|
super.initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smack.util;
|
package org.jivesoftware.smack.util;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Encodes and decodes to and from Base64 notation.</p>
|
* <p>Encodes and decodes to and from Base64 notation.</p>
|
||||||
* This code was obtained from <a href="http://iharder.net/base64">http://iharder.net/base64</a></p>
|
* This code was obtained from <a href="http://iharder.net/base64">http://iharder.net/base64</a></p>
|
||||||
|
@ -17,9 +20,9 @@ package org.jivesoftware.smack.util;
|
||||||
*/
|
*/
|
||||||
public class Base64
|
public class Base64
|
||||||
{
|
{
|
||||||
|
private static Logger log = Logger.getLogger(Base64.class.getName());
|
||||||
|
|
||||||
/* ******** P U B L I C F I E L D S ******** */
|
/* ******** P U B L I C F I E L D S ******** */
|
||||||
|
|
||||||
|
|
||||||
/** No options specified. Value is zero. */
|
/** No options specified. Value is zero. */
|
||||||
public final static int NO_OPTIONS = 0;
|
public final static int NO_OPTIONS = 0;
|
||||||
|
@ -311,18 +314,6 @@ public class Base64
|
||||||
/** Defeats instantiation. */
|
/** Defeats instantiation. */
|
||||||
private Base64(){}
|
private Base64(){}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints command line usage.
|
|
||||||
*
|
|
||||||
* @param msg A message to include with usage info.
|
|
||||||
*/
|
|
||||||
private final static void usage( String msg )
|
|
||||||
{
|
|
||||||
System.err.println( msg );
|
|
||||||
System.err.println( "Usage: java Base64 -e|-d inputfile outputfile" );
|
|
||||||
} // end usage
|
|
||||||
|
|
||||||
|
|
||||||
/* ******** E N C O D I N G M E T H O D S ******** */
|
/* ******** E N C O D I N G M E T H O D S ******** */
|
||||||
|
|
||||||
|
|
||||||
|
@ -494,7 +485,7 @@ public class Base64
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException e )
|
catch( java.io.IOException e )
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error encoding object", e);
|
||||||
return null;
|
return null;
|
||||||
} // end catch
|
} // end catch
|
||||||
finally
|
finally
|
||||||
|
@ -623,7 +614,7 @@ public class Base64
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException e )
|
catch( java.io.IOException e )
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error encoding bytes", e);
|
||||||
return null;
|
return null;
|
||||||
} // end catch
|
} // end catch
|
||||||
finally
|
finally
|
||||||
|
@ -778,10 +769,11 @@ public class Base64
|
||||||
|
|
||||||
return 3;
|
return 3;
|
||||||
}catch( Exception e){
|
}catch( Exception e){
|
||||||
System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) );
|
log.log(Level.SEVERE, e.getMessage(), e);
|
||||||
System.out.println(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) );
|
log.severe(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) );
|
||||||
System.out.println(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) );
|
log.severe(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) );
|
||||||
System.out.println(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) );
|
log.severe(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) );
|
||||||
|
log.severe(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) );
|
||||||
return -1;
|
return -1;
|
||||||
} // end catch
|
} // end catch
|
||||||
}
|
}
|
||||||
|
@ -839,7 +831,7 @@ public class Base64
|
||||||
} // end if: white space, equals sign or better
|
} // end if: white space, equals sign or better
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" );
|
log.warning("Bad Base64 input character at " + i + ": " + source[i] + "(decimal)");
|
||||||
return null;
|
return null;
|
||||||
} // end else:
|
} // end else:
|
||||||
} // each input character
|
} // each input character
|
||||||
|
@ -967,12 +959,12 @@ public class Base64
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException e )
|
catch( java.io.IOException e )
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error reading object", e);
|
||||||
obj = null;
|
obj = null;
|
||||||
} // end catch
|
} // end catch
|
||||||
catch( java.lang.ClassNotFoundException e )
|
catch( java.lang.ClassNotFoundException e )
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Class not found for encoded object", e);
|
||||||
obj = null;
|
obj = null;
|
||||||
} // end catch
|
} // end catch
|
||||||
finally
|
finally
|
||||||
|
@ -1079,7 +1071,7 @@ public class Base64
|
||||||
// Check for size of file
|
// Check for size of file
|
||||||
if( file.length() > Integer.MAX_VALUE )
|
if( file.length() > Integer.MAX_VALUE )
|
||||||
{
|
{
|
||||||
System.err.println( "File is too big for this convenience method (" + file.length() + " bytes)." );
|
log.warning("File is too big for this convenience method (" + file.length() + " bytes).");
|
||||||
return null;
|
return null;
|
||||||
} // end if: file too big for int index
|
} // end if: file too big for int index
|
||||||
buffer = new byte[ (int)file.length() ];
|
buffer = new byte[ (int)file.length() ];
|
||||||
|
@ -1100,7 +1092,7 @@ public class Base64
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException e )
|
catch( java.io.IOException e )
|
||||||
{
|
{
|
||||||
System.err.println( "Error decoding from file " + filename );
|
log.log(Level.SEVERE, "Error decoding from file " + filename, e);
|
||||||
} // end catch: IOException
|
} // end catch: IOException
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -1148,7 +1140,7 @@ public class Base64
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException e )
|
catch( java.io.IOException e )
|
||||||
{
|
{
|
||||||
System.err.println( "Error encoding from file " + filename );
|
log.log(Level.SEVERE, "Error encoding from file " + filename, e);
|
||||||
} // end catch: IOException
|
} // end catch: IOException
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -1175,7 +1167,7 @@ public class Base64
|
||||||
out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
|
out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException ex ) {
|
catch( java.io.IOException ex ) {
|
||||||
ex.printStackTrace();
|
log.log(Level.SEVERE, "Error encoding file " + infile, ex);
|
||||||
} // end catch
|
} // end catch
|
||||||
finally {
|
finally {
|
||||||
try { out.close(); }
|
try { out.close(); }
|
||||||
|
@ -1201,7 +1193,7 @@ public class Base64
|
||||||
out.write( decoded );
|
out.write( decoded );
|
||||||
} // end try
|
} // end try
|
||||||
catch( java.io.IOException ex ) {
|
catch( java.io.IOException ex ) {
|
||||||
ex.printStackTrace();
|
log.log(Level.SEVERE, "Error decoding file " + infile, ex);
|
||||||
} // end catch
|
} // end catch
|
||||||
finally {
|
finally {
|
||||||
try { out.close(); }
|
try { out.close(); }
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.jivesoftware.smack.util;
|
||||||
import org.jivesoftware.smack.util.collections.AbstractMapEntry;
|
import org.jivesoftware.smack.util.collections.AbstractMapEntry;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized Map that is size-limited (using an LRU algorithm) and
|
* A specialized Map that is size-limited (using an LRU algorithm) and
|
||||||
|
@ -49,7 +50,7 @@ import java.util.*;
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
*/
|
*/
|
||||||
public class Cache<K, V> implements Map<K, V> {
|
public class Cache<K, V> implements Map<K, V> {
|
||||||
|
private static Logger log = Logger.getLogger(Cache.class.getName());
|
||||||
/**
|
/**
|
||||||
* The map the keys and values are stored in.
|
* The map the keys and values are stored in.
|
||||||
*/
|
*/
|
||||||
|
@ -382,8 +383,7 @@ public class Cache<K, V> implements Map<K, V> {
|
||||||
|
|
||||||
while (expireTime > node.timestamp) {
|
while (expireTime > node.timestamp) {
|
||||||
if (remove(node.object, true) == null) {
|
if (remove(node.object, true) == null) {
|
||||||
System.err.println("Error attempting to remove(" + node.object.toString() +
|
log.warning("Error attempting to remove(" + node.object.toString() + ") - cacheObject not found in cache!");
|
||||||
") - cacheObject not found in cache!");
|
|
||||||
// remove from the ageList
|
// remove from the ageList
|
||||||
node.remove();
|
node.remove();
|
||||||
}
|
}
|
||||||
|
@ -417,9 +417,7 @@ public class Cache<K, V> implements Map<K, V> {
|
||||||
for (int i=map.size(); i>desiredSize; i--) {
|
for (int i=map.size(); i>desiredSize; i--) {
|
||||||
// Get the key and invoke the remove method on it.
|
// Get the key and invoke the remove method on it.
|
||||||
if (remove(lastAccessedList.getLast().object, true) == null) {
|
if (remove(lastAccessedList.getLast().object, true) == null) {
|
||||||
System.err.println("Error attempting to cullCache with remove(" +
|
log.warning("Error attempting to cullCache with remove(" + lastAccessedList.getLast().object.toString() + ") - cacheObject not found in cache!");
|
||||||
lastAccessedList.getLast().object.toString() + ") - " +
|
|
||||||
"cacheObject not found in cache!");
|
|
||||||
lastAccessedList.getLast().remove();
|
lastAccessedList.getLast().remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
source/org/jivesoftware/smack/util/FileUtils.java
Normal file
59
source/org/jivesoftware/smack/util/FileUtils.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package org.jivesoftware.smack.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class FileUtils {
|
||||||
|
|
||||||
|
private FileUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream getStreamForUrl(String url, ClassLoader loader) throws MalformedURLException, IOException {
|
||||||
|
URI fileUri = URI.create(url);
|
||||||
|
|
||||||
|
if (fileUri.getScheme() == null) {
|
||||||
|
throw new MalformedURLException("No protocol found in file URL: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileUri.getScheme().equals("classpath")) {
|
||||||
|
// Get an array of class loaders to try loading the providers files from.
|
||||||
|
ClassLoader[] classLoaders = getClassLoaders();
|
||||||
|
for (ClassLoader classLoader : classLoaders) {
|
||||||
|
InputStream is = classLoader.getResourceAsStream(fileUri.getSchemeSpecificPart());
|
||||||
|
|
||||||
|
if (is != null) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return fileUri.toURL().openStream();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns default classloaders.
|
||||||
|
*
|
||||||
|
* @return an array of ClassLoader instances.
|
||||||
|
*/
|
||||||
|
public static ClassLoader[] getClassLoaders() {
|
||||||
|
ClassLoader[] classLoaders = new ClassLoader[2];
|
||||||
|
classLoaders[0] = FileUtils.class.getClassLoader();
|
||||||
|
classLoaders[1] = Thread.currentThread().getContextClassLoader();
|
||||||
|
// Clean up possible null values. Note that #getClassLoader may return a null value.
|
||||||
|
List<ClassLoader> loaders = new ArrayList<ClassLoader>();
|
||||||
|
|
||||||
|
for (ClassLoader classLoader : classLoaders) {
|
||||||
|
if (classLoader != null) {
|
||||||
|
loaders.add(classLoader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loaders.toArray(new ClassLoader[loaders.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -29,6 +29,8 @@ import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Connection;
|
import org.jivesoftware.smack.Connection;
|
||||||
import org.jivesoftware.smack.packet.Authentication;
|
import org.jivesoftware.smack.packet.Authentication;
|
||||||
|
@ -57,6 +59,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public class PacketParserUtils {
|
public class PacketParserUtils {
|
||||||
|
private static Logger logger = Logger.getLogger(PacketParserUtils.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Namespace used to store packet properties.
|
* Namespace used to store packet properties.
|
||||||
|
@ -198,7 +201,7 @@ public class PacketParserUtils {
|
||||||
type = Presence.Type.valueOf(typeString);
|
type = Presence.Type.valueOf(typeString);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
System.err.println("Found invalid presence type " + typeString);
|
logger.warning("Found invalid presence type " + typeString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Presence presence = new Presence(type);
|
Presence presence = new Presence(type);
|
||||||
|
@ -242,7 +245,7 @@ public class PacketParserUtils {
|
||||||
presence.setMode(Presence.Mode.valueOf(modeText));
|
presence.setMode(Presence.Mode.valueOf(modeText));
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
System.err.println("Found invalid presence mode " + modeText);
|
logger.warning("Found invalid presence mode " + modeText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (elementName.equals("error")) {
|
else if (elementName.equals("error")) {
|
||||||
|
@ -263,7 +266,7 @@ public class PacketParserUtils {
|
||||||
presence.addExtension(PacketParserUtils.parsePacketExtension(elementName, namespace, parser));
|
presence.addExtension(PacketParserUtils.parsePacketExtension(elementName, namespace, parser));
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
System.err.println("Failed to parse extension packet in Presence packet.");
|
logger.warning("Failed to parse extension packet in Presence packet.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,7 +642,7 @@ public class PacketParserUtils {
|
||||||
value = in.readObject();
|
value = in.readObject();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
logger.log(Level.SEVERE, "Error parsing java object", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name != null && value != null) {
|
if (name != null && value != null) {
|
||||||
|
@ -782,8 +785,7 @@ public class PacketParserUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
// Print stack trace. We shouldn't be getting an illegal error type.
|
logger.log(Level.SEVERE, "Could not find error type for " + type.toUpperCase(), iae);
|
||||||
iae.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return new XMPPError(Integer.parseInt(errorCode), errorType, condition, message, extensions);
|
return new XMPPError(Integer.parseInt(errorCode), errorType, condition, message, extensions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -41,6 +43,7 @@ import java.util.regex.Pattern;
|
||||||
* A collection of utility methods for String objects.
|
* A collection of utility methods for String objects.
|
||||||
*/
|
*/
|
||||||
public class StringUtils {
|
public class StringUtils {
|
||||||
|
private static Logger log = Logger.getLogger(StringUtils.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date format as defined in XEP-0082 - XMPP Date and Time Profiles. The time zone is set to
|
* Date format as defined in XEP-0082 - XMPP Date and Time Profiles. The time zone is set to
|
||||||
|
@ -619,8 +622,7 @@ public class StringUtils {
|
||||||
digest = MessageDigest.getInstance("SHA-1");
|
digest = MessageDigest.getInstance("SHA-1");
|
||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException nsae) {
|
catch (NoSuchAlgorithmException nsae) {
|
||||||
System.err.println("Failed to load the SHA-1 MessageDigest. " +
|
log.log(Level.SEVERE, "Failed to load the SHA-1 MessageDigest. Smack will be unable to function normally.", nsae);
|
||||||
"Jive will be unable to function normally.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now, compute hash.
|
// Now, compute hash.
|
||||||
|
@ -628,7 +630,7 @@ public class StringUtils {
|
||||||
digest.update(data.getBytes("UTF-8"));
|
digest.update(data.getBytes("UTF-8"));
|
||||||
}
|
}
|
||||||
catch (UnsupportedEncodingException e) {
|
catch (UnsupportedEncodingException e) {
|
||||||
System.err.println(e);
|
log.log(Level.SEVERE, "Error computing hash", e);
|
||||||
}
|
}
|
||||||
return encodeHex(digest.digest());
|
return encodeHex(digest.digest());
|
||||||
}
|
}
|
||||||
|
@ -664,7 +666,7 @@ public class StringUtils {
|
||||||
bytes = data.getBytes("ISO-8859-1");
|
bytes = data.getBytes("ISO-8859-1");
|
||||||
}
|
}
|
||||||
catch (UnsupportedEncodingException uee) {
|
catch (UnsupportedEncodingException uee) {
|
||||||
uee.printStackTrace();
|
throw new IllegalStateException(uee);
|
||||||
}
|
}
|
||||||
return encodeBase64(bytes);
|
return encodeBase64(bytes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.PacketListener;
|
import org.jivesoftware.smack.PacketListener;
|
||||||
import org.jivesoftware.smack.Connection;
|
import org.jivesoftware.smack.Connection;
|
||||||
|
@ -42,6 +44,7 @@ import org.jivesoftware.smackx.packet.MessageEvent;
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public class MessageEventManager {
|
public class MessageEventManager {
|
||||||
|
private static Logger log = Logger.getLogger(MessageEventManager.class.getName());
|
||||||
|
|
||||||
private List<MessageEventNotificationListener> messageEventNotificationListeners = new ArrayList<MessageEventNotificationListener>();
|
private List<MessageEventNotificationListener> messageEventNotificationListeners = new ArrayList<MessageEventNotificationListener>();
|
||||||
private List<MessageEventRequestListener> messageEventRequestListeners = new ArrayList<MessageEventRequestListener>();
|
private List<MessageEventRequestListener> messageEventRequestListeners = new ArrayList<MessageEventRequestListener>();
|
||||||
|
@ -157,12 +160,8 @@ public class MessageEventManager {
|
||||||
for (int i = 0; i < listeners.length; i++) {
|
for (int i = 0; i < listeners.length; i++) {
|
||||||
method.invoke(listeners[i], new Object[] { from, packetID, this });
|
method.invoke(listeners[i], new Object[] { from, packetID, this });
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error while invoking MessageEventRequestListener", e);
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,12 +187,8 @@ public class MessageEventManager {
|
||||||
for (int i = 0; i < listeners.length; i++) {
|
for (int i = 0; i < listeners.length; i++) {
|
||||||
method.invoke(listeners[i], new Object[] { from, packetID });
|
method.invoke(listeners[i], new Object[] { from, packetID });
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error while invoking MessageEventNotificationListener", e);
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ import org.jivesoftware.smackx.packet.MultipleAddresses;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MultipleRecipientManager allows to send packets to multiple recipients by making use of
|
* A MultipleRecipientManager allows to send packets to multiple recipients by making use of
|
||||||
|
@ -42,6 +44,7 @@ import java.util.List;
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public class MultipleRecipientManager {
|
public class MultipleRecipientManager {
|
||||||
|
private static Logger log = Logger.getLogger(MultipleRecipientManager.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a cache to hold the 100 most recently accessed elements for a period of
|
* Create a cache to hold the 100 most recently accessed elements for a period of
|
||||||
|
@ -309,13 +312,12 @@ public class MultipleRecipientManager {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Cache the discovered information
|
// Cache the discovered information
|
||||||
services.put(serviceName, serviceAddress == null ? "" : serviceAddress);
|
services.put(serviceName, serviceAddress == null ? "" : serviceAddress);
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error occurred retrieving multiple recipients service", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.jivesoftware.smackx.packet.PEPEvent;
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface PEPListener {
|
public interface PEPListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -60,6 +60,7 @@ import org.jivesoftware.smackx.packet.PEPPubSub;
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class PEPManager {
|
public class PEPManager {
|
||||||
|
|
||||||
private List<PEPListener> pepListeners = new ArrayList<PEPListener>();
|
private List<PEPListener> pepListeners = new ArrayList<PEPListener>();
|
||||||
|
|
|
@ -28,6 +28,8 @@ import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
import org.jivesoftware.smackx.packet.XHTMLExtension;
|
import org.jivesoftware.smackx.packet.XHTMLExtension;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages XHTML formatted texts within messages. A XHTMLManager provides a high level access to
|
* Manages XHTML formatted texts within messages. A XHTMLManager provides a high level access to
|
||||||
|
@ -38,6 +40,8 @@ import java.util.Iterator;
|
||||||
*/
|
*/
|
||||||
public class XHTMLManager {
|
public class XHTMLManager {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(XHTMLManager.class.getName());
|
||||||
|
|
||||||
private final static String namespace = "http://jabber.org/protocol/xhtml-im";
|
private final static String namespace = "http://jabber.org/protocol/xhtml-im";
|
||||||
|
|
||||||
// Enable the XHTML support on every established connection
|
// Enable the XHTML support on every established connection
|
||||||
|
@ -137,7 +141,7 @@ public class XHTMLManager {
|
||||||
return result.containsFeature(namespace);
|
return result.containsFeature(namespace);
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error checking if service is available", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -594,7 +594,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public IBBOutputStream() {
|
public IBBOutputStream() {
|
||||||
this.buffer = new byte[(byteStreamRequest.getBlockSize()/4)*3];
|
this.buffer = new byte[byteStreamRequest.getBlockSize()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
@ -67,6 +69,7 @@ import org.jivesoftware.smack.XMPPException;
|
||||||
* @author Henning Staib
|
* @author Henning Staib
|
||||||
*/
|
*/
|
||||||
public class Socks5Proxy {
|
public class Socks5Proxy {
|
||||||
|
private static Logger log = Logger.getLogger(Socks5Proxy.class.getName());
|
||||||
|
|
||||||
/* SOCKS5 proxy singleton */
|
/* SOCKS5 proxy singleton */
|
||||||
private static Socks5Proxy socks5Server;
|
private static Socks5Proxy socks5Server;
|
||||||
|
@ -150,8 +153,7 @@ public class Socks5Proxy {
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
// couldn't setup server
|
// couldn't setup server
|
||||||
System.err.println("couldn't setup local SOCKS5 proxy on port "
|
log.log(Level.SEVERE, "couldn't setup local SOCKS5 proxy on port " + SmackConfiguration.getLocalSocks5ProxyPort(), e);
|
||||||
+ SmackConfiguration.getLocalSocks5ProxyPort() + ": " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An AdHocCommandManager is responsible for keeping the list of available
|
* An AdHocCommandManager is responsible for keeping the list of available
|
||||||
|
@ -58,7 +59,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
* @author Gabriel Guardincerri
|
* @author Gabriel Guardincerri
|
||||||
*/
|
*/
|
||||||
public class AdHocCommandManager {
|
public class AdHocCommandManager {
|
||||||
|
|
||||||
private static final String DISCO_NAMESPACE = "http://jabber.org/protocol/commands";
|
private static final String DISCO_NAMESPACE = "http://jabber.org/protocol/commands";
|
||||||
|
|
||||||
private static final String discoNode = DISCO_NAMESPACE;
|
private static final String discoNode = DISCO_NAMESPACE;
|
||||||
|
@ -470,7 +470,6 @@ public class AdHocCommandManager {
|
||||||
executingCommands.remove(sessionId);
|
executingCommands.remove(sessionId);
|
||||||
}
|
}
|
||||||
respondError(response, error);
|
respondError(response, error);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -527,7 +526,7 @@ public class AdHocCommandManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: Check that all the requierd fields of the form are
|
// TODO: Check that all the required fields of the form are
|
||||||
// TODO: filled, if not throw an exception. This will simplify the
|
// TODO: filled, if not throw an exception. This will simplify the
|
||||||
// TODO: construction of new commands
|
// TODO: construction of new commands
|
||||||
|
|
||||||
|
@ -585,8 +584,6 @@ public class AdHocCommandManager {
|
||||||
executingCommands.remove(sessionId);
|
executingCommands.remove(sessionId);
|
||||||
}
|
}
|
||||||
respondError(response, error);
|
respondError(response, error);
|
||||||
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -650,12 +647,10 @@ public class AdHocCommandManager {
|
||||||
command.setNode(commandInfo.getNode());
|
command.setNode(commandInfo.getNode());
|
||||||
}
|
}
|
||||||
catch (InstantiationException e) {
|
catch (InstantiationException e) {
|
||||||
e.printStackTrace();
|
|
||||||
throw new XMPPException(new XMPPError(
|
throw new XMPPException(new XMPPError(
|
||||||
XMPPError.Condition.interna_server_error));
|
XMPPError.Condition.interna_server_error));
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException e) {
|
catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
|
||||||
throw new XMPPException(new XMPPError(
|
throw new XMPPException(new XMPPError(
|
||||||
XMPPError.Condition.interna_server_error));
|
XMPPError.Condition.interna_server_error));
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@ import java.io.Writer;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The EnhancedDebugger is a debugger that allows to debug sent, received and interpreted messages
|
* The EnhancedDebugger is a debugger that allows to debug sent, received and interpreted messages
|
||||||
|
@ -64,6 +66,8 @@ import java.util.Date;
|
||||||
*/
|
*/
|
||||||
public class EnhancedDebugger implements SmackDebugger {
|
public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(EnhancedDebugger.class.getName());
|
||||||
|
|
||||||
private static final String NEWLINE = "\n";
|
private static final String NEWLINE = "\n";
|
||||||
|
|
||||||
private static ImageIcon packetReceivedIcon;
|
private static ImageIcon packetReceivedIcon;
|
||||||
|
@ -427,7 +431,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
receivedText.replaceRange("", 0, receivedText.getLineEndOffset(0));
|
receivedText.replaceRange("", 0, receivedText.getLineEndOffset(0));
|
||||||
}
|
}
|
||||||
catch (BadLocationException e) {
|
catch (BadLocationException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error with line offset, MAX_TABLE_ROWS is set too low: " + EnhancedDebuggerWindow.MAX_TABLE_ROWS, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
receivedText.append(str.substring(0, index + 1));
|
receivedText.append(str.substring(0, index + 1));
|
||||||
|
@ -462,7 +466,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
sentText.replaceRange("", 0, sentText.getLineEndOffset(0));
|
sentText.replaceRange("", 0, sentText.getLineEndOffset(0));
|
||||||
}
|
}
|
||||||
catch (BadLocationException e) {
|
catch (BadLocationException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error with line offset, MAX_TABLE_ROWS is set too low: " + EnhancedDebuggerWindow.MAX_TABLE_ROWS, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,28 +899,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (TransformerConfigurationException tce) {
|
catch (TransformerConfigurationException tce) {
|
||||||
// Error generated by the parser
|
log.log(Level.SEVERE, "Transformer Factory error", tce);
|
||||||
System.out.println("\n** Transformer Factory error");
|
|
||||||
System.out.println(" " + tce.getMessage());
|
|
||||||
|
|
||||||
// Use the contained exception, if any
|
|
||||||
Throwable x = tce;
|
|
||||||
if (tce.getException() != null)
|
|
||||||
x = tce.getException();
|
|
||||||
x.printStackTrace();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (TransformerException te) {
|
catch (TransformerException te) {
|
||||||
// Error generated by the parser
|
log.log(Level.SEVERE, "Transformation error", te);
|
||||||
System.out.println("\n** Transformation error");
|
|
||||||
System.out.println(" " + te.getMessage());
|
|
||||||
|
|
||||||
// Use the contained exception, if any
|
|
||||||
Throwable x = te;
|
|
||||||
if (te.getException() != null)
|
|
||||||
x = te.getException();
|
|
||||||
x.printStackTrace();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.provider.IQProvider;
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
@ -39,12 +41,13 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||||
/**
|
/**
|
||||||
* Simple implementation of an EntityCapsPersistentCache that uses a directory
|
* Simple implementation of an EntityCapsPersistentCache that uses a directory
|
||||||
* to store the Caps information for every known node. Every node is represented
|
* to store the Caps information for every known node. Every node is represented
|
||||||
* by an file.
|
* by a file.
|
||||||
*
|
*
|
||||||
* @author Florian Schmaus
|
* @author Florian Schmaus
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache {
|
public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache {
|
||||||
|
private static Logger log = Logger.getLogger(SimpleDirectoryPersistentCache.class.getName());
|
||||||
|
|
||||||
private File cacheDir;
|
private File cacheDir;
|
||||||
private StringEncoder filenameEncoder;
|
private StringEncoder filenameEncoder;
|
||||||
|
@ -54,7 +57,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
||||||
* cacheDir exists and that it's an directory.
|
* cacheDir exists and that it's an directory.
|
||||||
* <p>
|
* <p>
|
||||||
* Default filename encoder {@link Base32Encoder}, as this will work on all
|
* Default filename encoder {@link Base32Encoder}, as this will work on all
|
||||||
* filesystems, both case sensitive and case insensitive. It does however
|
* file systems, both case sensitive and case insensitive. It does however
|
||||||
* produce longer filenames.
|
* produce longer filenames.
|
||||||
*
|
*
|
||||||
* @param cacheDir
|
* @param cacheDir
|
||||||
|
@ -91,7 +94,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
||||||
if (nodeFile.createNewFile())
|
if (nodeFile.createNewFile())
|
||||||
writeInfoToFile(nodeFile, info);
|
writeInfoToFile(nodeFile, info);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to write disco info to file", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +163,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
parser.setInput(reader);
|
parser.setInput(reader);
|
||||||
} catch (XmlPullParserException xppe) {
|
} catch (XmlPullParserException xppe) {
|
||||||
xppe.printStackTrace();
|
log.log(Level.SEVERE, "Exception initializing parser", xppe);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
97
source/org/jivesoftware/smackx/forward/Forwarded.java
Normal file
97
source/org/jivesoftware/smackx/forward/Forwarded.java
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.forward;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet extension for <a href="http://xmpp.org/extensions/xep-0297.html">XEP-0297</a>: Stanza Forwarding.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class Forwarded implements PacketExtension {
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:forward:0";
|
||||||
|
public static final String ELEMENT_NAME = "forwarded";
|
||||||
|
|
||||||
|
private DelayInfo delay;
|
||||||
|
private Packet forwardedPacket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Forwarded packet extension.
|
||||||
|
*
|
||||||
|
* @param delay an optional {@link DelayInfo} timestamp of the packet.
|
||||||
|
* @param fwdPacket the packet that is forwarded (required).
|
||||||
|
*/
|
||||||
|
public Forwarded(DelayInfo delay, Packet fwdPacket) {
|
||||||
|
this.delay = delay;
|
||||||
|
this.forwardedPacket = fwdPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Forwarded packet extension.
|
||||||
|
*
|
||||||
|
* @param delay an optional {@link DelayInfo} timestamp of the packet.
|
||||||
|
* @param fwdPacket the packet that is forwarded (required).
|
||||||
|
*/
|
||||||
|
public Forwarded(Packet fwdPacket) {
|
||||||
|
this.forwardedPacket = fwdPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return ELEMENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toXML() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("<").append(getElementName()).append(" xmlns=\"")
|
||||||
|
.append(getNamespace()).append("\">");
|
||||||
|
|
||||||
|
if (delay != null)
|
||||||
|
buf.append(delay.toXML());
|
||||||
|
buf.append(forwardedPacket.toXML());
|
||||||
|
|
||||||
|
buf.append("</").append(getElementName()).append(">");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the packet forwarded by this stanza.
|
||||||
|
*
|
||||||
|
* @return the {@link Packet} instance (typically a message) that was forwarded.
|
||||||
|
*/
|
||||||
|
public Packet getForwardedPacket() {
|
||||||
|
return forwardedPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the timestamp of the forwarded packet.
|
||||||
|
*
|
||||||
|
* @return the {@link DelayInfo} representing the time when the original packet was sent. May be null.
|
||||||
|
*/
|
||||||
|
public DelayInfo getDelayInfo() {
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Georg Lukas
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.forward.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInfo;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the {@link PacketExtensionProvider} to parse
|
||||||
|
* forwarded messages from a packet. It will return a {@link Forwarded} packet extension.
|
||||||
|
*
|
||||||
|
* @author Georg Lukas
|
||||||
|
*/
|
||||||
|
public class ForwardedProvider implements PacketExtensionProvider {
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
DelayInfo di = null;
|
||||||
|
Packet packet = null;
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int eventType = parser.next();
|
||||||
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
if (parser.getName().equals("delay"))
|
||||||
|
di = (DelayInfo)PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser);
|
||||||
|
else if (parser.getName().equals("message"))
|
||||||
|
packet = PacketParserUtils.parseMessage(parser);
|
||||||
|
else throw new Exception("Unsupported forwarded packet type: " + parser.getName());
|
||||||
|
}
|
||||||
|
else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(Forwarded.ELEMENT_NAME))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
if (packet == null)
|
||||||
|
throw new Exception("forwarded extension must contain a packet");
|
||||||
|
return new Forwarded(di, packet);
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Chat;
|
import org.jivesoftware.smack.Chat;
|
||||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
|
@ -76,6 +78,7 @@ import org.jivesoftware.smackx.packet.MUCUser;
|
||||||
* @author Gaston Dombiak, Larry Kirschner
|
* @author Gaston Dombiak, Larry Kirschner
|
||||||
*/
|
*/
|
||||||
public class MultiUserChat {
|
public class MultiUserChat {
|
||||||
|
private static Logger log = Logger.getLogger(MultiUserChat.class.getName());
|
||||||
|
|
||||||
private final static String discoNamespace = "http://jabber.org/protocol/muc";
|
private final static String discoNamespace = "http://jabber.org/protocol/muc";
|
||||||
private final static String discoNode = "http://jabber.org/protocol/muc#rooms";
|
private final static String discoNode = "http://jabber.org/protocol/muc#rooms";
|
||||||
|
@ -179,7 +182,7 @@ public class MultiUserChat {
|
||||||
return result.containsFeature(discoNamespace);
|
return result.containsFeature(discoNamespace);
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error checking user [" + user + "] for MUC support", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +225,7 @@ public class MultiUserChat {
|
||||||
return answer.iterator();
|
return answer.iterator();
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error getting joined rooms for user [" + user + "]", e);
|
||||||
// Return an iterator on an empty collection
|
// Return an iterator on an empty collection
|
||||||
return new ArrayList<String>().iterator();
|
return new ArrayList<String>().iterator();
|
||||||
}
|
}
|
||||||
|
@ -953,13 +956,12 @@ public class MultiUserChat {
|
||||||
DiscoverInfo.Identity identity = identities.next();
|
DiscoverInfo.Identity identity = identities.next();
|
||||||
return identity.getName();
|
return identity.getName();
|
||||||
}
|
}
|
||||||
// If no Identity was found then the user does not have a reserved room nickname
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error retrieving room nickname", e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
// If no Identity was found then the user does not have a reserved room nickname
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2061,11 +2063,11 @@ public class MultiUserChat {
|
||||||
method.invoke(listener, params);
|
method.invoke(listener, params);
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to invoke method on UserStatusListener", e);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to invoke method on UserStatusListener", e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to invoke method on UserStatusListener", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2112,11 +2114,11 @@ public class MultiUserChat {
|
||||||
method.invoke(listener, params.toArray());
|
method.invoke(listener, params.toArray());
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to invoke method on ParticipantStatusListener", e);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to invoke method on ParticipantStatusListener", e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to invoke method on ParticipantStatusListener", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,6 +337,7 @@ public class DiscoverInfo extends IQ {
|
||||||
* 'type' attribute refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
* 'type' attribute refer to <a href="http://www.jabber.org/registrar/disco-categories.html">Jabber::Registrar</a>
|
||||||
*
|
*
|
||||||
* @param type the identity's type.
|
* @param type the identity's type.
|
||||||
|
* @deprecated As per the spec, this field is mandatory and the 3 argument constructor should be used instead.
|
||||||
*/
|
*/
|
||||||
public void setType(String type) {
|
public void setType(String type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class PEPEvent implements PacketExtension {
|
public class PEPEvent implements PacketExtension {
|
||||||
|
|
||||||
PEPItem item;
|
PEPItem item;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract class PEPItem implements PacketExtension {
|
public abstract class PEPItem implements PacketExtension {
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.IQ;
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class PEPPubSub extends IQ {
|
public class PEPPubSub extends IQ {
|
||||||
|
|
||||||
PEPItem item;
|
PEPItem item;
|
||||||
|
|
|
@ -27,6 +27,8 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Time IQ packet, which is used by XMPP clients to exchange their respective local
|
* A Time IQ packet, which is used by XMPP clients to exchange their respective local
|
||||||
|
@ -61,6 +63,7 @@ import java.util.TimeZone;
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
*/
|
*/
|
||||||
public class Time extends IQ {
|
public class Time extends IQ {
|
||||||
|
private static Logger log = Logger.getLogger(Time.class.getName());
|
||||||
|
|
||||||
private static SimpleDateFormat utcFormat = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
private static SimpleDateFormat utcFormat = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
|
||||||
private static DateFormat displayFormat = DateFormat.getDateTimeInstance();
|
private static DateFormat displayFormat = DateFormat.getDateTimeInstance();
|
||||||
|
@ -94,7 +97,7 @@ public class Time extends IQ {
|
||||||
/**
|
/**
|
||||||
* Returns the local time or <tt>null</tt> if the time hasn't been set.
|
* Returns the local time or <tt>null</tt> if the time hasn't been set.
|
||||||
*
|
*
|
||||||
* @return the lcocal time.
|
* @return the local time.
|
||||||
*/
|
*/
|
||||||
public Date getTime() {
|
public Date getTime() {
|
||||||
if (utc == null) {
|
if (utc == null) {
|
||||||
|
@ -109,7 +112,7 @@ public class Time extends IQ {
|
||||||
date = cal.getTime();
|
date = cal.getTime();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error getting local time", e);
|
||||||
}
|
}
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Connection;
|
import org.jivesoftware.smack.Connection;
|
||||||
import org.jivesoftware.smack.PacketCollector;
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
@ -85,6 +87,8 @@ import org.jivesoftware.smack.util.StringUtils;
|
||||||
* @author Kirill Maximov (kir@maxkir.com)
|
* @author Kirill Maximov (kir@maxkir.com)
|
||||||
*/
|
*/
|
||||||
public class VCard extends IQ {
|
public class VCard extends IQ {
|
||||||
|
private static Logger log = Logger.getLogger(VCard.class.getName());
|
||||||
|
|
||||||
private static final String DEFAULT_MIME_TYPE = "image/jpeg";
|
private static final String DEFAULT_MIME_TYPE = "image/jpeg";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -332,7 +336,7 @@ public class VCard extends IQ {
|
||||||
bytes = getBytes(avatarURL);
|
bytes = getBytes(avatarURL);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error getting bytes from URL: " + avatarURL, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAvatar(bytes);
|
setAvatar(bytes);
|
||||||
|
@ -489,7 +493,7 @@ public class VCard extends IQ {
|
||||||
digest = MessageDigest.getInstance("SHA-1");
|
digest = MessageDigest.getInstance("SHA-1");
|
||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e) {
|
catch (NoSuchAlgorithmException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to get message digest", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,7 +586,7 @@ public class VCard extends IQ {
|
||||||
result = (VCard) packet;
|
result = (VCard) packet;
|
||||||
}
|
}
|
||||||
catch (ClassCastException e) {
|
catch (ClassCastException e) {
|
||||||
System.out.println("No VCard for " + user);
|
log.log(Level.SEVERE, "No VCard for " + user, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.jivesoftware.smackx.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.provider.UrlProviderFileInitializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the default provider file for the Smack extensions on initialization.
|
||||||
|
*
|
||||||
|
* @author Robin Collier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExtensionInitializer extends UrlProviderFileInitializer {
|
||||||
|
@Override
|
||||||
|
protected String getFilePath() {
|
||||||
|
return "classpath:META-INF/extension.providers";
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ package org.jivesoftware.smackx.provider;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.provider.IQProvider;
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
@ -37,6 +39,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class StreamInitiationProvider implements IQProvider {
|
public class StreamInitiationProvider implements IQProvider {
|
||||||
|
private static Logger log = Logger.getLogger(StreamInitiationProvider.class.getName());
|
||||||
|
|
||||||
public IQ parseIQ(final XmlPullParser parser) throws Exception {
|
public IQ parseIQ(final XmlPullParser parser) throws Exception {
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
@ -90,7 +93,7 @@ public class StreamInitiationProvider implements IQProvider {
|
||||||
fileSize = Long.parseLong(size);
|
fileSize = Long.parseLong(size);
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Failed to parse file size from " + fileSize, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vCard provider.
|
* vCard provider.
|
||||||
|
@ -42,6 +44,7 @@ import java.util.List;
|
||||||
* @author Derek DeMoro
|
* @author Derek DeMoro
|
||||||
*/
|
*/
|
||||||
public class VCardProvider implements IQProvider {
|
public class VCardProvider implements IQProvider {
|
||||||
|
private static Logger log = Logger.getLogger(VCardProvider.class.getName());
|
||||||
|
|
||||||
private static final String PREFERRED_ENCODING = "UTF-8";
|
private static final String PREFERRED_ENCODING = "UTF-8";
|
||||||
|
|
||||||
|
@ -71,10 +74,10 @@ public class VCardProvider implements IQProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (XmlPullParserException e) {
|
catch (XmlPullParserException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Exception parsing VCard", e);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Exception parsing VCard", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
String xmlText = sb.toString();
|
String xmlText = sb.toString();
|
||||||
|
|
|
@ -22,36 +22,27 @@ package org.jivesoftware.smack;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.ChatManager.MatchMode;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
import org.jivesoftware.smack.packet.Message.Type;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that verifies the correct behavior of the {@see Roster} implementation.
|
|
||||||
*
|
|
||||||
* @see Roster
|
|
||||||
* @see <a href="http://xmpp.org/rfcs/rfc3921.html#roster">Roster Management</a>
|
|
||||||
* @author Guenther Niess
|
|
||||||
*/
|
|
||||||
public class ChatConnectionTest {
|
public class ChatConnectionTest {
|
||||||
|
|
||||||
private DummyConnection connection;
|
private DummyConnection connection;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
// Uncomment this to enable debug output
|
connection = getConnection();
|
||||||
//Connection.DEBUG_ENABLED = true;
|
|
||||||
|
|
||||||
connection = new DummyConnection();
|
|
||||||
connection.connect();
|
|
||||||
connection.login("me", "secret");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -60,47 +51,176 @@ public class ChatConnectionTest {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Confirm that a new chat is created when a chat message is received but
|
|
||||||
* there is no thread id for a user with only a base jid.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void chatCreatedWithIncomingChatNoThreadBaseJid()
|
public void validateDefaultSetNormalIncluded() {
|
||||||
{
|
ChatManager.setDefaultIsNormalIncluded(false);
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
assertFalse(getConnection().getChatManager().isNormalIncluded());
|
||||||
connection.getChatManager().addChatListener(listener);
|
|
||||||
|
|
||||||
Packet incomingChat = createChatPacket(null, false);
|
ChatManager.setDefaultIsNormalIncluded(true);
|
||||||
processServerMessage(incomingChat);
|
assertTrue(getConnection().getChatManager().isNormalIncluded());
|
||||||
|
|
||||||
Chat newChat = listener.getNewChat();
|
|
||||||
assertNotNull(newChat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Confirm that a new chat is created when a chat message is received but
|
|
||||||
* there is no thread id for a user with a full jid.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void chatCreatedWhenIncomingChatNoThreadFullJid()
|
public void validateDefaultSetMatchMode() {
|
||||||
{
|
ChatManager.setDefaultMatchMode(MatchMode.NONE);
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
assertEquals(MatchMode.NONE, getConnection().getChatManager().getMatchMode());
|
||||||
connection.getChatManager().addChatListener(listener);
|
|
||||||
|
|
||||||
|
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
|
||||||
|
assertEquals(MatchMode.BARE_JID, getConnection().getChatManager().getMatchMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateMessageTypeWithDefaults() {
|
||||||
|
DummyConnection dc = getConnection();
|
||||||
|
ChatManager cm = dc.getChatManager();
|
||||||
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
Message incomingChat = createChatPacket("134", true);
|
||||||
|
incomingChat.setType(Type.chat);
|
||||||
|
processServerMessage(incomingChat, dc);
|
||||||
|
assertNotNull(listener.getNewChat());
|
||||||
|
|
||||||
|
dc = getConnection();
|
||||||
|
cm = dc.getChatManager();
|
||||||
|
listener = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
incomingChat = createChatPacket("134", true);
|
||||||
|
incomingChat.setType(Type.normal);
|
||||||
|
processServerMessage(incomingChat, dc);
|
||||||
|
assertNotNull(listener.getNewChat());
|
||||||
|
|
||||||
|
dc = getConnection();
|
||||||
|
cm = dc.getChatManager();
|
||||||
|
listener = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
incomingChat = createChatPacket("134", true);
|
||||||
|
incomingChat.setType(Type.groupchat);
|
||||||
|
processServerMessage(incomingChat, dc);
|
||||||
|
assertNull(listener.getNewChat());
|
||||||
|
|
||||||
|
dc = getConnection();
|
||||||
|
cm = dc.getChatManager();
|
||||||
|
listener = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
incomingChat = createChatPacket("134", true);
|
||||||
|
incomingChat.setType(Type.headline);
|
||||||
|
processServerMessage(incomingChat, dc);
|
||||||
|
assertNull(listener.getNewChat());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateMessageTypeWithNoNormal() {
|
||||||
|
ChatManager.setDefaultIsNormalIncluded(false);
|
||||||
|
DummyConnection dc = getConnection();
|
||||||
|
ChatManager cm = dc.getChatManager();
|
||||||
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
Message incomingChat = createChatPacket("134", true);
|
||||||
|
incomingChat.setType(Type.chat);
|
||||||
|
processServerMessage(incomingChat, dc);
|
||||||
|
assertNotNull(listener.getNewChat());
|
||||||
|
|
||||||
|
dc = getConnection();
|
||||||
|
cm = dc.getChatManager();
|
||||||
|
listener = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
incomingChat = createChatPacket("134", true);
|
||||||
|
incomingChat.setType(Type.normal);
|
||||||
|
processServerMessage(incomingChat, dc);
|
||||||
|
assertNull(listener.getNewChat());
|
||||||
|
}
|
||||||
|
|
||||||
|
// No thread behaviour
|
||||||
|
@Test
|
||||||
|
public void chatMatchedOnJIDWhenNoThreadBareMode() {
|
||||||
|
// MatchMode.BARE_JID is the default, so setting required.
|
||||||
|
DummyConnection con = getConnection();
|
||||||
|
TestMessageListener msgListener = new TestMessageListener();
|
||||||
|
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||||
|
con.getChatManager().addChatListener(listener);
|
||||||
Packet incomingChat = createChatPacket(null, true);
|
Packet incomingChat = createChatPacket(null, true);
|
||||||
processServerMessage(incomingChat);
|
processServerMessage(incomingChat, con);
|
||||||
|
|
||||||
Chat newChat = listener.getNewChat();
|
Chat newChat = listener.getNewChat();
|
||||||
assertNotNull(newChat);
|
assertNotNull(newChat);
|
||||||
|
|
||||||
|
// Should match on chat with full jid
|
||||||
|
incomingChat = createChatPacket(null, true);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
assertEquals(2, msgListener.getNumMessages());
|
||||||
|
|
||||||
|
// Should match on chat with bare jid
|
||||||
|
incomingChat = createChatPacket(null, false);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
assertEquals(3, msgListener.getNumMessages());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chatMatchedOnJIDWhenNoThreadJidMode() {
|
||||||
|
DummyConnection con = getConnection();
|
||||||
|
TestMessageListener msgListener = new TestMessageListener();
|
||||||
|
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||||
|
ChatManager cm = con.getChatManager();
|
||||||
|
cm.setMatchMode(MatchMode.SUPPLIED_JID);
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
Packet incomingChat = createChatPacket(null, true);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
Chat newChat = listener.getNewChat();
|
||||||
|
assertNotNull(newChat);
|
||||||
|
cm.removeChatListener(listener);
|
||||||
|
|
||||||
|
// Should match on chat with full jid
|
||||||
|
incomingChat = createChatPacket(null, true);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
assertEquals(2, msgListener.getNumMessages());
|
||||||
|
|
||||||
|
// Should not match on chat with bare jid
|
||||||
|
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener2);
|
||||||
|
incomingChat = createChatPacket(null, false);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
assertEquals(2, msgListener.getNumMessages());
|
||||||
|
assertNotNull(listener2.getNewChat());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void chatMatchedOnJIDWhenNoThreadNoneMode() {
|
||||||
|
DummyConnection con = getConnection();
|
||||||
|
TestMessageListener msgListener = new TestMessageListener();
|
||||||
|
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||||
|
ChatManager cm = con.getChatManager();
|
||||||
|
cm.setMatchMode(MatchMode.NONE);
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
Packet incomingChat = createChatPacket(null, true);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
Chat newChat = listener.getNewChat();
|
||||||
|
assertNotNull(newChat);
|
||||||
|
assertEquals(1, msgListener.getNumMessages());
|
||||||
|
cm.removeChatListener(listener);
|
||||||
|
|
||||||
|
// Should not match on chat with full jid
|
||||||
|
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener2);
|
||||||
|
incomingChat = createChatPacket(null, true);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
assertEquals(1, msgListener.getNumMessages());
|
||||||
|
assertNotNull(newChat);
|
||||||
|
cm.removeChatListener(listener2);
|
||||||
|
|
||||||
|
// Should not match on chat with bare jid
|
||||||
|
TestChatManagerListener listener3 = new TestChatManagerListener();
|
||||||
|
cm.addChatListener(listener3);
|
||||||
|
incomingChat = createChatPacket(null, false);
|
||||||
|
processServerMessage(incomingChat, con);
|
||||||
|
assertEquals(1, msgListener.getNumMessages());
|
||||||
|
assertNotNull(listener3.getNewChat());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that an existing chat created with a base jid is matched to an
|
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||||
* incoming chat message that has no thread id and the user is a full jid.
|
* id and the user is a full jid.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void chatFoundWhenNoThreadFullJid()
|
public void chatFoundWhenNoThreadFullJid() {
|
||||||
{
|
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
connection.getChatManager().addChatListener(listener);
|
connection.getChatManager().addChatListener(listener);
|
||||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||||
|
@ -114,12 +234,11 @@ public class ChatConnectionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that an existing chat created with a base jid is matched to an
|
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||||
* incoming chat message that has no thread id and the user is a base jid.
|
* id and the user is a base jid.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void chatFoundWhenNoThreadBaseJid()
|
public void chatFoundWhenNoThreadBaseJid() {
|
||||||
{
|
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
connection.getChatManager().addChatListener(listener);
|
connection.getChatManager().addChatListener(listener);
|
||||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||||
|
@ -133,12 +252,11 @@ public class ChatConnectionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that an existing chat created with a base jid is matched to an
|
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||||
* incoming chat message that has the same id and the user is a full jid.
|
* and the user is a full jid.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void chatFoundWithSameThreadFullJid()
|
public void chatFoundWithSameThreadFullJid() {
|
||||||
{
|
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
connection.getChatManager().addChatListener(listener);
|
connection.getChatManager().addChatListener(listener);
|
||||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||||
|
@ -152,12 +270,11 @@ public class ChatConnectionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that an existing chat created with a base jid is matched to an
|
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||||
* incoming chat message that has the same id and the user is a base jid.
|
* and the user is a base jid.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void chatFoundWithSameThreadBaseJid()
|
public void chatFoundWithSameThreadBaseJid() {
|
||||||
{
|
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
connection.getChatManager().addChatListener(listener);
|
connection.getChatManager().addChatListener(listener);
|
||||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||||
|
@ -171,14 +288,11 @@ public class ChatConnectionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that an existing chat created with a base jid is not matched to
|
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||||
* an incoming chat message that has a different id and the same user as a
|
* different id and the same user as a base jid.
|
||||||
* base jid.
|
|
||||||
*/
|
*/
|
||||||
@Ignore
|
|
||||||
@Test
|
@Test
|
||||||
public void chatNotFoundWithDiffThreadBaseJid()
|
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||||
{
|
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
connection.getChatManager().addChatListener(listener);
|
connection.getChatManager().addChatListener(listener);
|
||||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||||
|
@ -192,13 +306,11 @@ public class ChatConnectionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that an existing chat created with a base jid is not matched to
|
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||||
* an incoming chat message that has a different id and the same base jid.
|
* different id and the same base jid.
|
||||||
*/
|
*/
|
||||||
@Ignore
|
|
||||||
@Test
|
@Test
|
||||||
public void chatNotFoundWithDiffThreadFullJid()
|
public void chatNotFoundWithDiffThreadFullJid() {
|
||||||
{
|
|
||||||
TestChatManagerListener listener = new TestChatManagerListener();
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
connection.getChatManager().addChatListener(listener);
|
connection.getChatManager().addChatListener(listener);
|
||||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||||
|
@ -211,78 +323,118 @@ public class ChatConnectionTest {
|
||||||
assertFalse(newChat == outgoing);
|
assertFalse(newChat == outgoing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Packet createChatPacket(final String threadId, final boolean isFullJid)
|
@Test
|
||||||
{
|
public void chatNotMatchedWithTypeNormal() {
|
||||||
|
TestChatManagerListener listener = new TestChatManagerListener();
|
||||||
|
DummyConnection con = getConnection();
|
||||||
|
ChatManager cm = con.getChatManager();
|
||||||
|
cm.setNormalIncluded(false);
|
||||||
|
cm.addChatListener(listener);
|
||||||
|
|
||||||
|
Message incomingChat = createChatPacket(null, false);
|
||||||
|
incomingChat.setType(Type.normal);
|
||||||
|
processServerMessage(incomingChat);
|
||||||
|
|
||||||
|
assertNull(listener.getNewChat());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatManager getChatManager(boolean includeNormal, MatchMode mode) {
|
||||||
|
ChatManager cm = getConnection().getChatManager();
|
||||||
|
cm.setMatchMode(mode);
|
||||||
|
cm.setNormalIncluded(includeNormal);
|
||||||
|
return cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DummyConnection getConnection() {
|
||||||
|
DummyConnection con = new DummyConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
con.connect();
|
||||||
|
con.login("me", "secret");
|
||||||
|
} catch (XMPPException e) {
|
||||||
|
// No need for handling in a dummy connection.
|
||||||
|
}
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
private Message createChatPacket(final String threadId, final boolean isFullJid) {
|
||||||
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
||||||
chatMsg.setBody("the body message");
|
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||||
|
|
||||||
if (threadId != null)
|
if (threadId != null)
|
||||||
chatMsg.addExtension(new PacketExtension()
|
chatMsg.setThread(threadId);
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public String toXML()
|
|
||||||
{
|
|
||||||
return "<thread>" + threadId + "</thread>";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNamespace()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getElementName()
|
|
||||||
{
|
|
||||||
return "thread";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return chatMsg;
|
return chatMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processServerMessage(Packet incomingChat)
|
private void processServerMessage(Packet incomingChat) {
|
||||||
{
|
processServerMessage(incomingChat, connection);
|
||||||
TestChatServer chatServer = new TestChatServer(incomingChat);
|
}
|
||||||
|
|
||||||
|
private void processServerMessage(Packet incomingChat, DummyConnection con) {
|
||||||
|
TestChatServer chatServer = new TestChatServer(incomingChat, con);
|
||||||
chatServer.start();
|
chatServer.start();
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
chatServer.join();
|
chatServer.join();
|
||||||
} catch (InterruptedException e)
|
} catch (InterruptedException e) {
|
||||||
{
|
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestChatManagerListener implements ChatManagerListener
|
class TestChatManagerListener implements ChatManagerListener {
|
||||||
{
|
|
||||||
private Chat newChat;
|
private Chat newChat;
|
||||||
|
private MessageListener listener;
|
||||||
|
|
||||||
@Override
|
public TestChatManagerListener(TestMessageListener msgListener) {
|
||||||
public void chatCreated(Chat chat, boolean createdLocally)
|
listener = msgListener;
|
||||||
{
|
|
||||||
newChat = chat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chat getNewChat()
|
public TestChatManagerListener() {
|
||||||
{
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void chatCreated(Chat chat, boolean createdLocally) {
|
||||||
|
newChat = chat;
|
||||||
|
|
||||||
|
if (listener != null)
|
||||||
|
newChat.addMessageListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chat getNewChat() {
|
||||||
return newChat;
|
return newChat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestChatServer extends Thread
|
private class TestChatServer extends Thread {
|
||||||
{
|
|
||||||
private Packet chatPacket;
|
private Packet chatPacket;
|
||||||
|
private DummyConnection con;
|
||||||
|
|
||||||
TestChatServer(Packet chatMsg)
|
TestChatServer(Packet chatMsg, DummyConnection conect) {
|
||||||
{
|
|
||||||
chatPacket = chatMsg;
|
chatPacket = chatMsg;
|
||||||
|
con = conect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run() {
|
||||||
{
|
con.processPacket(chatPacket);
|
||||||
connection.processPacket(chatPacket);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestMessageListener implements MessageListener {
|
||||||
|
private Chat msgChat;
|
||||||
|
private int counter = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processMessage(Chat chat, Message message) {
|
||||||
|
msgChat = chat;
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chat getChat() {
|
||||||
|
return msgChat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumMessages() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,14 @@ import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.Connection;
|
||||||
|
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||||
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
|
import org.jivesoftware.smack.ConnectionListener;
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.Roster;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.Connection.ListenerWrapper;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.jivesoftware.smack.keepalive;
|
package org.jivesoftware.smack.keepalive;
|
||||||
|
|
||||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -13,16 +12,13 @@ import org.jivesoftware.smack.DummyConnection;
|
||||||
import org.jivesoftware.smack.PacketInterceptor;
|
import org.jivesoftware.smack.PacketInterceptor;
|
||||||
import org.jivesoftware.smack.PacketListener;
|
import org.jivesoftware.smack.PacketListener;
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
import org.jivesoftware.smack.TestUtils;
|
|
||||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||||
import org.jivesoftware.smack.filter.IQTypeFilter;
|
import org.jivesoftware.smack.filter.IQTypeFilter;
|
||||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||||
import org.jivesoftware.smack.keepalive.KeepAliveManager;
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.ping.PingFailedListener;
|
import org.jivesoftware.smack.ping.PingFailedListener;
|
||||||
import org.jivesoftware.smack.ping.packet.Ping;
|
import org.jivesoftware.smack.ping.packet.Ping;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -2,8 +2,8 @@ package org.jivesoftware.smack.packet;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.jivesoftware.smack.TestUtils;
|
|
||||||
import org.jivesoftware.smack.packet.StreamError;
|
import org.jivesoftware.smack.packet.StreamError;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
|
@ -3,11 +3,11 @@ package org.jivesoftware.smack.parsing;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
import org.jivesoftware.smack.TestUtils;
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
import org.jivesoftware.smack.provider.ProviderManager;
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smack;
|
package org.jivesoftware.smack.test.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
|
@ -24,10 +24,10 @@ import java.util.TimeZone;
|
||||||
|
|
||||||
import org.custommonkey.xmlunit.DetailedDiff;
|
import org.custommonkey.xmlunit.DetailedDiff;
|
||||||
import org.custommonkey.xmlunit.Diff;
|
import org.custommonkey.xmlunit.Diff;
|
||||||
import org.jivesoftware.smack.TestUtils;
|
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
import org.jivesoftware.smackx.packet.DelayInformation;
|
import org.jivesoftware.smackx.packet.DelayInformation;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -57,7 +57,6 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
String sessionID = "session_id";
|
String sessionID = "session_id";
|
||||||
|
|
||||||
int blockSize = 10;
|
int blockSize = 10;
|
||||||
int dataSize = blockSize/4 * 3;
|
|
||||||
|
|
||||||
// protocol verifier
|
// protocol verifier
|
||||||
Protocol protocol;
|
Protocol protocol;
|
||||||
|
@ -120,7 +119,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
protocol.addResponse(null, incrementingSequence);
|
protocol.addResponse(null, incrementingSequence);
|
||||||
protocol.addResponse(null, incrementingSequence);
|
protocol.addResponse(null, incrementingSequence);
|
||||||
|
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
OutputStream outputStream = session.getOutputStream();
|
OutputStream outputStream = session.getOutputStream();
|
||||||
outputStream.write(controlData);
|
outputStream.write(controlData);
|
||||||
|
@ -145,7 +144,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
protocol.addResponse(null, incrementingSequence);
|
protocol.addResponse(null, incrementingSequence);
|
||||||
protocol.addResponse(null, incrementingSequence);
|
protocol.addResponse(null, incrementingSequence);
|
||||||
|
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
OutputStream outputStream = session.getOutputStream();
|
OutputStream outputStream = session.getOutputStream();
|
||||||
for (byte b : controlData) {
|
for (byte b : controlData) {
|
||||||
|
@ -172,11 +171,11 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
protocol.addResponse(null, incrementingSequence);
|
protocol.addResponse(null, incrementingSequence);
|
||||||
protocol.addResponse(null, incrementingSequence);
|
protocol.addResponse(null, incrementingSequence);
|
||||||
|
|
||||||
byte[] controlData = new byte[(dataSize * 3) - 2];
|
byte[] controlData = new byte[(blockSize * 3) - 2];
|
||||||
|
|
||||||
OutputStream outputStream = session.getOutputStream();
|
OutputStream outputStream = session.getOutputStream();
|
||||||
int off = 0;
|
int off = 0;
|
||||||
for (int i = 1; off+i <= controlData.length; i++) {
|
for (int i = 1; i <= 7; i++) {
|
||||||
outputStream.write(controlData, off, i);
|
outputStream.write(controlData, off, i);
|
||||||
off += i;
|
off += i;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +192,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void shouldSendThirtyDataPackets() throws Exception {
|
public void shouldSendThirtyDataPackets() throws Exception {
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||||
initiatorJID);
|
initiatorJID);
|
||||||
|
@ -220,7 +219,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception {
|
public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception {
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||||
initiatorJID);
|
initiatorJID);
|
||||||
|
@ -291,7 +290,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
public void shouldReadAllReceivedData1() throws Exception {
|
public void shouldReadAllReceivedData1() throws Exception {
|
||||||
// create random data
|
// create random data
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
byte[] controlData = new byte[3 * dataSize];
|
byte[] controlData = new byte[3 * blockSize];
|
||||||
rand.nextBytes(controlData);
|
rand.nextBytes(controlData);
|
||||||
|
|
||||||
// get IBB sessions data packet listener
|
// get IBB sessions data packet listener
|
||||||
|
@ -301,8 +300,8 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||||
|
|
||||||
// verify data packet and notify listener
|
// verify data packet and notify listener
|
||||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||||
false);
|
false);
|
||||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||||
Message dataMessage = new Message();
|
Message dataMessage = new Message();
|
||||||
|
@ -310,14 +309,14 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
listener.processPacket(dataMessage);
|
listener.processPacket(dataMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = new byte[3 * dataSize];
|
byte[] bytes = new byte[3 * blockSize];
|
||||||
int read = 0;
|
int read = 0;
|
||||||
read = inputStream.read(bytes, 0, dataSize);
|
read = inputStream.read(bytes, 0, blockSize);
|
||||||
assertEquals(dataSize, read);
|
assertEquals(blockSize, read);
|
||||||
read = inputStream.read(bytes, dataSize, dataSize);
|
read = inputStream.read(bytes, 10, blockSize);
|
||||||
assertEquals(dataSize, read);
|
assertEquals(blockSize, read);
|
||||||
read = inputStream.read(bytes, dataSize*2, dataSize);
|
read = inputStream.read(bytes, 20, blockSize);
|
||||||
assertEquals(dataSize, read);
|
assertEquals(blockSize, read);
|
||||||
|
|
||||||
// verify data
|
// verify data
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
@ -337,7 +336,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
public void shouldReadAllReceivedData2() throws Exception {
|
public void shouldReadAllReceivedData2() throws Exception {
|
||||||
// create random data
|
// create random data
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
byte[] controlData = new byte[3 * dataSize];
|
byte[] controlData = new byte[3 * blockSize];
|
||||||
rand.nextBytes(controlData);
|
rand.nextBytes(controlData);
|
||||||
|
|
||||||
// get IBB sessions data packet listener
|
// get IBB sessions data packet listener
|
||||||
|
@ -347,8 +346,8 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||||
|
|
||||||
// verify data packet and notify listener
|
// verify data packet and notify listener
|
||||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||||
false);
|
false);
|
||||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||||
Message dataMessage = new Message();
|
Message dataMessage = new Message();
|
||||||
|
@ -357,7 +356,7 @@ public class InBandBytestreamSessionMessageTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// read data
|
// read data
|
||||||
byte[] bytes = new byte[3 * dataSize];
|
byte[] bytes = new byte[3 * blockSize];
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
bytes[i] = (byte) inputStream.read();
|
bytes[i] = (byte) inputStream.read();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,7 @@ public class InBandBytestreamSessionTest {
|
||||||
String xmppServer = "xmpp-server";
|
String xmppServer = "xmpp-server";
|
||||||
String sessionID = "session_id";
|
String sessionID = "session_id";
|
||||||
|
|
||||||
int blockSize = 20;
|
int blockSize = 10;
|
||||||
int dataSize = blockSize/4 * 3;
|
|
||||||
|
|
||||||
// protocol verifier
|
// protocol verifier
|
||||||
Protocol protocol;
|
Protocol protocol;
|
||||||
|
@ -120,7 +119,7 @@ public class InBandBytestreamSessionTest {
|
||||||
protocol.addResponse(resultIQ, incrementingSequence);
|
protocol.addResponse(resultIQ, incrementingSequence);
|
||||||
protocol.addResponse(resultIQ, incrementingSequence);
|
protocol.addResponse(resultIQ, incrementingSequence);
|
||||||
|
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
OutputStream outputStream = session.getOutputStream();
|
OutputStream outputStream = session.getOutputStream();
|
||||||
outputStream.write(controlData);
|
outputStream.write(controlData);
|
||||||
|
@ -146,7 +145,7 @@ public class InBandBytestreamSessionTest {
|
||||||
protocol.addResponse(resultIQ, incrementingSequence);
|
protocol.addResponse(resultIQ, incrementingSequence);
|
||||||
protocol.addResponse(resultIQ, incrementingSequence);
|
protocol.addResponse(resultIQ, incrementingSequence);
|
||||||
|
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
OutputStream outputStream = session.getOutputStream();
|
OutputStream outputStream = session.getOutputStream();
|
||||||
for (byte b : controlData) {
|
for (byte b : controlData) {
|
||||||
|
@ -174,11 +173,11 @@ public class InBandBytestreamSessionTest {
|
||||||
protocol.addResponse(resultIQ, incrementingSequence);
|
protocol.addResponse(resultIQ, incrementingSequence);
|
||||||
protocol.addResponse(resultIQ, incrementingSequence);
|
protocol.addResponse(resultIQ, incrementingSequence);
|
||||||
|
|
||||||
byte[] controlData = new byte[(dataSize * 3) - 2];
|
byte[] controlData = new byte[(blockSize * 3) - 2];
|
||||||
|
|
||||||
OutputStream outputStream = session.getOutputStream();
|
OutputStream outputStream = session.getOutputStream();
|
||||||
int off = 0;
|
int off = 0;
|
||||||
for (int i = 1; i+off <= controlData.length; i++) {
|
for (int i = 1; i <= 7; i++) {
|
||||||
outputStream.write(controlData, off, i);
|
outputStream.write(controlData, off, i);
|
||||||
off += i;
|
off += i;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +194,7 @@ public class InBandBytestreamSessionTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void shouldSendThirtyDataPackets() throws Exception {
|
public void shouldSendThirtyDataPackets() throws Exception {
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||||
initiatorJID);
|
initiatorJID);
|
||||||
|
@ -223,7 +222,7 @@ public class InBandBytestreamSessionTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception {
|
public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception {
|
||||||
byte[] controlData = new byte[dataSize * 3];
|
byte[] controlData = new byte[blockSize * 3];
|
||||||
|
|
||||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||||
initiatorJID);
|
initiatorJID);
|
||||||
|
@ -254,7 +253,7 @@ public class InBandBytestreamSessionTest {
|
||||||
public void shouldSendDataCorrectly() throws Exception {
|
public void shouldSendDataCorrectly() throws Exception {
|
||||||
// create random data
|
// create random data
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
final byte[] controlData = new byte[256 * dataSize];
|
final byte[] controlData = new byte[256 * blockSize];
|
||||||
rand.nextBytes(controlData);
|
rand.nextBytes(controlData);
|
||||||
|
|
||||||
// compares the data of each packet with the control data
|
// compares the data of each packet with the control data
|
||||||
|
@ -264,7 +263,7 @@ public class InBandBytestreamSessionTest {
|
||||||
byte[] decodedData = request.getDataPacketExtension().getDecodedData();
|
byte[] decodedData = request.getDataPacketExtension().getDecodedData();
|
||||||
int seq = (int) request.getDataPacketExtension().getSeq();
|
int seq = (int) request.getDataPacketExtension().getSeq();
|
||||||
for (int i = 0; i < decodedData.length; i++) {
|
for (int i = 0; i < decodedData.length; i++) {
|
||||||
assertEquals(controlData[(seq * dataSize) + i], decodedData[i]);
|
assertEquals(controlData[(seq * blockSize) + i], decodedData[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +271,7 @@ public class InBandBytestreamSessionTest {
|
||||||
|
|
||||||
// set acknowledgments for the data packets
|
// set acknowledgments for the data packets
|
||||||
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
||||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||||
protocol.addResponse(resultIQ, incrementingSequence, dataVerification);
|
protocol.addResponse(resultIQ, incrementingSequence, dataVerification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +479,7 @@ public class InBandBytestreamSessionTest {
|
||||||
public void shouldReadAllReceivedData1() throws Exception {
|
public void shouldReadAllReceivedData1() throws Exception {
|
||||||
// create random data
|
// create random data
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
byte[] controlData = new byte[3 * dataSize];
|
byte[] controlData = new byte[3 * blockSize];
|
||||||
rand.nextBytes(controlData);
|
rand.nextBytes(controlData);
|
||||||
|
|
||||||
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
||||||
|
@ -491,24 +490,24 @@ public class InBandBytestreamSessionTest {
|
||||||
InputStream inputStream = session.getInputStream();
|
InputStream inputStream = session.getInputStream();
|
||||||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||||
|
|
||||||
// set data packet acknowledgement and notify listener
|
// set data packet acknowledgment and notify listener
|
||||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||||
protocol.addResponse(resultIQ);
|
protocol.addResponse(resultIQ);
|
||||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||||
false);
|
false);
|
||||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||||
Data data = new Data(dpe);
|
Data data = new Data(dpe);
|
||||||
listener.processPacket(data);
|
listener.processPacket(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = new byte[3 * dataSize];
|
byte[] bytes = new byte[3 * blockSize];
|
||||||
int read = 0;
|
int read = 0;
|
||||||
read = inputStream.read(bytes, 0, dataSize);
|
read = inputStream.read(bytes, 0, blockSize);
|
||||||
assertEquals(dataSize, read);
|
assertEquals(blockSize, read);
|
||||||
read = inputStream.read(bytes, dataSize, dataSize);
|
read = inputStream.read(bytes, 10, blockSize);
|
||||||
assertEquals(dataSize, read);
|
assertEquals(blockSize, read);
|
||||||
read = inputStream.read(bytes, dataSize*2, dataSize);
|
read = inputStream.read(bytes, 20, blockSize);
|
||||||
assertEquals(dataSize, read);
|
assertEquals(blockSize, read);
|
||||||
|
|
||||||
// verify data
|
// verify data
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
@ -528,7 +527,7 @@ public class InBandBytestreamSessionTest {
|
||||||
public void shouldReadAllReceivedData2() throws Exception {
|
public void shouldReadAllReceivedData2() throws Exception {
|
||||||
// create random data
|
// create random data
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
byte[] controlData = new byte[3 * dataSize];
|
byte[] controlData = new byte[3 * blockSize];
|
||||||
rand.nextBytes(controlData);
|
rand.nextBytes(controlData);
|
||||||
|
|
||||||
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
||||||
|
@ -540,9 +539,9 @@ public class InBandBytestreamSessionTest {
|
||||||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||||
|
|
||||||
// set data packet acknowledgment and notify listener
|
// set data packet acknowledgment and notify listener
|
||||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||||
protocol.addResponse(resultIQ);
|
protocol.addResponse(resultIQ);
|
||||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||||
false);
|
false);
|
||||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||||
Data data = new Data(dpe);
|
Data data = new Data(dpe);
|
||||||
|
@ -550,7 +549,7 @@ public class InBandBytestreamSessionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// read data
|
// read data
|
||||||
byte[] bytes = new byte[3 * dataSize];
|
byte[] bytes = new byte[3 * blockSize];
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
bytes[i] = (byte) inputStream.read();
|
bytes[i] = (byte) inputStream.read();
|
||||||
}
|
}
|
||||||
|
|
86
test-unit/org/jivesoftware/smackx/forward/ForwardedTest.java
Normal file
86
test-unit/org/jivesoftware/smackx/forward/ForwardedTest.java
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.forward;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInfo;
|
||||||
|
import org.jivesoftware.smackx.packet.DelayInformation;
|
||||||
|
import org.jivesoftware.smackx.forward.Forwarded;
|
||||||
|
import org.jivesoftware.smackx.forward.provider.ForwardedProvider;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.mxp1.MXParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import com.jamesmurty.utils.XMLBuilder;
|
||||||
|
|
||||||
|
public class ForwardedTest {
|
||||||
|
|
||||||
|
private static Properties outputProperties = new Properties();
|
||||||
|
static {
|
||||||
|
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forwardedTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
Forwarded fwd;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.e("message")
|
||||||
|
.a("from", "romeo@montague.com")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = TestUtils.getParser(control, "forwarded");
|
||||||
|
fwd = (Forwarded) new ForwardedProvider().parseExtension(parser);
|
||||||
|
|
||||||
|
// no delay in packet
|
||||||
|
assertEquals(null, fwd.getDelayInfo());
|
||||||
|
|
||||||
|
// check message
|
||||||
|
assertEquals("romeo@montague.com", fwd.getForwardedPacket().getFrom());
|
||||||
|
|
||||||
|
// check end of tag
|
||||||
|
assertEquals(XmlPullParser.END_TAG, parser.getEventType());
|
||||||
|
assertEquals("forwarded", parser.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=Exception.class)
|
||||||
|
public void forwardedEmptyTest() throws Exception {
|
||||||
|
XmlPullParser parser;
|
||||||
|
String control;
|
||||||
|
|
||||||
|
control = XMLBuilder.create("forwarded")
|
||||||
|
.a("xmlns", "urn:xmpp:forwarded:0")
|
||||||
|
.asString(outputProperties);
|
||||||
|
|
||||||
|
parser = TestUtils.getParser(control, "forwarded");
|
||||||
|
new ForwardedProvider().parseExtension(parser);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,19 +15,21 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.ping;
|
package org.jivesoftware.smackx.ping;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import org.jivesoftware.smack.DummyConnection;
|
import org.jivesoftware.smack.DummyConnection;
|
||||||
import org.jivesoftware.smack.TestUtils;
|
|
||||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.ping.packet.Ping;
|
import org.jivesoftware.smack.ping.packet.Ping;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
public class PingTest {
|
public class PingTest {
|
||||||
private DummyConnection dummyCon;
|
private DummyConnection dummyCon;
|
||||||
private ThreadedDummyConnection threadedCon;
|
private ThreadedDummyConnection threadedCon;
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package org.jivesoftware.smackx.provider;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.ExtensionProviderInfo;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.provider.IQProviderInfo;
|
||||||
|
import org.jivesoftware.smack.provider.ProviderFileLoader;
|
||||||
|
import org.jivesoftware.smack.provider.ProviderLoader;
|
||||||
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class ProviderConfigTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addGenericLoaderProvider() {
|
||||||
|
ProviderManager.getInstance().addLoader(new ProviderLoader() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<IQProviderInfo> getIQProviderInfo() {
|
||||||
|
ArrayList<IQProviderInfo> l = new ArrayList<IQProviderInfo>(1);
|
||||||
|
l.add(new IQProviderInfo("provider", "test:provider", new TestIQProvider()));
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.assertNotNull(ProviderManager.getInstance().getIQProvider("provider", "test:provider"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addClasspathFileLoaderProvider() throws Exception{
|
||||||
|
ProviderManager.getInstance().addLoader(new ProviderFileLoader(FileUtils.getStreamForUrl("classpath:org/jivesoftware/smackx/provider/test.providers", null)));
|
||||||
|
Assert.assertNotNull(ProviderManager.getInstance().getIQProvider("provider", "test:file_provider"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestIQProvider implements IQProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
11
test-unit/org/jivesoftware/smackx/provider/test.providers
Normal file
11
test-unit/org/jivesoftware/smackx/provider/test.providers
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Providers file for default Smack extensions -->
|
||||||
|
<smackProviders>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>provider</elementName>
|
||||||
|
<namespace>test:file_provider</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.provider.ProviderConfigTest$TestIQProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
</smackProviders>
|
|
@ -26,10 +26,10 @@ import static org.junit.Assert.assertTrue;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
import org.jivesoftware.smack.TestUtils;
|
|
||||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.test.util.TestUtils;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||||
import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
|
import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
|
||||||
|
|
214
workgroup/resources/META-INF/workgroup.providers
Normal file
214
workgroup/resources/META-INF/workgroup.providers
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Providers for workgroup extensions -->
|
||||||
|
<smackProviders>
|
||||||
|
<!-- Fastpath providers -->
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>offer</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.OfferRequestProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>offer-revoke</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.OfferRevokeProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>agent-status-request</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>transcripts</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.TranscriptsProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>transcript</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.TranscriptProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>workgroups</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.AgentWorkgroups$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>agent-info</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.AgentInfo$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>transcript-search</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.TranscriptSearch$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>occupants-info</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.OccupantsInfo$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>chat-settings</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.settings.ChatSettings$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>chat-notes</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.ext.notes.ChatNotes$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>chat-sessions</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.ext.history.AgentChatHistory$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>offline-settings</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.settings.OfflineSettings$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>sound-settings</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.settings.SoundSettings$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>workgroup-properties</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.settings.WorkgroupProperties$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>search-settings</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.settings.SearchSettings$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>workgroup-form</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.ext.forms.WorkgroupForm$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>macros</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.ext.macros.Macros$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>chat-metadata</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.ext.history.ChatMetadata$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
org.jivesoftware.smackx.workgroup.site is missing ...
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>site-user</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.site.SiteUser$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>site-invite</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.site.SiteInvitation$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>site-user-history</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.site.SiteUserHistory$Provider</className>
|
||||||
|
</iqProvider>
|
||||||
|
-->
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>generic-metadata</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.settings.GenericSettings$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>monitor</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.MonitorPacket$InternalProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
|
<!-- Packet Extension Providers -->
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>queue-status</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.QueueUpdate$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>workgroup</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.WorkgroupInformation$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>metadata</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.MetaDataProvider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>session</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.SessionID$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>user</elementName>
|
||||||
|
<namespace>http://jivesoftware.com/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.UserID$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>agent-status</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.AgentStatus$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>notify-queue-details</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.QueueDetails$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>notify-queue</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.QueueOverview$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>invite</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.RoomInvitation$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>transfer</elementName>
|
||||||
|
<namespace>http://jabber.org/protocol/workgroup</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.workgroup.packet.RoomTransfer$Provider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
|
</smackProviders>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.jivesoftware.smackx.workgroup;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.provider.UrlProviderFileInitializer;
|
||||||
|
|
||||||
|
public class WorkgroupProviderInitializer extends UrlProviderFileInitializer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFilePath() {
|
||||||
|
return "classpath:META-INF/workgroup.providers";
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manges information about the agents in a workgroup and their presence.
|
* Manges information about the agents in a workgroup and their presence.
|
||||||
|
@ -45,7 +46,7 @@ import java.util.Set;
|
||||||
* @see AgentSession#getAgentRoster()
|
* @see AgentSession#getAgentRoster()
|
||||||
*/
|
*/
|
||||||
public class AgentRoster {
|
public class AgentRoster {
|
||||||
|
private static Logger log = Logger.getLogger(AgentRoster.class.getName());
|
||||||
private static final int EVENT_AGENT_ADDED = 0;
|
private static final int EVENT_AGENT_ADDED = 0;
|
||||||
private static final int EVENT_AGENT_REMOVED = 1;
|
private static final int EVENT_AGENT_REMOVED = 1;
|
||||||
private static final int EVENT_PRESENCE_CHANGED = 2;
|
private static final int EVENT_PRESENCE_CHANGED = 2;
|
||||||
|
@ -284,7 +285,7 @@ public class AgentRoster {
|
||||||
String from = presence.getFrom();
|
String from = presence.getFrom();
|
||||||
if (from == null) {
|
if (from == null) {
|
||||||
// TODO Check if we need to ignore these presences or this is a server bug?
|
// TODO Check if we need to ignore these presences or this is a server bug?
|
||||||
System.out.println("Presence with no FROM: " + presence.toXML());
|
log.warning("Presence with no FROM: " + presence.toXML());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String key = getPresenceMapKey(from);
|
String key = getPresenceMapKey(from);
|
|
@ -40,6 +40,8 @@ import org.jivesoftware.smackx.ReportedData;
|
||||||
import org.jivesoftware.smackx.packet.MUCUser;
|
import org.jivesoftware.smackx.packet.MUCUser;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class embodies the agent's active presence within a given workgroup. The application
|
* This class embodies the agent's active presence within a given workgroup. The application
|
||||||
|
@ -53,6 +55,7 @@ import java.util.*;
|
||||||
* @author Derek DeMoro
|
* @author Derek DeMoro
|
||||||
*/
|
*/
|
||||||
public class AgentSession {
|
public class AgentSession {
|
||||||
|
private static Logger log = Logger.getLogger(AgentSession.class.getName());
|
||||||
|
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
|
@ -118,7 +121,7 @@ public class AgentSession {
|
||||||
handlePacket(packet);
|
handlePacket(packet);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.log(Level.SEVERE, "Error processing packet", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue