mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 06:12:05 +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.
191
build/build.xml
191
build/build.xml
|
@ -17,7 +17,7 @@
|
|||
|
||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
|
||||
<classpath>
|
||||
<pathelement location="${basedir}/build/ant-contrib.jar"/>
|
||||
<pathelement location="${basedir}/build/ant-contrib-1.0b2.jar"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
|
||||
|
@ -26,29 +26,36 @@
|
|||
|
||||
<!-- Smack Version -->
|
||||
<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.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>
|
||||
<equals arg1="${version.extra}" arg2=""/>
|
||||
<if>
|
||||
<length string="${version.extra}" when="greater" length="0"/>
|
||||
<then>
|
||||
<property name="version"
|
||||
value="${version.major}.${version.minor}.${version.revision}"/>
|
||||
<property name="version.filename"
|
||||
value="${version.major}_${version.minor}_${version.revision}"/>
|
||||
<var name="mutable-version" value="${mutable-version}.${version.extra}"/>
|
||||
<var name="mutable-experimental-version" value="${mutable-experimental-version}.${version.extra}" />
|
||||
</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>
|
||||
<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 name="compile.dir" value="${basedir}/target/classes" />
|
||||
<property name="compile.test.dir" value="${basedir}/target/classes-test" />
|
||||
|
@ -132,6 +139,40 @@
|
|||
<pathelement path="${compile.dir}"/>
|
||||
</classpath>
|
||||
</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>
|
||||
|
||||
<!-- compile-test -->
|
||||
|
@ -170,54 +211,68 @@
|
|||
<!-- 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" />
|
||||
<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}"
|
||||
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"/>
|
||||
</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" />
|
||||
<jar file="${jar.dest.dir}/smack.jar" update="true">
|
||||
<bndwrap jars="${smack.jar.name}" output="${smack.jar.name}" />
|
||||
<jar file="${smack.jar.name}" update="true">
|
||||
<manifest>
|
||||
<attribute name="Bundle-SymbolicName" value="org.igniterealtime.smack" />
|
||||
<attribute name="Bundle-SymbolicName" value="${bundle.name}" />
|
||||
<attribute name="Bundle-Version" value="${version}" />
|
||||
</manifest>
|
||||
</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}"
|
||||
includes="org/jivesoftware/smackx/**/*.class, **/*.providers"
|
||||
includes="org/jivesoftware/smackx/**/*.class, **/extension.providers"
|
||||
excludes="org/jivesoftware/smackx/debugger/*.class">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="smack.jar" />
|
||||
</manifest>
|
||||
<zipfileset src="${merge.lib.dir}/jzlib.jar"/>
|
||||
</jar>
|
||||
<bndwrap jars="${jar.dest.dir}/smackx.jar" output="${jar.dest.dir}/smackx.jar" />
|
||||
<jar file="${jar.dest.dir}/smackx.jar" update="true">
|
||||
<bndwrap jars="${smackx.jar.name}" output="${smackx.jar.name}" />
|
||||
<jar file="${smackx.jar.name}" update="true">
|
||||
<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>
|
||||
</jar>
|
||||
<copy todir="${compile.dir}/images">
|
||||
|
||||
<property name="debug.jar.name" value="${jar.dest.dir}/smackx-debug-${version}.jar" />
|
||||
<copy todir="${compile.dir}/images">
|
||||
<fileset dir="${basedir}/build/resources/images">
|
||||
<include name="*.png"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<jar destfile="${jar.dest.dir}/smackx-debug.jar"
|
||||
<jar destfile="${debug.jar.name}"
|
||||
basedir="${compile.dir}"
|
||||
includes="org/jivesoftware/smackx/debugger/*.class, **/*.png">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="smack.jar" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<bndwrap jars="${jar.dest.dir}/smackx-debug.jar" output="${jar.dest.dir}/smackx-debug.jar" />
|
||||
<jar file="${jar.dest.dir}/smackx-debug.jar" update="true">
|
||||
<bndwrap jars="${debug.jar.name}" output="${debug.jar.name}" />
|
||||
<jar file="${debug.jar.name}" update="true">
|
||||
<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>
|
||||
</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"
|
||||
includes="org/jivesoftware/smackx/**/*.class">
|
||||
<manifest>
|
||||
|
@ -225,35 +280,79 @@
|
|||
</manifest>
|
||||
<zipfileset src="${jingle.extension.merge.lib.dir}/jstun.jar"/>
|
||||
</jar>
|
||||
<bndwrap jars="${jar.dest.dir}/smackx-jingle.jar" output="${jar.dest.dir}/smackx-jingle.jar" />
|
||||
<jar file="${jar.dest.dir}/smackx-jingle.jar" update="true">
|
||||
<bndwrap jars="${jingle.jar.name}" output="${jingle.jar.name}" />
|
||||
<jar file="${jingle.jar.name}" update="true">
|
||||
<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>
|
||||
</jar>
|
||||
<delete file="${compile.dir}/META-INF/smack-config.xml" />
|
||||
<delete file="${compile.dir}/META-INF/smack.providers" />
|
||||
|
||||
<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/*.providers" />
|
||||
<delete>
|
||||
<fileset dir="${compile.dir}/images">
|
||||
<include name="*.png"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
-->
|
||||
</target>
|
||||
|
||||
<!-- jar -->
|
||||
<!-- ======================================================================================= -->
|
||||
<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"
|
||||
basedir="${compile.test.dir}"
|
||||
includes="org/jivesoftware/smack/**/*.class"
|
||||
includes="org/jivesoftware/smack/**/*.class, **/smack-config.xml, **/core.providers, **/jul.properties"
|
||||
/>
|
||||
</target>
|
||||
|
||||
<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"
|
||||
basedir="${compile.test.dir}"
|
||||
includes="org/jivesoftware/smackx/**/*.class
|
||||
org/jivesoftware/util/**/*.class"
|
||||
includes="org/jivesoftware/smackx/**/*.class, org/jivesoftware/util/**/*.class, **/extension.providers"
|
||||
/>
|
||||
</target>
|
||||
|
||||
|
@ -283,7 +382,7 @@
|
|||
<link href="http://java.sun.com/j2se/1.3/docs/api/" />
|
||||
<link href="http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/" />
|
||||
</javadoc>
|
||||
</target>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- test -->
|
||||
|
@ -365,7 +464,7 @@
|
|||
<!-- ======================================================================================= -->
|
||||
<target name="test-unit" depends="compile, jar-test, jar-test-smackx" unless="no.test">
|
||||
<junit printsummary="on"
|
||||
fork="true"
|
||||
fork="false"
|
||||
haltonfailure="false"
|
||||
failureproperty="tests.failed"
|
||||
showoutput="true">
|
||||
|
@ -385,7 +484,7 @@
|
|||
</fileset>
|
||||
<fileset dir="${jar.dest.dir}">
|
||||
<include name="smack-test.jar"/>
|
||||
<include name="smack-test-smackx.jar" />
|
||||
<include name="smack-test-smackx.jar" />
|
||||
</fileset>
|
||||
<pathelement location="${compile.dir}" />
|
||||
<pathelement location="${test-unit.dir}" />
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
<classpathentry kind="src" path="source"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<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/build/java-xmlbuilder-0.3.jar"/>
|
||||
<classpathentry kind="lib" path="build/build/xmlunit.jar"/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>smack-3.3.x</name>
|
||||
<name>smack-3.4.x</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<!-- Include Ant Optional Tasks -->
|
||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
|
||||
<classpath>
|
||||
<pathelement location="${basedir}/build/ant-contrib.jar"/>
|
||||
<pathelement location="${basedir}/build/ant-contrib-1.0b2.jar"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
|
||||
|
@ -28,155 +28,66 @@
|
|||
<!-- ======================================================================================= -->
|
||||
<target name="all">
|
||||
<!-- create release properties -->
|
||||
<if>
|
||||
<equals arg1="${dailybuild}" arg2="true" />
|
||||
<then>
|
||||
<tstamp>
|
||||
<format property="build.date" pattern="yyyy-MM-dd" locale="en"/>
|
||||
</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 -->
|
||||
<property name="release.dir" value="${basedir}/target/release/${version}" />
|
||||
<property name="release.samples.dir" value="${release.dir}/samples" />
|
||||
<tstamp>
|
||||
<format property="release.date" pattern="dd/MM/yyyy" locale="en"/>
|
||||
</tstamp>
|
||||
|
||||
<!-- create release dirs -->
|
||||
<mkdir dir="${release.dir}" />
|
||||
<mkdir dir="${release-dev.dir}" />
|
||||
<!-- Copy smack.jar -->
|
||||
<mkdir dir="${release.samples.dir}" />
|
||||
|
||||
<!-- Copy smack.jar -->
|
||||
<copy todir="${release.dir}">
|
||||
<fileset dir="${jar.dest.dir}" includes="smack.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx-debug.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx-jingle.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smack-${version}.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx-${version}.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx-debug-${version}.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 todir="${release-dev.dir}">
|
||||
<fileset dir="${jar.dest.dir}" includes="smack.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx-debug.jar" />
|
||||
<fileset dir="${jar.dest.dir}" includes="smackx-jingle.jar" />
|
||||
<copy todir="${release.samples.dir}">
|
||||
<fileset dir="${basedir}/build/resources/META-INF" includes="sample.providers" />
|
||||
<fileset dir="${basedir}/build/resources/META-INF" includes="smack-config.xml" />
|
||||
</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 Javadocs -->
|
||||
|
||||
|
||||
<!-- Copy Javadocs -->
|
||||
<copy todir="${release.dir}/javadoc">
|
||||
<fileset dir="${basedir}/target/javadoc" includes="**/*.*" />
|
||||
</copy>
|
||||
<copy todir="${release-dev.dir}/javadoc">
|
||||
<fileset dir="${basedir}/target/javadoc" includes="**/*.*" />
|
||||
</copy>
|
||||
<!-- Copy documentation -->
|
||||
|
||||
<!-- Copy documentation -->
|
||||
<copy todir="${release.dir}/documentation">
|
||||
<fileset dir="${basedir}/documentation" includes="**/*.*" />
|
||||
</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}">
|
||||
<fileset dir="${basedir}/build/resources/releasedocs" includes="*.html" />
|
||||
<filterset>
|
||||
<filter token="builddate" value="${builddate}"/>
|
||||
<filter token="releasedate" value="${release.date}"/>
|
||||
<filter token="version" value="${version}"/>
|
||||
</filterset>
|
||||
</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>
|
||||
-----------------------------------------------
|
||||
Release made, testing Ant targets of release...
|
||||
Release made
|
||||
-----------------------------------------------
|
||||
</echo>
|
||||
|
||||
<!-- call the release tester -->
|
||||
<antcall target="test" />
|
||||
</target>
|
||||
|
||||
<!-- 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>
|
File diff suppressed because it is too large
Load diff
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 -->
|
||||
<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.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.muc.MultiUserChat</className>
|
||||
<className>org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager</className>
|
||||
|
|
|
@ -148,7 +148,7 @@ hr {
|
|||
<td><b>@version@</b></td>
|
||||
</tr><tr>
|
||||
<td align="right">released:</td>
|
||||
<td><b>@builddate@</b></td>
|
||||
<td><b>@releasedate@</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
|
|
@ -140,6 +140,47 @@ hr {
|
|||
</div>
|
||||
|
||||
<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>
|
||||
|
||||
|
|
|
@ -40,6 +40,37 @@ over which features applications require:
|
|||
</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">
|
||||
Establishing a Connection
|
||||
</p>
|
||||
|
|
|
@ -15,44 +15,68 @@ Provider Architecture: Packet Extensions and Custom IQ's
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<p class="subheader">Introduction</p>
|
||||
|
||||
The Smack provider architecture is a system for plugging in
|
||||
custom XML parsing of packet extensions and IQ packets. The
|
||||
standard <a href="extensions/index.html">Smack Extensions</a>
|
||||
are built using the provider architecture. Two types of
|
||||
providers exist:<ul>
|
||||
are built using the provider architecture. There are two types of
|
||||
providers:<ul>
|
||||
<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>
|
||||
|
||||
<p class="subheader">IQProvider</p>
|
||||
|
||||
By default, Smack only knows how to process IQ packets with sub-packets that
|
||||
are in a few namespaces such as:<ul>
|
||||
By default, Smack only knows how to process a few standard packets and sub-packets
|
||||
that are in a few namespaces such as:<ul>
|
||||
<li>jabber:iq:auth
|
||||
<li>jabber:iq:roster
|
||||
<li>jabber:iq:register</ul>
|
||||
|
||||
Because many more IQ types are part of XMPP and its extensions, a pluggable IQ parsing
|
||||
mechanism is provided. IQ providers are registered programatically or by creating a
|
||||
smack.providers file in the META-INF directory of your JAR file. The file is an XML
|
||||
document that contains one or more iqProvider entries, as in the following example:
|
||||
There are many more IQ types and extensions that are part of XMPP standards, and of
|
||||
course an endless number that can be added as custom extensions. To support this, an
|
||||
extensible parsing mechanism is provided via Smack and user build providers.
|
||||
<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>
|
||||
<?xml version="1.0"?>
|
||||
<smackProviders>
|
||||
<iqProvider>
|
||||
<elementName>query</elementName>
|
||||
<namespace>jabber:iq:time</namespace>
|
||||
<className>org.jivesoftware.smack.packet.Time</className>
|
||||
</iqProvider>
|
||||
</smackProviders></pre>
|
||||
-Dsmack.provider.file=classpath:com/myco/provider/myco_custom.providers
|
||||
or
|
||||
-Dsmack.provider.file=file:///c:/myco/provider/myco_custom.providers
|
||||
</pre>
|
||||
</ul>
|
||||
|
||||
Each IQ provider is associated with an element name and a namespace. In the
|
||||
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>
|
||||
<p class="subheader">IQ Providers</p>
|
||||
|
||||
The IQ provider class can either implement the IQProvider
|
||||
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.
|
||||
For example, an XMPP time packet resembles the following:
|
||||
|
||||
<p>
|
||||
<i>Introspection</i>
|
||||
<p>
|
||||
<u>Time Packet</u>
|
||||
<pre>
|
||||
<iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'>
|
||||
<query xmlns='jabber:iq:time'>
|
||||
<utc>20020910T17:58:35</utc>
|
||||
<tz>MDT</tz>
|
||||
<display>Tue Sep 10 12:58:35 2002</display>
|
||||
</query>
|
||||
</iq></pre>
|
||||
<iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'>
|
||||
<query xmlns='jabber:iq:time'>
|
||||
<utc>20020910T17:58:35</utc>
|
||||
<tz>MDT</tz>
|
||||
<display>Tue Sep 10 12:58:35 2002</display>
|
||||
</query>
|
||||
</iq>
|
||||
</pre>
|
||||
|
||||
In order for this packet to be automatically mapped to the Time object listed in the
|
||||
providers file above, it must have the methods setUtc(String), setTz(String), and
|
||||
setDisplay(String). The introspection service will automatically try to convert the String
|
||||
<p>
|
||||
<u>Time IQ Class</u>
|
||||
<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
|
||||
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
|
||||
packet extensions, which are child elements in a custom namespace
|
||||
of IQ, message and presence packets.
|
||||
Each extension provider is registered with an element name and namespace
|
||||
in the smack.providers file as in the following example:
|
||||
<p>
|
||||
<u>Disco Items IQProvider</u>
|
||||
<pre>
|
||||
public class DiscoverItemsProvider implements IQProvider {
|
||||
|
||||
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>
|
||||
<?xml version="1.0"?>
|
||||
<smackProviders>
|
||||
<iq type='result' from='pubsub.shakespeare.lit' to='francisco@denmark.lit/barracks' id='sub1'>
|
||||
<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>
|
||||
<elementName>x</elementName>
|
||||
<namespace>jabber:iq:event</namespace>
|
||||
<className>org.jivesoftware.smack.packet.MessageEvent</className>
|
||||
<elementName>subscription</elementName>
|
||||
<namespace>http://jabber.org/protocol/pubsub</namespace>
|
||||
<className>org.jivesoftware.smackx.pubsub.provider.SubscriptionProvider</className>
|
||||
</extensionProvider>
|
||||
</smackProviders></pre>
|
||||
</smackProviders></pre>
|
||||
|
||||
If multiple provider entries attempt to register to handle the same element
|
||||
name and namespace, the first entry loaded from the classpath will take
|
||||
precedence.<p>
|
||||
Each provider is associated with an element name and a namespace. If multiple provider entries attempt to register to
|
||||
handle the same namespace, the last entry added to the <b>ProviderManager</b> will overwrite any other that was loaded
|
||||
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>
|
||||
|
|
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.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Allows creation and management of accounts on an XMPP server.
|
||||
|
@ -40,7 +42,8 @@ import java.util.Map;
|
|||
* @author Matt Tucker
|
||||
*/
|
||||
public class AccountManager {
|
||||
|
||||
private static Logger logger = Logger.getLogger(AccountManager.class.getName());
|
||||
|
||||
private Connection connection;
|
||||
private Registration info = null;
|
||||
|
||||
|
@ -134,7 +137,7 @@ public class AccountManager {
|
|||
}
|
||||
}
|
||||
catch (XMPPException xe) {
|
||||
xe.printStackTrace();
|
||||
logger.log(Level.SEVERE, "Error retrieving account attributes from server", xe);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
@ -155,7 +158,7 @@ public class AccountManager {
|
|||
return info.getAttributes().get(name);
|
||||
}
|
||||
catch (XMPPException xe) {
|
||||
xe.printStackTrace();
|
||||
logger.log(Level.SEVERE, "Error retrieving account attribute " + name + " info from server", xe);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -175,6 +178,7 @@ public class AccountManager {
|
|||
return info.getInstructions();
|
||||
}
|
||||
catch (XMPPException xe) {
|
||||
logger.log(Level.SEVERE, "Error retrieving account instructions from server", xe);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,7 +170,19 @@ 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
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Chat
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
|
@ -33,39 +34,59 @@ import org.jivesoftware.smack.filter.PacketFilter;
|
|||
import org.jivesoftware.smack.filter.ThreadFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.collections.ReferenceMap;
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*/
|
||||
public class ChatManager {
|
||||
|
||||
/**
|
||||
* Returns the next unique id. Each id made up of a short alphanumeric
|
||||
* prefix along with a unique numeric value.
|
||||
*
|
||||
* @return the next id.
|
||||
/*
|
||||
* 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 synchronized String nextID() {
|
||||
return prefix + Long.toString(id++);
|
||||
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;
|
||||
|
||||
/**
|
||||
* Defines the different modes under which a match will be attempted with an existing chat when
|
||||
* the incoming message does not have a thread id.
|
||||
*/
|
||||
public enum MatchMode {
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Keeps track of the current increment, which is appended to the prefix to
|
||||
* forum a unique ID.
|
||||
private boolean normalIncluded = defaultIsNormalInclude;
|
||||
|
||||
/*
|
||||
* Determines how incoming message with no thread will be matched to existing chats.
|
||||
*/
|
||||
private static long id = 0;
|
||||
|
||||
private MatchMode matchMode = defaultMatchMode;
|
||||
|
||||
/**
|
||||
* Maps thread ID to chat.
|
||||
*/
|
||||
|
@ -101,11 +122,11 @@ public class ChatManager {
|
|||
return false;
|
||||
}
|
||||
Message.Type messageType = ((Message) packet).getType();
|
||||
return messageType != Message.Type.groupchat &&
|
||||
messageType != Message.Type.headline;
|
||||
return (messageType == Type.chat) || (normalIncluded ? messageType == Type.normal : false);
|
||||
}
|
||||
};
|
||||
// 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.
|
||||
connection.addPacketListener(new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
|
@ -116,10 +137,6 @@ public class ChatManager {
|
|||
}
|
||||
else {
|
||||
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) {
|
||||
|
@ -130,6 +147,44 @@ public class ChatManager {
|
|||
}, 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.
|
||||
*
|
||||
|
@ -138,12 +193,7 @@ public class ChatManager {
|
|||
* @return the created chat.
|
||||
*/
|
||||
public Chat createChat(String userJID, MessageListener listener) {
|
||||
String threadID;
|
||||
do {
|
||||
threadID = nextID();
|
||||
} while (threadChats.get(threadID) != null);
|
||||
|
||||
return createChat(userJID, threadID, listener);
|
||||
return createChat(userJID, null, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,7 +205,7 @@ public class ChatManager {
|
|||
* @return the created chat.
|
||||
*/
|
||||
public Chat createChat(String userJID, String thread, MessageListener listener) {
|
||||
if(thread == null) {
|
||||
if (thread == null) {
|
||||
thread = nextID();
|
||||
}
|
||||
Chat chat = threadChats.get(thread);
|
||||
|
@ -191,20 +241,25 @@ public class ChatManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Try to get a matching chat for the given user JID. Try the full
|
||||
* JID map first, the try to match on the base JID if no match is
|
||||
* found.
|
||||
* Try to get a matching chat for the given user JID, based on the {@link MatchMode}.
|
||||
* <li>NONE - return null
|
||||
* <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
|
||||
* @return
|
||||
* @param userJID jid in the from field of message.
|
||||
* @return Matching chat, or null if no match found.
|
||||
*/
|
||||
private Chat getUserChat(String userJID) {
|
||||
Chat match = jidChats.get(userJID);
|
||||
if (matchMode == MatchMode.NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Chat match = jidChats.get(userJID);
|
||||
|
||||
if (match == null) {
|
||||
match = baseJidChats.get(StringUtils.parseBareAddress(userJID));
|
||||
}
|
||||
return match;
|
||||
if (match == null && (matchMode == MatchMode.BARE_JID)) {
|
||||
match = baseJidChats.get(StringUtils.parseBareAddress(userJID));
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
public Chat getThreadChat(String thread) {
|
||||
|
@ -278,4 +333,21 @@ public class ChatManager {
|
|||
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.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.compression.JzlibInputOutputStream;
|
||||
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
||||
|
@ -83,7 +84,8 @@ import org.jivesoftware.smack.packet.Presence;
|
|||
* @author Guenther Niess
|
||||
*/
|
||||
public abstract class Connection {
|
||||
|
||||
private static Logger log = Logger.getLogger(Connection.class.getName());
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 packetFilter the packet filter to use.
|
||||
*/
|
||||
|
@ -681,6 +687,9 @@ public abstract class Connection {
|
|||
* invoked every time a packet is about to be sent by this connection. Interceptors
|
||||
* may modify the packet to be sent. A packet filter determines which packets
|
||||
* 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 packetFilter the packet filter to use.
|
||||
|
@ -757,7 +766,7 @@ public abstract class Connection {
|
|||
debuggerClass = Class.forName(className);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.warning("Unabled to instantiate debugger class " + className);
|
||||
}
|
||||
}
|
||||
if (debuggerClass == null) {
|
||||
|
@ -771,7 +780,7 @@ public abstract class Connection {
|
|||
Class.forName("org.jivesoftware.smack.debugger.LiteDebugger");
|
||||
}
|
||||
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 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.
|
||||
|
@ -45,6 +47,8 @@ import java.util.concurrent.*;
|
|||
*/
|
||||
class PacketReader {
|
||||
|
||||
private static Logger log = Logger.getLogger(PacketReader.class.getName());
|
||||
|
||||
private Thread readerThread;
|
||||
private ExecutorService listenerExecutor;
|
||||
|
||||
|
@ -134,7 +138,7 @@ class PacketReader {
|
|||
catch (Exception e) {
|
||||
// Catch and print any exception so we can recover
|
||||
// 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);
|
||||
}
|
||||
catch (XmlPullParserException xppe) {
|
||||
xppe.printStackTrace();
|
||||
log.log(Level.WARNING, "Error while resetting parser", xppe);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,8 +455,7 @@ class PacketReader {
|
|||
try {
|
||||
listenerWrapper.notifyListener(packet);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Exception in packet listener: " + e);
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Exception in packet listener", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.io.IOException;
|
|||
import java.io.Writer;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
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
|
||||
|
@ -38,7 +40,8 @@ import java.util.concurrent.BlockingQueue;
|
|||
* @author Matt Tucker
|
||||
*/
|
||||
class PacketWriter {
|
||||
|
||||
private static Logger log = Logger.getLogger(PacketWriter.class.getName());
|
||||
|
||||
private Thread writerThread;
|
||||
private Writer writer;
|
||||
private XMPPConnection connection;
|
||||
|
@ -88,7 +91,7 @@ class PacketWriter {
|
|||
queue.put(packet);
|
||||
}
|
||||
catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
log.log(Level.SEVERE, "Failed to queue packet to send to server: " + packet.toString(), ie);
|
||||
return;
|
||||
}
|
||||
synchronized (queue) {
|
||||
|
@ -165,14 +168,14 @@ class PacketWriter {
|
|||
// we won't have time to entirely flush it before the socket is forced closed
|
||||
// by the shutdown process.
|
||||
try {
|
||||
while (!queue.isEmpty()) {
|
||||
Packet packet = queue.remove();
|
||||
while (!queue.isEmpty()) {
|
||||
Packet packet = queue.remove();
|
||||
writer.write(packet.toXML());
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.warning("Error flushing queue during shutdown, ignore and continue");
|
||||
}
|
||||
|
||||
// Delete the queue contents (hopefully nothing is left).
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smack;
|
|||
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
/**
|
||||
* Handles the automatic reconnection process. Every time a connection is dropped without
|
||||
* the application explictly closing it, the manager automatically tries to reconnect to
|
||||
|
@ -34,7 +35,8 @@ import java.util.Random;
|
|||
* @author Francisco Vives
|
||||
*/
|
||||
public class ReconnectionManager implements ConnectionListener {
|
||||
|
||||
private static Logger log = Logger.getLogger(ReconnectionManager.class.getName());
|
||||
|
||||
// Holds the connection to the server
|
||||
private Connection connection;
|
||||
private Thread reconnectionThread;
|
||||
|
@ -132,8 +134,8 @@ public class ReconnectionManager implements ConnectionListener {
|
|||
ReconnectionManager.this
|
||||
.notifyAttemptToReconnectIn(remainingSeconds);
|
||||
}
|
||||
catch (InterruptedException e1) {
|
||||
e1.printStackTrace();
|
||||
catch (InterruptedException e1) {
|
||||
log.warning("Sleeping thread interrupted");
|
||||
// Notify the reconnection has failed
|
||||
ReconnectionManager.this.notifyReconnectionFailed(e1);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.security.cert.CertificateException;
|
|||
import java.security.cert.CertificateParsingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -41,7 +42,8 @@ import java.util.regex.Pattern;
|
|||
* @author Gaston Dombiak
|
||||
*/
|
||||
class ServerTrustManager implements X509TrustManager {
|
||||
|
||||
private static Logger log = Logger.getLogger(ServerTrustManager.class.getName());
|
||||
|
||||
private static Pattern cnPattern = Pattern.compile("(?i)(cn=)([^,]*)");
|
||||
|
||||
private ConnectionConfiguration configuration;
|
||||
|
@ -153,8 +155,7 @@ class ServerTrustManager implements X509TrustManager {
|
|||
trusted = trustStore.getCertificateAlias(x509Certificates[nSize - 1]) != null;
|
||||
if (!trusted && nSize == 1 && configuration.isSelfSignedCertificateEnabled())
|
||||
{
|
||||
System.out.println("Accepting self-signed certificate of remote server: " +
|
||||
peerIdentities);
|
||||
log.info("Accepting self-signed certificate of remote server: " + peerIdentities);
|
||||
trusted = true;
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +269,7 @@ class ServerTrustManager implements X509TrustManager {
|
|||
}
|
||||
}
|
||||
// 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) {
|
||||
|
|
|
@ -20,16 +20,18 @@
|
|||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Collections;
|
||||
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.ParsingExceptionCallback;
|
||||
import org.jivesoftware.smack.util.FileUtils;
|
||||
import org.xmlpull.mxp1.MXParser;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
|
@ -49,16 +51,22 @@ import org.xmlpull.v1.XmlPullParser;
|
|||
* @author Gaston Dombiak
|
||||
*/
|
||||
public final class SmackConfiguration {
|
||||
|
||||
private static final String SMACK_VERSION = "3.3.1";
|
||||
|
||||
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 Logger log = Logger.getLogger(SmackConfiguration.class.getName());
|
||||
|
||||
private static InputStream configFileStream;
|
||||
|
||||
private static int packetReplyTimeout = 5000;
|
||||
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 int localSocks5ProxyPort = 7777;
|
||||
private static int packetCollectorSize = 5000;
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The default parsing exception callback is {@link ExceptionThrowingCallback} which will
|
||||
|
@ -81,75 +89,39 @@ public final class SmackConfiguration {
|
|||
* 1) a set of classes will be loaded in order to execute their static init block
|
||||
* 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 {
|
||||
// Get an array of class loaders to try loading the providers files from.
|
||||
ClassLoader[] classLoaders = getClassLoaders();
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
Enumeration<URL> configEnum = classLoader.getResources("META-INF/smack-config.xml");
|
||||
while (configEnum.hasMoreElements()) {
|
||||
URL url = configEnum.nextElement();
|
||||
InputStream systemStream = null;
|
||||
try {
|
||||
systemStream = url.openStream();
|
||||
XmlPullParser parser = new MXParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||
parser.setInput(systemStream, "UTF-8");
|
||||
int eventType = parser.getEventType();
|
||||
do {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("className")) {
|
||||
// Attempt to load the class so that the class can get initialized
|
||||
parseClassToLoad(parser);
|
||||
}
|
||||
else if (parser.getName().equals("packetReplyTimeout")) {
|
||||
packetReplyTimeout = parseIntProperty(parser, packetReplyTimeout);
|
||||
}
|
||||
else if (parser.getName().equals("keepAliveInterval")) {
|
||||
keepAliveInterval = parseIntProperty(parser, keepAliveInterval);
|
||||
}
|
||||
else if (parser.getName().equals("mechName")) {
|
||||
defaultMechs.add(parser.nextText());
|
||||
}
|
||||
else if (parser.getName().equals("localSocks5ProxyEnabled")) {
|
||||
localSocks5ProxyEnabled = Boolean.parseBoolean(parser.nextText());
|
||||
}
|
||||
else if (parser.getName().equals("localSocks5ProxyPort")) {
|
||||
localSocks5ProxyPort = parseIntProperty(parser, localSocks5ProxyPort);
|
||||
}
|
||||
else if (parser.getName().equals("packetCollectorSize")) {
|
||||
packetCollectorSize = parseIntProperty(parser, packetCollectorSize);
|
||||
}
|
||||
else if (parser.getName().equals("autoEnableEntityCaps")) {
|
||||
autoEnableEntityCaps = Boolean.parseBoolean(parser.nextText());
|
||||
}
|
||||
else if (parser.getName().equals("autoEnableEntityCaps")) {
|
||||
autoEnableEntityCaps = Boolean.parseBoolean(parser.nextText());
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
while (eventType != XmlPullParser.END_DOCUMENT);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
systemStream.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
configFileStream = FileUtils.getStreamForUrl(configFileUrl, loader);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new IllegalArgumentException("Failed to create input stream from specified file URL ["+ configFileUrl + "]", e);
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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".
|
||||
*
|
||||
|
@ -166,6 +138,8 @@ public final class SmackConfiguration {
|
|||
* @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;
|
||||
|
@ -180,6 +154,8 @@ public final class SmackConfiguration {
|
|||
* @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();
|
||||
}
|
||||
|
@ -195,6 +171,7 @@ public final class SmackConfiguration {
|
|||
* no keep-alive should be sent.
|
||||
*/
|
||||
public static int getKeepAliveInterval() {
|
||||
initialize();
|
||||
return keepAliveInterval;
|
||||
}
|
||||
|
||||
|
@ -207,6 +184,7 @@ public final class SmackConfiguration {
|
|||
* or -1 if no keep-alive should be sent.
|
||||
*/
|
||||
public static void setKeepAliveInterval(int interval) {
|
||||
initialize();
|
||||
keepAliveInterval = interval;
|
||||
}
|
||||
|
||||
|
@ -217,6 +195,7 @@ public final class SmackConfiguration {
|
|||
* @return The number of packets to queue before deleting older packets.
|
||||
*/
|
||||
public static int getPacketCollectorSize() {
|
||||
initialize();
|
||||
return packetCollectorSize;
|
||||
}
|
||||
|
||||
|
@ -227,6 +206,7 @@ public final class SmackConfiguration {
|
|||
* @param The number of packets to queue before deleting older packets.
|
||||
*/
|
||||
public static void setPacketCollectorSize(int collectorSize) {
|
||||
initialize();
|
||||
packetCollectorSize = collectorSize;
|
||||
}
|
||||
|
||||
|
@ -236,6 +216,8 @@ public final class SmackConfiguration {
|
|||
* @param mech the SASL mechanism to be added
|
||||
*/
|
||||
public static void addSaslMech(String mech) {
|
||||
initialize();
|
||||
|
||||
if(! defaultMechs.contains(mech) ) {
|
||||
defaultMechs.add(mech);
|
||||
}
|
||||
|
@ -247,6 +229,8 @@ public final class SmackConfiguration {
|
|||
* @param mechs the Collection of SASL mechanisms to be added
|
||||
*/
|
||||
public static void addSaslMechs(Collection<String> mechs) {
|
||||
initialize();
|
||||
|
||||
for(String mech : mechs) {
|
||||
addSaslMech(mech);
|
||||
}
|
||||
|
@ -258,9 +242,8 @@ public final class SmackConfiguration {
|
|||
* @param mech the SASL mechanism to be removed
|
||||
*/
|
||||
public static void removeSaslMech(String mech) {
|
||||
if( defaultMechs.contains(mech) ) {
|
||||
defaultMechs.remove(mech);
|
||||
}
|
||||
initialize();
|
||||
defaultMechs.remove(mech);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,9 +252,8 @@ public final class SmackConfiguration {
|
|||
* @param mechs the Collection of SASL mechanisms to be removed
|
||||
*/
|
||||
public static void removeSaslMechs(Collection<String> mechs) {
|
||||
for(String mech : mechs) {
|
||||
removeSaslMech(mech);
|
||||
}
|
||||
initialize();
|
||||
defaultMechs.removeAll(mechs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -282,7 +264,7 @@ public final class SmackConfiguration {
|
|||
* @return the list of SASL mechanisms to be used.
|
||||
*/
|
||||
public static List<String> getSaslMechs() {
|
||||
return defaultMechs;
|
||||
return Collections.unmodifiableList(defaultMechs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -291,6 +273,7 @@ public final class SmackConfiguration {
|
|||
* @return if the local Socks5 proxy should be started
|
||||
*/
|
||||
public static boolean isLocalSocks5ProxyEnabled() {
|
||||
initialize();
|
||||
return localSocks5ProxyEnabled;
|
||||
}
|
||||
|
||||
|
@ -300,6 +283,7 @@ public final class SmackConfiguration {
|
|||
* @param localSocks5ProxyEnabled if the local Socks5 proxy should be started
|
||||
*/
|
||||
public static void setLocalSocks5ProxyEnabled(boolean localSocks5ProxyEnabled) {
|
||||
initialize();
|
||||
SmackConfiguration.localSocks5ProxyEnabled = localSocks5ProxyEnabled;
|
||||
}
|
||||
|
||||
|
@ -309,6 +293,7 @@ public final class SmackConfiguration {
|
|||
* @return the port of the local Socks5 proxy
|
||||
*/
|
||||
public static int getLocalSocks5ProxyPort() {
|
||||
initialize();
|
||||
return localSocks5ProxyPort;
|
||||
}
|
||||
|
||||
|
@ -319,26 +304,29 @@ public final class SmackConfiguration {
|
|||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -346,6 +334,7 @@ public final class SmackConfiguration {
|
|||
* @see ParsingExceptionCallback
|
||||
*/
|
||||
public static void setDefaultParsingExceptionCallback(ParsingExceptionCallback callback) {
|
||||
initialize();
|
||||
defaultCallback = callback;
|
||||
}
|
||||
|
||||
|
@ -356,6 +345,7 @@ public final class SmackConfiguration {
|
|||
* @see ParsingExceptionCallback
|
||||
*/
|
||||
public static ParsingExceptionCallback getDefaultParsingExceptionCallback() {
|
||||
initialize();
|
||||
return defaultCallback;
|
||||
}
|
||||
|
||||
|
@ -363,11 +353,15 @@ public final class SmackConfiguration {
|
|||
String className = parser.nextText();
|
||||
// Attempt to load the class so that the class can get initialized
|
||||
try {
|
||||
Class.forName(className);
|
||||
Class<?> initClass = Class.forName(className);
|
||||
|
||||
if (SmackInitializer.class.isAssignableFrom(initClass)) {
|
||||
SmackInitializer initializer = (SmackInitializer) initClass.newInstance();
|
||||
initializer.initialize();
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
System.err.println("Error! A startup class specified in smack-config.xml could " +
|
||||
"not be loaded: " + className);
|
||||
log.log(Level.WARNING, "A startup class [" + className + "] specified in smack-config.xml could not be loaded: ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,27 +372,93 @@ public final class SmackConfiguration {
|
|||
return Integer.parseInt(parser.nextText());
|
||||
}
|
||||
catch (NumberFormatException nfe) {
|
||||
nfe.printStackTrace();
|
||||
log.log(Level.SEVERE, "Could not parse integer", nfe);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of class loaders to load resources from.
|
||||
*
|
||||
* @return an array of ClassLoader instances.
|
||||
/*
|
||||
* Order of precedence for config file is VM arg, setConfigXXX methods and embedded default file location.
|
||||
*/
|
||||
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);
|
||||
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();
|
||||
try {
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||
parser.setInput(cfgFileStream, "UTF-8");
|
||||
int eventType = parser.getEventType();
|
||||
do {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("className")) {
|
||||
// Attempt to load the class so that the class can get initialized
|
||||
parseClassToLoad(parser);
|
||||
}
|
||||
else if (parser.getName().equals("packetReplyTimeout")) {
|
||||
packetReplyTimeout = parseIntProperty(parser, packetReplyTimeout);
|
||||
}
|
||||
else if (parser.getName().equals("keepAliveInterval")) {
|
||||
keepAliveInterval = parseIntProperty(parser, keepAliveInterval);
|
||||
}
|
||||
else if (parser.getName().equals("mechName")) {
|
||||
defaultMechs.add(parser.nextText());
|
||||
}
|
||||
else if (parser.getName().equals("localSocks5ProxyEnabled")) {
|
||||
localSocks5ProxyEnabled = Boolean.parseBoolean(parser.nextText());
|
||||
}
|
||||
else if (parser.getName().equals("localSocks5ProxyPort")) {
|
||||
localSocks5ProxyPort = parseIntProperty(parser, localSocks5ProxyPort);
|
||||
}
|
||||
else if (parser.getName().equals("packetCollectorSize")) {
|
||||
packetCollectorSize = parseIntProperty(parser, packetCollectorSize);
|
||||
}
|
||||
else if (parser.getName().equals("autoEnableEntityCaps")) {
|
||||
autoEnableEntityCaps = Boolean.parseBoolean(parser.nextText());
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "Error occurred while reading config file", e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
cfgFileStream.close();
|
||||
} catch (IOException e) {
|
||||
log.log(Level.INFO, "Error while closing config file input stream", e);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
ks = null;
|
||||
} else if (context == null) {
|
||||
//System.out.println("Keystore type: "+configuration.getKeystoreType());
|
||||
if(config.getKeystoreType().equals("NONE")) {
|
||||
ks = null;
|
||||
pcb = null;
|
||||
|
@ -1043,10 +1042,13 @@ public class XMPPConnection extends Connection {
|
|||
*/
|
||||
synchronized void notifyConnectionError(Exception e) {
|
||||
// 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;
|
||||
|
||||
packetReader.done = true;
|
||||
packetWriter.done = true;
|
||||
if (packetReader != null)
|
||||
packetReader.done = true;
|
||||
if (packetWriter != null)
|
||||
packetWriter.done = true;
|
||||
// Closes the connection temporary. A reconnection is possible
|
||||
shutdown(new Presence(Presence.Type.unavailable));
|
||||
// Notify connection listeners of the error.
|
||||
|
|
|
@ -80,7 +80,10 @@ public class Message extends Packet {
|
|||
*/
|
||||
public Message(String to, Type type) {
|
||||
setTo(to);
|
||||
this.type = type;
|
||||
|
||||
if (type != null) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,8 @@ import java.io.ObjectOutputStream;
|
|||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
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
|
||||
|
@ -41,7 +43,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
* @author Matt Tucker
|
||||
*/
|
||||
public abstract class Packet {
|
||||
|
||||
private static Logger log = Logger.getLogger(Packet.class.getName());
|
||||
|
||||
protected static final String DEFAULT_LANGUAGE =
|
||||
java.util.Locale.getDefault().getLanguage().toLowerCase();
|
||||
|
||||
|
@ -411,7 +414,7 @@ public abstract class Packet {
|
|||
buf.append(encodedVal).append("</value>");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error encoding java object", e);
|
||||
}
|
||||
finally {
|
||||
if (out != null) {
|
||||
|
@ -452,6 +455,7 @@ public abstract class Packet {
|
|||
return DEFAULT_LANGUAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = (xmlns != null ? xmlns.hashCode() : 0);
|
||||
|
@ -483,4 +488,9 @@ public abstract class Packet {
|
|||
result = 31 * result + (error != null ? error.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toXML();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,18 +20,21 @@
|
|||
|
||||
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
|
||||
*
|
||||
*/
|
||||
public class ExceptionLoggingCallback extends ParsingExceptionCallback {
|
||||
|
||||
private static Logger log = Logger.getLogger(ExceptionLoggingCallback.class.getName());
|
||||
|
||||
@Override
|
||||
public void handleUnparsablePacket(UnparsablePacket unparsed) throws Exception {
|
||||
System.err.print("Smack message parsing exception: " + unparsed.getParsingException().getMessage());
|
||||
unparsed.getParsingException().printStackTrace();
|
||||
System.err.println("Unparsed content: " + unparsed.getContent());
|
||||
log.log(Level.SEVERE, "Smack message parsing exception: ", unparsed.getParsingException());
|
||||
log.severe("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;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.xmlpull.mxp1.MXParser;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
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
|
||||
* 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
|
||||
* 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. 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
|
||||
* store all top-level elements of the sub-packet in DefaultPacketExtension object and then
|
||||
* 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
|
||||
*/
|
||||
public class ProviderManager {
|
||||
public final class ProviderManager {
|
||||
|
||||
private static ProviderManager instance;
|
||||
|
||||
|
@ -123,9 +114,7 @@ public class ProviderManager {
|
|||
private Map<String, Object> iqProviders = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* Returns the only ProviderManager valid instance. Use {@link #setInstance(ProviderManager)}
|
||||
* to configure your own provider manager. If non was provided then an instance of this
|
||||
* class will be used.
|
||||
* Returns the ProviderManager instance.
|
||||
*
|
||||
* @return the only ProviderManager valid instance.
|
||||
*/
|
||||
|
@ -136,130 +125,28 @@ public class ProviderManager {
|
|||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the only ProviderManager valid instance to be used by all Connections. If you
|
||||
* 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;
|
||||
private ProviderManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
// Load IQ processing providers.
|
||||
try {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
cnfe.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
public void addLoader(ProviderLoader loader) {
|
||||
if (loader == null) {
|
||||
throw new IllegalArgumentException("loader cannot be null");
|
||||
}
|
||||
|
||||
if (loader.getIQProviderInfo() != null) {
|
||||
for (IQProviderInfo info : loader.getIQProviderInfo()) {
|
||||
iqProviders.put(getProviderKey(info.getElementName(), info.getNamespace()), info.getProvider());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
if (loader.getExtensionProviderInfo() != null) {
|
||||
for (ExtensionProviderInfo info : loader.getExtensionProviderInfo()) {
|
||||
extensionProviders.put(getProviderKey(info.getElementName(), info.getNamespace()), info.getProvider());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the IQ provider registered to the specified XML element name and namespace.
|
||||
* For example, if a provider was registered to the element name "query" and the
|
||||
|
@ -411,28 +298,4 @@ public class ProviderManager {
|
|||
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,9 @@
|
|||
*
|
||||
*/
|
||||
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>
|
||||
|
@ -17,9 +20,9 @@ package org.jivesoftware.smack.util;
|
|||
*/
|
||||
public class Base64
|
||||
{
|
||||
|
||||
/* ******** P U B L I C F I E L D S ******** */
|
||||
|
||||
private static Logger log = Logger.getLogger(Base64.class.getName());
|
||||
|
||||
/* ******** P U B L I C F I E L D S ******** */
|
||||
|
||||
/** No options specified. Value is zero. */
|
||||
public final static int NO_OPTIONS = 0;
|
||||
|
@ -311,18 +314,6 @@ public class Base64
|
|||
/** Defeats instantiation. */
|
||||
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 ******** */
|
||||
|
||||
|
||||
|
@ -494,7 +485,7 @@ public class Base64
|
|||
} // end try
|
||||
catch( java.io.IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error encoding object", e);
|
||||
return null;
|
||||
} // end catch
|
||||
finally
|
||||
|
@ -623,7 +614,7 @@ public class Base64
|
|||
} // end try
|
||||
catch( java.io.IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error encoding bytes", e);
|
||||
return null;
|
||||
} // end catch
|
||||
finally
|
||||
|
@ -777,11 +768,12 @@ public class Base64
|
|||
destination[ destOffset + 2 ] = (byte)( outBuff );
|
||||
|
||||
return 3;
|
||||
}catch( Exception e){
|
||||
System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) );
|
||||
System.out.println(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) );
|
||||
System.out.println(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) );
|
||||
System.out.println(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) );
|
||||
}catch( Exception e){
|
||||
log.log(Level.SEVERE, e.getMessage(), e);
|
||||
log.severe(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) );
|
||||
log.severe(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) );
|
||||
log.severe(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) );
|
||||
log.severe(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) );
|
||||
return -1;
|
||||
} // end catch
|
||||
}
|
||||
|
@ -839,7 +831,7 @@ public class Base64
|
|||
} // end if: white space, equals sign or better
|
||||
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;
|
||||
} // end else:
|
||||
} // each input character
|
||||
|
@ -967,12 +959,12 @@ public class Base64
|
|||
} // end try
|
||||
catch( java.io.IOException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error reading object", e);
|
||||
obj = null;
|
||||
} // end catch
|
||||
catch( java.lang.ClassNotFoundException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Class not found for encoded object", e);
|
||||
obj = null;
|
||||
} // end catch
|
||||
finally
|
||||
|
@ -1079,7 +1071,7 @@ public class Base64
|
|||
// Check for size of file
|
||||
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;
|
||||
} // end if: file too big for int index
|
||||
buffer = new byte[ (int)file.length() ];
|
||||
|
@ -1100,7 +1092,7 @@ public class Base64
|
|||
} // end try
|
||||
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
|
||||
finally
|
||||
{
|
||||
|
@ -1148,7 +1140,7 @@ public class Base64
|
|||
} // end try
|
||||
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
|
||||
finally
|
||||
{
|
||||
|
@ -1175,7 +1167,7 @@ public class Base64
|
|||
out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output.
|
||||
} // end try
|
||||
catch( java.io.IOException ex ) {
|
||||
ex.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error encoding file " + infile, ex);
|
||||
} // end catch
|
||||
finally {
|
||||
try { out.close(); }
|
||||
|
@ -1201,7 +1193,7 @@ public class Base64
|
|||
out.write( decoded );
|
||||
} // end try
|
||||
catch( java.io.IOException ex ) {
|
||||
ex.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error decoding file " + infile, ex);
|
||||
} // end catch
|
||||
finally {
|
||||
try { out.close(); }
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.jivesoftware.smack.util;
|
|||
import org.jivesoftware.smack.util.collections.AbstractMapEntry;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A specialized Map that is size-limited (using an LRU algorithm) and
|
||||
|
@ -49,7 +50,7 @@ import java.util.*;
|
|||
* @author Matt Tucker
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -382,8 +383,7 @@ public class Cache<K, V> implements Map<K, V> {
|
|||
|
||||
while (expireTime > node.timestamp) {
|
||||
if (remove(node.object, true) == null) {
|
||||
System.err.println("Error attempting to remove(" + node.object.toString() +
|
||||
") - cacheObject not found in cache!");
|
||||
log.warning("Error attempting to remove(" + node.object.toString() + ") - cacheObject not found in cache!");
|
||||
// remove from the ageList
|
||||
node.remove();
|
||||
}
|
||||
|
@ -417,9 +417,7 @@ public class Cache<K, V> implements Map<K, V> {
|
|||
for (int i=map.size(); i>desiredSize; i--) {
|
||||
// Get the key and invoke the remove method on it.
|
||||
if (remove(lastAccessedList.getLast().object, true) == null) {
|
||||
System.err.println("Error attempting to cullCache with remove(" +
|
||||
lastAccessedList.getLast().object.toString() + ") - " +
|
||||
"cacheObject not found in cache!");
|
||||
log.warning("Error attempting to cullCache with remove(" + lastAccessedList.getLast().object.toString() + ") - cacheObject not found in cache!");
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.packet.Authentication;
|
||||
|
@ -57,7 +59,8 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class PacketParserUtils {
|
||||
|
||||
private static Logger logger = Logger.getLogger(PacketParserUtils.class.getName());
|
||||
|
||||
/**
|
||||
* Namespace used to store packet properties.
|
||||
*/
|
||||
|
@ -198,7 +201,7 @@ public class PacketParserUtils {
|
|||
type = Presence.Type.valueOf(typeString);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
System.err.println("Found invalid presence type " + typeString);
|
||||
logger.warning("Found invalid presence type " + typeString);
|
||||
}
|
||||
}
|
||||
Presence presence = new Presence(type);
|
||||
|
@ -242,7 +245,7 @@ public class PacketParserUtils {
|
|||
presence.setMode(Presence.Mode.valueOf(modeText));
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
System.err.println("Found invalid presence mode " + modeText);
|
||||
logger.warning("Found invalid presence mode " + modeText);
|
||||
}
|
||||
}
|
||||
else if (elementName.equals("error")) {
|
||||
|
@ -263,7 +266,7 @@ public class PacketParserUtils {
|
|||
presence.addExtension(PacketParserUtils.parsePacketExtension(elementName, namespace, parser));
|
||||
}
|
||||
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();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.log(Level.SEVERE, "Error parsing java object", e);
|
||||
}
|
||||
}
|
||||
if (name != null && value != null) {
|
||||
|
@ -782,8 +785,7 @@ public class PacketParserUtils {
|
|||
}
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
// Print stack trace. We shouldn't be getting an illegal error type.
|
||||
iae.printStackTrace();
|
||||
logger.log(Level.SEVERE, "Could not find error type for " + type.toUpperCase(), iae);
|
||||
}
|
||||
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.Random;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -41,7 +43,8 @@ import java.util.regex.Pattern;
|
|||
* A collection of utility methods for String objects.
|
||||
*/
|
||||
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
|
||||
* UTC.
|
||||
|
@ -619,8 +622,7 @@ public class StringUtils {
|
|||
digest = MessageDigest.getInstance("SHA-1");
|
||||
}
|
||||
catch (NoSuchAlgorithmException nsae) {
|
||||
System.err.println("Failed to load the SHA-1 MessageDigest. " +
|
||||
"Jive will be unable to function normally.");
|
||||
log.log(Level.SEVERE, "Failed to load the SHA-1 MessageDigest. Smack will be unable to function normally.", nsae);
|
||||
}
|
||||
}
|
||||
// Now, compute hash.
|
||||
|
@ -628,7 +630,7 @@ public class StringUtils {
|
|||
digest.update(data.getBytes("UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
System.err.println(e);
|
||||
log.log(Level.SEVERE, "Error computing hash", e);
|
||||
}
|
||||
return encodeHex(digest.digest());
|
||||
}
|
||||
|
@ -664,7 +666,7 @@ public class StringUtils {
|
|||
bytes = data.getBytes("ISO-8859-1");
|
||||
}
|
||||
catch (UnsupportedEncodingException uee) {
|
||||
uee.printStackTrace();
|
||||
throw new IllegalStateException(uee);
|
||||
}
|
||||
return encodeBase64(bytes);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.lang.reflect.Method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.Connection;
|
||||
|
@ -42,7 +44,8 @@ import org.jivesoftware.smackx.packet.MessageEvent;
|
|||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class MessageEventManager {
|
||||
|
||||
private static Logger log = Logger.getLogger(MessageEventManager.class.getName());
|
||||
|
||||
private List<MessageEventNotificationListener> messageEventNotificationListeners = new ArrayList<MessageEventNotificationListener>();
|
||||
private List<MessageEventRequestListener> messageEventRequestListeners = new ArrayList<MessageEventRequestListener>();
|
||||
|
||||
|
@ -157,12 +160,8 @@ public class MessageEventManager {
|
|||
for (int i = 0; i < listeners.length; i++) {
|
||||
method.invoke(listeners[i], new Object[] { from, packetID, this });
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "Error while invoking MessageEventRequestListener", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,12 +187,8 @@ public class MessageEventManager {
|
|||
for (int i = 0; i < listeners.length; i++) {
|
||||
method.invoke(listeners[i], new Object[] { from, packetID });
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "Error while invoking MessageEventNotificationListener", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ import org.jivesoftware.smackx.packet.MultipleAddresses;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
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
|
||||
|
@ -42,7 +44,8 @@ import java.util.List;
|
|||
* @author Gaston Dombiak
|
||||
*/
|
||||
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
|
||||
* 24 hours.
|
||||
|
@ -309,13 +312,12 @@ public class MultipleRecipientManager {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Cache the discovered information
|
||||
services.put(serviceName, serviceAddress == null ? "" : serviceAddress);
|
||||
}
|
||||
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
|
||||
*/
|
||||
@Deprecated
|
||||
public interface PEPListener {
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.jivesoftware.smackx.packet.PEPPubSub;
|
|||
*
|
||||
* @author Jeff Williams
|
||||
*/
|
||||
@Deprecated
|
||||
public class PEPManager {
|
||||
|
||||
private List<PEPListener> pepListeners = new ArrayList<PEPListener>();
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.jivesoftware.smackx.packet.DiscoverInfo;
|
|||
import org.jivesoftware.smackx.packet.XHTMLExtension;
|
||||
|
||||
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
|
||||
|
@ -38,6 +40,8 @@ import java.util.Iterator;
|
|||
*/
|
||||
public class XHTMLManager {
|
||||
|
||||
private static Logger log = Logger.getLogger(XHTMLManager.class.getName());
|
||||
|
||||
private final static String namespace = "http://jabber.org/protocol/xhtml-im";
|
||||
|
||||
// Enable the XHTML support on every established connection
|
||||
|
@ -137,7 +141,7 @@ public class XHTMLManager {
|
|||
return result.containsFeature(namespace);
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error checking if service is available", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -594,7 +594,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
* Constructor.
|
||||
*/
|
||||
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.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
@ -67,7 +69,8 @@ import org.jivesoftware.smack.XMPPException;
|
|||
* @author Henning Staib
|
||||
*/
|
||||
public class Socks5Proxy {
|
||||
|
||||
private static Logger log = Logger.getLogger(Socks5Proxy.class.getName());
|
||||
|
||||
/* SOCKS5 proxy singleton */
|
||||
private static Socks5Proxy socks5Server;
|
||||
|
||||
|
@ -150,8 +153,7 @@ public class Socks5Proxy {
|
|||
}
|
||||
catch (IOException e) {
|
||||
// couldn't setup server
|
||||
System.err.println("couldn't setup local SOCKS5 proxy on port "
|
||||
+ SmackConfiguration.getLocalSocks5ProxyPort() + ": " + e.getMessage());
|
||||
log.log(Level.SEVERE, "couldn't setup local SOCKS5 proxy on port " + SmackConfiguration.getLocalSocks5ProxyPort(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* An AdHocCommandManager is responsible for keeping the list of available
|
||||
|
@ -58,7 +59,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
* @author Gabriel Guardincerri
|
||||
*/
|
||||
public class AdHocCommandManager {
|
||||
|
||||
private static final String DISCO_NAMESPACE = "http://jabber.org/protocol/commands";
|
||||
|
||||
private static final String discoNode = DISCO_NAMESPACE;
|
||||
|
@ -470,7 +470,6 @@ public class AdHocCommandManager {
|
|||
executingCommands.remove(sessionId);
|
||||
}
|
||||
respondError(response, error);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -527,7 +526,7 @@ public class AdHocCommandManager {
|
|||
}
|
||||
|
||||
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: construction of new commands
|
||||
|
||||
|
@ -585,8 +584,6 @@ public class AdHocCommandManager {
|
|||
executingCommands.remove(sessionId);
|
||||
}
|
||||
respondError(response, error);
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -650,12 +647,10 @@ public class AdHocCommandManager {
|
|||
command.setNode(commandInfo.getNode());
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
throw new XMPPException(new XMPPError(
|
||||
XMPPError.Condition.interna_server_error));
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
throw new XMPPException(new XMPPError(
|
||||
XMPPError.Condition.interna_server_error));
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ import java.io.Writer;
|
|||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
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
|
||||
|
@ -64,6 +66,8 @@ import java.util.Date;
|
|||
*/
|
||||
public class EnhancedDebugger implements SmackDebugger {
|
||||
|
||||
private static Logger log = Logger.getLogger(EnhancedDebugger.class.getName());
|
||||
|
||||
private static final String NEWLINE = "\n";
|
||||
|
||||
private static ImageIcon packetReceivedIcon;
|
||||
|
@ -427,7 +431,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
|||
receivedText.replaceRange("", 0, receivedText.getLineEndOffset(0));
|
||||
}
|
||||
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));
|
||||
|
@ -462,7 +466,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
|||
sentText.replaceRange("", 0, sentText.getLineEndOffset(0));
|
||||
}
|
||||
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) {
|
||||
// Error generated by the parser
|
||||
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();
|
||||
|
||||
log.log(Level.SEVERE, "Transformer Factory error", tce);
|
||||
}
|
||||
catch (TransformerException te) {
|
||||
// Error generated by the parser
|
||||
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();
|
||||
|
||||
log.log(Level.SEVERE, "Transformation error", te);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
|
@ -39,13 +41,14 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
/**
|
||||
* Simple implementation of an EntityCapsPersistentCache that uses a directory
|
||||
* to store the Caps information for every known node. Every node is represented
|
||||
* by an file.
|
||||
* by a file.
|
||||
*
|
||||
* @author Florian Schmaus
|
||||
*
|
||||
*/
|
||||
public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache {
|
||||
|
||||
private static Logger log = Logger.getLogger(SimpleDirectoryPersistentCache.class.getName());
|
||||
|
||||
private File cacheDir;
|
||||
private StringEncoder filenameEncoder;
|
||||
|
||||
|
@ -54,7 +57,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
|||
* cacheDir exists and that it's an directory.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* @param cacheDir
|
||||
|
@ -91,7 +94,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache
|
|||
if (nodeFile.createNewFile())
|
||||
writeInfoToFile(nodeFile, info);
|
||||
} 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.setInput(reader);
|
||||
} catch (XmlPullParserException xppe) {
|
||||
xppe.printStackTrace();
|
||||
log.log(Level.SEVERE, "Exception initializing parser", xppe);
|
||||
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.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.Chat;
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
|
@ -76,7 +78,8 @@ import org.jivesoftware.smackx.packet.MUCUser;
|
|||
* @author Gaston Dombiak, Larry Kirschner
|
||||
*/
|
||||
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 discoNode = "http://jabber.org/protocol/muc#rooms";
|
||||
|
||||
|
@ -179,7 +182,7 @@ public class MultiUserChat {
|
|||
return result.containsFeature(discoNamespace);
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error checking user [" + user + "] for MUC support", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +225,7 @@ public class MultiUserChat {
|
|||
return answer.iterator();
|
||||
}
|
||||
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 new ArrayList<String>().iterator();
|
||||
}
|
||||
|
@ -953,13 +956,12 @@ public class MultiUserChat {
|
|||
DiscoverInfo.Identity identity = identities.next();
|
||||
return identity.getName();
|
||||
}
|
||||
// If no Identity was found then the user does not have a reserved room nickname
|
||||
return null;
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
log.log(Level.SEVERE, "Error retrieving room nickname", e);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Failed to invoke method on UserStatusListener", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Failed to invoke method on UserStatusListener", 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());
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Failed to invoke method on ParticipantStatusListener", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Failed to invoke method on ParticipantStatusListener", 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>
|
||||
*
|
||||
* @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) {
|
||||
this.type = type;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.PacketExtension;
|
|||
*
|
||||
* @author Jeff Williams
|
||||
*/
|
||||
@Deprecated
|
||||
public class PEPEvent implements PacketExtension {
|
||||
|
||||
PEPItem item;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.PacketExtension;
|
|||
*
|
||||
* @author Jeff Williams
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class PEPItem implements PacketExtension {
|
||||
|
||||
String id;
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.IQ;
|
|||
*
|
||||
* @author Jeff Williams
|
||||
*/
|
||||
@Deprecated
|
||||
public class PEPPubSub extends IQ {
|
||||
|
||||
PEPItem item;
|
||||
|
|
|
@ -27,6 +27,8 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
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
|
||||
|
@ -61,7 +63,8 @@ import java.util.TimeZone;
|
|||
* @author Matt Tucker
|
||||
*/
|
||||
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 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.
|
||||
*
|
||||
* @return the lcocal time.
|
||||
* @return the local time.
|
||||
*/
|
||||
public Date getTime() {
|
||||
if (utc == null) {
|
||||
|
@ -109,7 +112,7 @@ public class Time extends IQ {
|
|||
date = cal.getTime();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error getting local time", e);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
|
@ -85,6 +87,8 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
* @author Kirill Maximov (kir@maxkir.com)
|
||||
*/
|
||||
public class VCard extends IQ {
|
||||
private static Logger log = Logger.getLogger(VCard.class.getName());
|
||||
|
||||
private static final String DEFAULT_MIME_TYPE = "image/jpeg";
|
||||
|
||||
/**
|
||||
|
@ -332,7 +336,7 @@ public class VCard extends IQ {
|
|||
bytes = getBytes(avatarURL);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Error getting bytes from URL: " + avatarURL, e);
|
||||
}
|
||||
|
||||
setAvatar(bytes);
|
||||
|
@ -489,7 +493,7 @@ public class VCard extends IQ {
|
|||
digest = MessageDigest.getInstance("SHA-1");
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Failed to get message digest", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -582,7 +586,7 @@ public class VCard extends IQ {
|
|||
result = (VCard) packet;
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
System.out.println("No VCard for " + user);
|
||||
log.log(Level.SEVERE, "No VCard for " + user, e);
|
||||
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.util.Date;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
|
@ -37,7 +39,8 @@ import org.xmlpull.v1.XmlPullParser;
|
|||
*
|
||||
*/
|
||||
public class StreamInitiationProvider implements IQProvider {
|
||||
|
||||
private static Logger log = Logger.getLogger(StreamInitiationProvider.class.getName());
|
||||
|
||||
public IQ parseIQ(final XmlPullParser parser) throws Exception {
|
||||
boolean done = false;
|
||||
|
||||
|
@ -90,7 +93,7 @@ public class StreamInitiationProvider implements IQProvider {
|
|||
fileSize = Long.parseLong(size);
|
||||
}
|
||||
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.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* vCard provider.
|
||||
|
@ -42,7 +44,8 @@ import java.util.List;
|
|||
* @author Derek DeMoro
|
||||
*/
|
||||
public class VCardProvider implements IQProvider {
|
||||
|
||||
private static Logger log = Logger.getLogger(VCardProvider.class.getName());
|
||||
|
||||
private static final String PREFERRED_ENCODING = "UTF-8";
|
||||
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
|
@ -71,10 +74,10 @@ public class VCardProvider implements IQProvider {
|
|||
}
|
||||
}
|
||||
catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Exception parsing VCard", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.SEVERE, "Exception parsing VCard", e);
|
||||
}
|
||||
|
||||
String xmlText = sb.toString();
|
||||
|
|
|
@ -22,267 +22,419 @@ package org.jivesoftware.smack;
|
|||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.jivesoftware.smack.ChatManager.MatchMode;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
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 {
|
||||
|
||||
private DummyConnection connection;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Uncomment this to enable debug output
|
||||
//Connection.DEBUG_ENABLED = true;
|
||||
|
||||
connection = new DummyConnection();
|
||||
connection.connect();
|
||||
connection.login("me", "secret");
|
||||
connection = getConnection();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null)
|
||||
connection.disconnect();
|
||||
if (connection != null)
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncluded() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
assertFalse(getConnection().getChatManager().isNormalIncluded());
|
||||
|
||||
ChatManager.setDefaultIsNormalIncluded(true);
|
||||
assertTrue(getConnection().getChatManager().isNormalIncluded());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchMode() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.NONE);
|
||||
assertEquals(MatchMode.NONE, getConnection().getChatManager().getMatchMode());
|
||||
|
||||
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);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
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 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.
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatCreatedWithIncomingChatNoThreadBaseJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
public void chatFoundWhenNoThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatCreatedWhenIncomingChatNoThreadFullJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an
|
||||
* incoming chat message that has no thread id and the user is a full jid.
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadFullJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
public void chatFoundWithSameThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an
|
||||
* incoming chat message that has no thread id and the user is a base jid.
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadBaseJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
public void chatFoundWithSameThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an
|
||||
* incoming chat message that has the same id and the user is a full jid.
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same user as a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadFullJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an
|
||||
* incoming chat message that has the same id and the user is a base jid.
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadBaseJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
public void chatNotFoundWithDiffThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to
|
||||
* an incoming chat message that has a different id and the same user as a
|
||||
* base jid.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadBaseJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
public void chatNotMatchedWithTypeNormal() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
DummyConnection con = getConnection();
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setNormalIncluded(false);
|
||||
cm.addChatListener(listener);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
Message incomingChat = createChatPacket(null, false);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to
|
||||
* an incoming chat message that has a different id and the same base jid.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadFullJid()
|
||||
{
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
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);
|
||||
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
if (threadId != null)
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
||||
private Packet createChatPacket(final String threadId, final boolean isFullJid)
|
||||
{
|
||||
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
||||
chatMsg.setBody("the body message");
|
||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||
|
||||
if (threadId != null)
|
||||
chatMsg.addExtension(new PacketExtension()
|
||||
{
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
return "<thread>" + threadId + "</thread>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName()
|
||||
{
|
||||
return "thread";
|
||||
}
|
||||
});
|
||||
return chatMsg;
|
||||
private void processServerMessage(Packet incomingChat) {
|
||||
processServerMessage(incomingChat, connection);
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat, DummyConnection con) {
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, con);
|
||||
chatServer.start();
|
||||
try {
|
||||
chatServer.join();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat)
|
||||
{
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat);
|
||||
chatServer.start();
|
||||
try
|
||||
{
|
||||
chatServer.join();
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
fail();
|
||||
}
|
||||
class TestChatManagerListener implements ChatManagerListener {
|
||||
private Chat newChat;
|
||||
private MessageListener listener;
|
||||
|
||||
public TestChatManagerListener(TestMessageListener msgListener) {
|
||||
listener = msgListener;
|
||||
}
|
||||
|
||||
public TestChatManagerListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chatCreated(Chat chat, boolean createdLocally) {
|
||||
newChat = chat;
|
||||
|
||||
if (listener != null)
|
||||
newChat.addMessageListener(listener);
|
||||
}
|
||||
|
||||
public Chat getNewChat() {
|
||||
return newChat;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestChatServer extends Thread {
|
||||
private Packet chatPacket;
|
||||
private DummyConnection con;
|
||||
|
||||
TestChatServer(Packet chatMsg, DummyConnection conect) {
|
||||
chatPacket = chatMsg;
|
||||
con = conect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
con.processPacket(chatPacket);
|
||||
}
|
||||
}
|
||||
|
||||
class TestChatManagerListener implements ChatManagerListener
|
||||
{
|
||||
private Chat newChat;
|
||||
|
||||
@Override
|
||||
public void chatCreated(Chat chat, boolean createdLocally)
|
||||
{
|
||||
newChat = chat;
|
||||
}
|
||||
|
||||
public Chat getNewChat()
|
||||
{
|
||||
return newChat;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestChatServer extends Thread
|
||||
{
|
||||
private Packet chatPacket;
|
||||
|
||||
TestChatServer(Packet chatMsg)
|
||||
{
|
||||
chatPacket = chatMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
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.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.Presence;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.jivesoftware.smack.keepalive;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Properties;
|
||||
|
@ -13,16 +12,13 @@ import org.jivesoftware.smack.DummyConnection;
|
|||
import org.jivesoftware.smack.PacketInterceptor;
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.TestUtils;
|
||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||
import org.jivesoftware.smack.filter.IQTypeFilter;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.keepalive.KeepAliveManager;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.ping.PingFailedListener;
|
||||
import org.jivesoftware.smack.ping.packet.Ping;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
|
@ -2,8 +2,8 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.jivesoftware.smack.TestUtils;
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.junit.Test;
|
||||
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.assertNotNull;
|
||||
|
||||
import org.jivesoftware.smack.TestUtils;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
package org.jivesoftware.smack.test.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
|
@ -24,10 +24,10 @@ import java.util.TimeZone;
|
|||
|
||||
import org.custommonkey.xmlunit.DetailedDiff;
|
||||
import org.custommonkey.xmlunit.Diff;
|
||||
import org.jivesoftware.smack.TestUtils;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smackx.packet.DelayInformation;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
|
|
@ -57,7 +57,6 @@ public class InBandBytestreamSessionMessageTest {
|
|||
String sessionID = "session_id";
|
||||
|
||||
int blockSize = 10;
|
||||
int dataSize = blockSize/4 * 3;
|
||||
|
||||
// protocol verifier
|
||||
Protocol protocol;
|
||||
|
@ -120,7 +119,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
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.write(controlData);
|
||||
|
@ -145,7 +144,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
protocol.addResponse(null, incrementingSequence);
|
||||
protocol.addResponse(null, incrementingSequence);
|
||||
|
||||
byte[] controlData = new byte[dataSize * 3];
|
||||
byte[] controlData = new byte[blockSize * 3];
|
||||
|
||||
OutputStream outputStream = session.getOutputStream();
|
||||
for (byte b : controlData) {
|
||||
|
@ -172,11 +171,11 @@ public class InBandBytestreamSessionMessageTest {
|
|||
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();
|
||||
int off = 0;
|
||||
for (int i = 1; off+i <= controlData.length; i++) {
|
||||
for (int i = 1; i <= 7; i++) {
|
||||
outputStream.write(controlData, off, i);
|
||||
off += i;
|
||||
}
|
||||
|
@ -193,7 +192,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
*/
|
||||
@Test
|
||||
public void shouldSendThirtyDataPackets() throws Exception {
|
||||
byte[] controlData = new byte[dataSize * 3];
|
||||
byte[] controlData = new byte[blockSize * 3];
|
||||
|
||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||
initiatorJID);
|
||||
|
@ -220,7 +219,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
*/
|
||||
@Test
|
||||
public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception {
|
||||
byte[] controlData = new byte[dataSize * 3];
|
||||
byte[] controlData = new byte[blockSize * 3];
|
||||
|
||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||
initiatorJID);
|
||||
|
@ -291,7 +290,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
public void shouldReadAllReceivedData1() throws Exception {
|
||||
// create random data
|
||||
Random rand = new Random();
|
||||
byte[] controlData = new byte[3 * dataSize];
|
||||
byte[] controlData = new byte[3 * blockSize];
|
||||
rand.nextBytes(controlData);
|
||||
|
||||
// get IBB sessions data packet listener
|
||||
|
@ -301,8 +300,8 @@ public class InBandBytestreamSessionMessageTest {
|
|||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||
|
||||
// verify data packet and notify listener
|
||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
||||
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||
false);
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||
Message dataMessage = new Message();
|
||||
|
@ -310,14 +309,14 @@ public class InBandBytestreamSessionMessageTest {
|
|||
listener.processPacket(dataMessage);
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[3 * dataSize];
|
||||
byte[] bytes = new byte[3 * blockSize];
|
||||
int read = 0;
|
||||
read = inputStream.read(bytes, 0, dataSize);
|
||||
assertEquals(dataSize, read);
|
||||
read = inputStream.read(bytes, dataSize, dataSize);
|
||||
assertEquals(dataSize, read);
|
||||
read = inputStream.read(bytes, dataSize*2, dataSize);
|
||||
assertEquals(dataSize, read);
|
||||
read = inputStream.read(bytes, 0, blockSize);
|
||||
assertEquals(blockSize, read);
|
||||
read = inputStream.read(bytes, 10, blockSize);
|
||||
assertEquals(blockSize, read);
|
||||
read = inputStream.read(bytes, 20, blockSize);
|
||||
assertEquals(blockSize, read);
|
||||
|
||||
// verify data
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
|
@ -337,7 +336,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
public void shouldReadAllReceivedData2() throws Exception {
|
||||
// create random data
|
||||
Random rand = new Random();
|
||||
byte[] controlData = new byte[3 * dataSize];
|
||||
byte[] controlData = new byte[3 * blockSize];
|
||||
rand.nextBytes(controlData);
|
||||
|
||||
// get IBB sessions data packet listener
|
||||
|
@ -347,8 +346,8 @@ public class InBandBytestreamSessionMessageTest {
|
|||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||
|
||||
// verify data packet and notify listener
|
||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
||||
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||
false);
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||
Message dataMessage = new Message();
|
||||
|
@ -357,7 +356,7 @@ public class InBandBytestreamSessionMessageTest {
|
|||
}
|
||||
|
||||
// read data
|
||||
byte[] bytes = new byte[3 * dataSize];
|
||||
byte[] bytes = new byte[3 * blockSize];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = (byte) inputStream.read();
|
||||
}
|
||||
|
|
|
@ -57,8 +57,7 @@ public class InBandBytestreamSessionTest {
|
|||
String xmppServer = "xmpp-server";
|
||||
String sessionID = "session_id";
|
||||
|
||||
int blockSize = 20;
|
||||
int dataSize = blockSize/4 * 3;
|
||||
int blockSize = 10;
|
||||
|
||||
// protocol verifier
|
||||
Protocol protocol;
|
||||
|
@ -120,7 +119,7 @@ public class InBandBytestreamSessionTest {
|
|||
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.write(controlData);
|
||||
|
@ -146,7 +145,7 @@ public class InBandBytestreamSessionTest {
|
|||
protocol.addResponse(resultIQ, incrementingSequence);
|
||||
protocol.addResponse(resultIQ, incrementingSequence);
|
||||
|
||||
byte[] controlData = new byte[dataSize * 3];
|
||||
byte[] controlData = new byte[blockSize * 3];
|
||||
|
||||
OutputStream outputStream = session.getOutputStream();
|
||||
for (byte b : controlData) {
|
||||
|
@ -174,11 +173,11 @@ public class InBandBytestreamSessionTest {
|
|||
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();
|
||||
int off = 0;
|
||||
for (int i = 1; i+off <= controlData.length; i++) {
|
||||
for (int i = 1; i <= 7; i++) {
|
||||
outputStream.write(controlData, off, i);
|
||||
off += i;
|
||||
}
|
||||
|
@ -195,7 +194,7 @@ public class InBandBytestreamSessionTest {
|
|||
*/
|
||||
@Test
|
||||
public void shouldSendThirtyDataPackets() throws Exception {
|
||||
byte[] controlData = new byte[dataSize * 3];
|
||||
byte[] controlData = new byte[blockSize * 3];
|
||||
|
||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||
initiatorJID);
|
||||
|
@ -223,7 +222,7 @@ public class InBandBytestreamSessionTest {
|
|||
*/
|
||||
@Test
|
||||
public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception {
|
||||
byte[] controlData = new byte[dataSize * 3];
|
||||
byte[] controlData = new byte[blockSize * 3];
|
||||
|
||||
InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream,
|
||||
initiatorJID);
|
||||
|
@ -254,7 +253,7 @@ public class InBandBytestreamSessionTest {
|
|||
public void shouldSendDataCorrectly() throws Exception {
|
||||
// create random data
|
||||
Random rand = new Random();
|
||||
final byte[] controlData = new byte[256 * dataSize];
|
||||
final byte[] controlData = new byte[256 * blockSize];
|
||||
rand.nextBytes(controlData);
|
||||
|
||||
// compares the data of each packet with the control data
|
||||
|
@ -264,7 +263,7 @@ public class InBandBytestreamSessionTest {
|
|||
byte[] decodedData = request.getDataPacketExtension().getDecodedData();
|
||||
int seq = (int) request.getDataPacketExtension().getSeq();
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -480,7 +479,7 @@ public class InBandBytestreamSessionTest {
|
|||
public void shouldReadAllReceivedData1() throws Exception {
|
||||
// create random data
|
||||
Random rand = new Random();
|
||||
byte[] controlData = new byte[3 * dataSize];
|
||||
byte[] controlData = new byte[3 * blockSize];
|
||||
rand.nextBytes(controlData);
|
||||
|
||||
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
||||
|
@ -491,24 +490,24 @@ public class InBandBytestreamSessionTest {
|
|||
InputStream inputStream = session.getInputStream();
|
||||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||
|
||||
// set data packet acknowledgement and notify listener
|
||||
for (int i = 0; i < controlData.length / dataSize; i++) {
|
||||
// set data packet acknowledgment and notify listener
|
||||
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||
protocol.addResponse(resultIQ);
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||
false);
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||
Data data = new Data(dpe);
|
||||
listener.processPacket(data);
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[3 * dataSize];
|
||||
byte[] bytes = new byte[3 * blockSize];
|
||||
int read = 0;
|
||||
read = inputStream.read(bytes, 0, dataSize);
|
||||
assertEquals(dataSize, read);
|
||||
read = inputStream.read(bytes, dataSize, dataSize);
|
||||
assertEquals(dataSize, read);
|
||||
read = inputStream.read(bytes, dataSize*2, dataSize);
|
||||
assertEquals(dataSize, read);
|
||||
read = inputStream.read(bytes, 0, blockSize);
|
||||
assertEquals(blockSize, read);
|
||||
read = inputStream.read(bytes, 10, blockSize);
|
||||
assertEquals(blockSize, read);
|
||||
read = inputStream.read(bytes, 20, blockSize);
|
||||
assertEquals(blockSize, read);
|
||||
|
||||
// verify data
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
|
@ -528,7 +527,7 @@ public class InBandBytestreamSessionTest {
|
|||
public void shouldReadAllReceivedData2() throws Exception {
|
||||
// create random data
|
||||
Random rand = new Random();
|
||||
byte[] controlData = new byte[3 * dataSize];
|
||||
byte[] controlData = new byte[3 * blockSize];
|
||||
rand.nextBytes(controlData);
|
||||
|
||||
IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID);
|
||||
|
@ -540,9 +539,9 @@ public class InBandBytestreamSessionTest {
|
|||
PacketListener listener = Whitebox.getInternalState(inputStream, PacketListener.class);
|
||||
|
||||
// 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);
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * dataSize, dataSize,
|
||||
String base64Data = StringUtils.encodeBase64(controlData, i * blockSize, blockSize,
|
||||
false);
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||
Data data = new Data(dpe);
|
||||
|
@ -550,7 +549,7 @@ public class InBandBytestreamSessionTest {
|
|||
}
|
||||
|
||||
// read data
|
||||
byte[] bytes = new byte[3 * dataSize];
|
||||
byte[] bytes = new byte[3 * blockSize];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
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;
|
||||
|
||||
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.TestUtils;
|
||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.ping.packet.Ping;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PingTest {
|
||||
private DummyConnection dummyCon;
|
||||
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>
|
|
@ -22,7 +22,7 @@ package org.jivesoftware.smackx.pubsub;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
|
|
|
@ -26,10 +26,10 @@ import static org.junit.Assert.assertTrue;
|
|||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.jivesoftware.smack.TestUtils;
|
||||
import org.jivesoftware.smack.ThreadedDummyConnection;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||
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.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Manges information about the agents in a workgroup and their presence.
|
||||
|
@ -45,7 +46,7 @@ import java.util.Set;
|
|||
* @see AgentSession#getAgentRoster()
|
||||
*/
|
||||
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_REMOVED = 1;
|
||||
private static final int EVENT_PRESENCE_CHANGED = 2;
|
||||
|
@ -284,7 +285,7 @@ public class AgentRoster {
|
|||
String from = presence.getFrom();
|
||||
if (from == null) {
|
||||
// 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;
|
||||
}
|
||||
String key = getPresenceMapKey(from);
|
|
@ -40,6 +40,8 @@ import org.jivesoftware.smackx.ReportedData;
|
|||
import org.jivesoftware.smackx.packet.MUCUser;
|
||||
|
||||
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
|
||||
|
@ -53,7 +55,8 @@ import java.util.*;
|
|||
* @author Derek DeMoro
|
||||
*/
|
||||
public class AgentSession {
|
||||
|
||||
private static Logger log = Logger.getLogger(AgentSession.class.getName());
|
||||
|
||||
private Connection connection;
|
||||
|
||||
private String workgroupJID;
|
||||
|
@ -118,7 +121,7 @@ public class AgentSession {
|
|||
handlePacket(packet);
|
||||
}
|
||||
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