From a3ab886896c6f9baed3290d330afa6c3fafcd96f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 10 Mar 2014 10:20:52 +0100 Subject: [PATCH] Reworked compression-jzlib and compressionHandlers - There is now no longer the need to use reflection for compression-jzlib. - compressionHandlers are a global configuration property and therefore belong in SmackConfiguration. --- .../compression/JzlibInputOutputStream.java | 49 ++++++++----------- core/build.gradle | 1 + .../smack/SmackConfiguration.java | 39 ++++++++++----- .../jivesoftware/smack/XMPPConnection.java | 11 ----- .../org/jivesoftware/smack/TCPConnection.java | 5 +- 5 files changed, 50 insertions(+), 55 deletions(-) diff --git a/compression-jzlib/src/main/java/org/jivesoftware/smack/compression/JzlibInputOutputStream.java b/compression-jzlib/src/main/java/org/jivesoftware/smack/compression/JzlibInputOutputStream.java index 821bab25e..744625fc6 100644 --- a/compression-jzlib/src/main/java/org/jivesoftware/smack/compression/JzlibInputOutputStream.java +++ b/compression-jzlib/src/main/java/org/jivesoftware/smack/compression/JzlibInputOutputStream.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013 Florian Schmaus + * Copyright 2013-2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,31 +16,28 @@ */ package org.jivesoftware.smack.compression; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; + +import org.jivesoftware.smack.SmackConfiguration; + +import com.jcraft.jzlib.JZlib; +import com.jcraft.jzlib.ZInputStream; +import com.jcraft.jzlib.ZOutputStream; /** - * This class provides XMPP "zlib" compression with the help of JZLib. Note that jzlib-1.0.7 must be used (i.e. in the - * classpath), newer versions won't work! + * This class provides XMPP "zlib" compression with the help of JZLib. * * @author Florian Schmaus * @see JZLib * */ +@SuppressWarnings("deprecation") public class JzlibInputOutputStream extends XMPPInputOutputStream { - private static Class zoClass = null; - private static Class ziClass = null; - static { - try { - zoClass = Class.forName("com.jcraft.jzlib.ZOutputStream"); - ziClass = Class.forName("com.jcraft.jzlib.ZInputStream"); - } catch (ClassNotFoundException e) { - } + SmackConfiguration.addCompressionHandler(new JzlibInputOutputStream()); } public JzlibInputOutputStream() { @@ -49,28 +46,22 @@ public class JzlibInputOutputStream extends XMPPInputOutputStream { @Override public boolean isSupported() { - return (zoClass != null && ziClass != null); + return true; } @Override - public InputStream getInputStream(InputStream inputStream) throws SecurityException, NoSuchMethodException, - IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException { - Constructor constructor = ziClass.getConstructor(InputStream.class); - Object in = constructor.newInstance(inputStream); + public InputStream getInputStream(InputStream inputStream) throws IOException { + ZInputStream is = new ZInputStream(inputStream); + is.setFlushMode(JZlib.Z_SYNC_FLUSH); - Method method = ziClass.getMethod("setFlushMode", Integer.TYPE); - method.invoke(in, 2); - return (InputStream) in; + return is; } @Override - public OutputStream getOutputStream(OutputStream outputStream) throws SecurityException, NoSuchMethodException, - IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { - Constructor constructor = zoClass.getConstructor(OutputStream.class, Integer.TYPE); - Object out = constructor.newInstance(outputStream, 9); + public OutputStream getOutputStream(OutputStream outputStream) throws IOException { + ZOutputStream os = new ZOutputStream(outputStream); + os.setFlushMode(JZlib.Z_SYNC_FLUSH); - Method method = zoClass.getMethod("setFlushMode", Integer.TYPE); - method.invoke(out, 2); - return (OutputStream) out; + return os; } } diff --git a/core/build.gradle b/core/build.gradle index 9d47b3495..9e0054c87 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -24,6 +24,7 @@ task compressionJar(type: Jar) { dependsOn classes from sourceSets.main.output include('org/jivesoftware/smack/compression/**') + include('org/jivesoftware/smack/SmackConfiguration.class') } task dnsJar(type: Jar) { appendix += '-dns' diff --git a/core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java b/core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java index bfcf57805..3a5ee4f68 100644 --- a/core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java +++ b/core/src/main/java/org/jivesoftware/smack/SmackConfiguration.java @@ -28,6 +28,8 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream; +import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.initializer.SmackInitializer; import org.jivesoftware.smack.parsing.ExceptionThrowingCallback; import org.jivesoftware.smack.parsing.ParsingExceptionCallback; @@ -64,6 +66,15 @@ public final class SmackConfiguration { private static Set disabledSmackClasses = new HashSet(); + private final static List compressionHandlers = new ArrayList(2); + + /** + * Loads the configuration from the smack-config.xml file.

+ * + * So far this means that: + * 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 { String smackVersion; try { @@ -104,6 +115,9 @@ public final class SmackConfiguration { catch (Exception e) { throw new IllegalStateException(e); } + + // Add the Java7 compression handler first, since it's preferred + compressionHandlers.add(new Java7ZlibInputOutputStream()); } /** @@ -112,17 +126,6 @@ public final class SmackConfiguration { */ private static ParsingExceptionCallback defaultCallback = new ExceptionThrowingCallback(); - private SmackConfiguration() { - } - - /** - * Loads the configuration from the smack-config.xml file.

- * - * So far this means that: - * 1) a set of classes will be loaded in order to execute their static init block - * 2) retrieve and set the current Smack release - */ - /** * Returns the Smack version information, eg "1.3.0". * @@ -250,6 +253,20 @@ public final class SmackConfiguration { return defaultCallback; } + public static void addCompressionHandler(XMPPInputOutputStream xmppInputOutputStream) { + compressionHandlers.add(xmppInputOutputStream); + } + + public static List getCompresionHandlers() { + List res = new ArrayList(compressionHandlers.size()); + for (XMPPInputOutputStream ios : compressionHandlers) { + if (ios.isSupported()) { + res.add(ios); + } + } + return res; + } + public static void processConfigFile(InputStream cfgFileStream, Collection exceptions) throws Exception { XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); diff --git a/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index 9d7cc99ea..a289e4019 100644 --- a/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -19,10 +19,8 @@ package org.jivesoftware.smack; import java.io.Reader; import java.io.Writer; import java.lang.reflect.Constructor; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -36,7 +34,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; -import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream; import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.debugger.SmackDebugger; import org.jivesoftware.smack.filter.IQReplyFilter; @@ -97,8 +94,6 @@ public abstract class XMPPConnection { private final static Set connectionEstablishedListeners = new CopyOnWriteArraySet(); - protected final static List compressionHandlers = new ArrayList(2); - /** * Value that indicates whether debugging is enabled. When enabled, a debug * window will apear for each new connection that will contain the following @@ -125,12 +120,6 @@ public abstract class XMPPConnection { } // Ensure the SmackConfiguration class is loaded by calling a method in it. SmackConfiguration.getVersion(); - // Add the Java7 compression handler first, since it's preferred - compressionHandlers.add(new Java7ZlibInputOutputStream()); - // If we don't have access to the Java7 API use the JZlib compression handler - - // TODO gradle migration - //compressionHandlers.add(new JzlibInputOutputStream()); } /** diff --git a/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java b/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java index 65d28a6da..a76c4feb6 100644 --- a/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java +++ b/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java @@ -827,10 +827,7 @@ public class TCPConnection extends XMPPConnection { */ private XMPPInputOutputStream maybeGetCompressionHandler() { if (compressionMethods != null) { - for (XMPPInputOutputStream handler : compressionHandlers) { - if (!handler.isSupported()) - continue; - + for (XMPPInputOutputStream handler : SmackConfiguration.getCompresionHandlers()) { String method = handler.getCompressionMethod(); if (compressionMethods.contains(method)) return handler;