/** * * Copyright 2003-2007 Jive Software, 2014-2020 Florian Schmaus * * 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.smack; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.jivesoftware.smack.bind2.Bind2ModuleDescriptor; import org.jivesoftware.smack.compress.provider.CompressedProvider; import org.jivesoftware.smack.compress.provider.FailureProvider; import org.jivesoftware.smack.compression.CompressionModuleDescriptor; import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream; import org.jivesoftware.smack.compression.XmppCompressionManager; import org.jivesoftware.smack.compression.zlib.ZlibXmppCompressionFactory; import org.jivesoftware.smack.initializer.SmackInitializer; import org.jivesoftware.smack.isr.InstantStreamResumptionModuleDescriptor; import org.jivesoftware.smack.packet.Bind; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.provider.BindIQProvider; import org.jivesoftware.smack.provider.BodyElementProvider; import org.jivesoftware.smack.provider.MessageSubjectElementProvider; import org.jivesoftware.smack.provider.MessageThreadElementProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.provider.SaslChallengeProvider; import org.jivesoftware.smack.provider.SaslFailureProvider; import org.jivesoftware.smack.provider.SaslSuccessProvider; import org.jivesoftware.smack.provider.TlsFailureProvider; import org.jivesoftware.smack.provider.TlsProceedProvider; import org.jivesoftware.smack.sasl.core.SASLAnonymous; import org.jivesoftware.smack.sasl.core.SASLXOauth2Mechanism; import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism; import org.jivesoftware.smack.sasl.core.ScramSha1PlusMechanism; import org.jivesoftware.smack.util.CloseableUtil; import org.jivesoftware.smack.util.FileUtils; import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.xml.XmlPullParser; public final class SmackInitialization { static final String SMACK_VERSION; private static final String DEFAULT_CONFIG_FILE = "org.jivesoftware.smack/smack-config.xml"; private static final Logger LOGGER = Logger.getLogger(SmackInitialization.class.getName()); /** * Loads the configuration from the smack-config.xml and system properties 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
* 3) set DEBUG
*/
static {
String smackVersion;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(FileUtils.getStreamForClasspathFile("org.jivesoftware.smack/version", null), StandardCharsets.UTF_8));
smackVersion = reader.readLine();
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Could not determine Smack version", e);
smackVersion = "unknown";
} finally {
CloseableUtil.maybeClose(reader, LOGGER);
}
SMACK_VERSION = smackVersion;
String disabledClasses = System.getProperty("smack.disabledClasses");
if (disabledClasses != null) {
String[] splitDisabledClasses = disabledClasses.split(",");
for (String s : splitDisabledClasses) SmackConfiguration.disabledSmackClasses.add(s);
}
InputStream configFileStream;
try {
configFileStream = FileUtils.getStreamForClasspathFile(DEFAULT_CONFIG_FILE, null);
}
catch (Exception e) {
throw new IllegalStateException("Could not load Smack configuration file", e);
}
try {
processConfigFile(configFileStream, null);
}
catch (Exception e) {
throw new IllegalStateException("Could not parse Smack configuration file", e);
}
// Add the Java7 compression handler first, since it's preferred
SmackConfiguration.addCompressionHandler(new Java7ZlibInputOutputStream());
XmppCompressionManager.registerXmppCompressionFactory(ZlibXmppCompressionFactory.INSTANCE);
// Use try block since we may not have permission to get a system
// property (for example, when an applet).
try {
// Only overwrite DEBUG if it is set via the 'smack.debugEnabled' property. To prevent DEBUG_ENABLED
// = true, which could be set e.g. via a static block from user code, from being overwritten by the property not set
if (Boolean.getBoolean("smack.debugEnabled")) {
SmackConfiguration.DEBUG = true;
}
}
catch (Exception e) {
LOGGER.log(Level.FINE, "Could not handle debugEnable property on Smack initialization", e);
}
SASLAuthentication.registerSASLMechanism(new SCRAMSHA1Mechanism());
SASLAuthentication.registerSASLMechanism(new ScramSha1PlusMechanism());
SASLAuthentication.registerSASLMechanism(new SASLXOauth2Mechanism());
SASLAuthentication.registerSASLMechanism(new SASLAnonymous());
ProviderManager.addIQProvider(Bind.ELEMENT, Bind.NAMESPACE, new BindIQProvider());
ProviderManager.addExtensionProvider(Message.Body.ELEMENT, Message.Body.NAMESPACE, new BodyElementProvider());
ProviderManager.addExtensionProvider(Message.Thread.ELEMENT, Message.Thread.NAMESPACE, new MessageThreadElementProvider());
ProviderManager.addExtensionProvider(Message.Subject.ELEMENT, Message.Subject.NAMESPACE, new MessageSubjectElementProvider());
ProviderManager.addNonzaProvider(SaslChallengeProvider.INSTANCE);
ProviderManager.addNonzaProvider(SaslSuccessProvider.INSTANCE);
ProviderManager.addNonzaProvider(SaslFailureProvider.INSTANCE);
ProviderManager.addNonzaProvider(TlsProceedProvider.INSTANCE);
ProviderManager.addNonzaProvider(TlsFailureProvider.INSTANCE);
ProviderManager.addNonzaProvider(CompressedProvider.INSTANCE);
ProviderManager.addNonzaProvider(FailureProvider.INSTANCE);
SmackConfiguration.addModule(Bind2ModuleDescriptor.class);
SmackConfiguration.addModule(CompressionModuleDescriptor.class);
SmackConfiguration.addModule(InstantStreamResumptionModuleDescriptor.class);
SmackConfiguration.smackInitialized = true;
}
public static void processConfigFile(InputStream cfgFileStream,
Collection