package org.jboss.resteasy.plugins.providers;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.ws.rs.ext.Providers;
import org.jboss.resteasy.core.ThreadLocalResteasyProviderFactory;
import org.jboss.resteasy.microprofile.config.ResteasyConfig.SOURCE;
import org.jboss.resteasy.microprofile.config.ResteasyConfigFactory;
import org.jboss.resteasy.plugins.interceptors.encoding.AcceptEncodingGZIPFilter;
import org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor;
import org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
public class RegisterBuiltin
{
public static void register(ResteasyProviderFactory factory)
{
register(factory, Collections.emptySet());
}
public static void register(ResteasyProviderFactory factory, Set<String> disabledProviders)
{
final ResteasyProviderFactory monitor = (factory instanceof ThreadLocalResteasyProviderFactory)
? ((ThreadLocalResteasyProviderFactory) factory).getDelegate()
: factory;
synchronized (monitor)
{
if (factory.isBuiltinsRegistered() || !factory.isRegisterBuiltins())
return;
try
{
registerProviders(factory, disabledProviders);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
factory.setBuiltinsRegistered(true);
}
}
public static void registerProviders(ResteasyProviderFactory factory) throws Exception
{
registerProviders(factory, Collections.emptySet());
}
public static void registerProviders(ResteasyProviderFactory factory, Set<String> disabledProviders) throws Exception
{
Enumeration<URL> en;
if (System.getSecurityManager() == null)
{
en = Thread.currentThread().getContextClassLoader().getResources("META-INF/services/" + Providers.class.getName());
}
else
{
en = AccessController.doPrivileged(new PrivilegedExceptionAction<Enumeration<URL>>()
{
@Override
public Enumeration<URL> run() throws IOException
{
return Thread.currentThread().getContextClassLoader().getResources("META-INF/services/" + Providers.class.getName());
}
});
}
Map<String, URL> origins = new HashMap<String, URL>();
while (en.hasMoreElements())
{
final URL url = en.nextElement();
InputStream is;
if (System.getSecurityManager() == null)
{
is = url.openStream();
}
else
{
is = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>()
{
@Override
public InputStream run() throws IOException
{
return url.openStream();
}
});
}
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String line;
while ((line = reader.readLine()) != null)
{
line = line.trim();
if (line.equals("")) continue;
if (disabledProviders.contains(line)) continue;
origins.put(line, url);
}
}
finally
{
is.close();
}
}
for (final Entry<String, URL> entry : origins.entrySet())
{
final String line = entry.getKey();
try
{
Class clazz;
if (System.getSecurityManager() == null)
{
clazz = Thread.currentThread().getContextClassLoader().loadClass(line);
}
else
{
clazz = AccessController.doPrivileged(new PrivilegedExceptionAction<Class>()
{
@Override
public Class run() throws ClassNotFoundException
{
return Thread.currentThread().getContextClassLoader().loadClass(line);
}
});
}
factory.registerProvider(clazz, true);
}
catch (NoClassDefFoundError e)
{
LogMessages.LOGGER.noClassDefFoundErrorError(line, entry.getValue(), e);
}
catch (ClassNotFoundException | PrivilegedActionException ex)
{
LogMessages.LOGGER.classNotFoundException(line, entry.getValue(), ex);
}
}
if (AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
final String value = ResteasyConfigFactory.getConfig().getValue("resteasy.allowGzip", SOURCE.SYSTEM);
if ("".equals(value)) return Boolean.FALSE;
return Boolean.parseBoolean(value);
}
})) {
factory.registerProvider(AcceptEncodingGZIPFilter.class, true);
factory.registerProvider(GZIPDecodingInterceptor.class, true);
factory.registerProvider(GZIPEncodingInterceptor.class, true);
}
}
}