Simplified ManagedAttribute mechanism

This commit is contained in:
Greg Wilkins 2015-06-19 15:24:06 +10:00
parent f9a3bdab2a
commit b0a3c7c5ea
3 changed files with 174 additions and 122 deletions

View File

@ -211,13 +211,11 @@ public class LikeJettyXml
HashLoginService login = new HashLoginService(); HashLoginService login = new HashLoginService();
login.setName("Test Realm"); login.setName("Test Realm");
login.setConfig(jetty_base + "/etc/realm.properties"); login.setConfig(jetty_base + "/etc/realm.properties");
login.setRefreshInterval(0); login.setHotReload(false);
server.addBean(login); server.addBean(login);
// Start the server // Start the server
server.start(); server.start();
server.dumpStdErr();
server.join(); server.join();
} }
} }

View File

@ -112,9 +112,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
public final static int SERVLET_MAJOR_VERSION=3; public final static int SERVLET_MAJOR_VERSION=3;
public final static int SERVLET_MINOR_VERSION=1; public final static int SERVLET_MINOR_VERSION=1;
public static final Class<?>[] SERVLET_LISTENER_TYPES = new Class[] {ServletContextListener.class, public static final Class<?>[] SERVLET_LISTENER_TYPES = new Class[] {ServletContextListener.class,
ServletContextAttributeListener.class, ServletContextAttributeListener.class,
ServletRequestListener.class, ServletRequestListener.class,
ServletRequestAttributeListener.class}; ServletRequestAttributeListener.class};
public static final int DEFAULT_LISTENER_TYPE_INDEX = 1; public static final int DEFAULT_LISTENER_TYPE_INDEX = 1;
public static final int EXTENDED_LISTENER_TYPE_INDEX = 0; public static final int EXTENDED_LISTENER_TYPE_INDEX = 0;
@ -155,7 +155,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return null; return null;
} }
protected Context _scontext; protected Context _scontext;
private final AttributesMap _attributes; private final AttributesMap _attributes;
private final Map<String, String> _initParams; private final Map<String, String> _initParams;
@ -715,7 +714,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
Context old_context = null; Context old_context = null;
_attributes.setAttribute("org.eclipse.jetty.server.Executor",getServer().getThreadPool()); _attributes.setAttribute("org.eclipse.jetty.server.Executor",getServer().getThreadPool());
try try
{ {
// Set the classloader // Set the classloader
@ -760,22 +759,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
String managedAttributes = _initParams.get(MANAGED_ATTRIBUTES); String managedAttributes = _initParams.get(MANAGED_ATTRIBUTES);
if (managedAttributes != null) if (managedAttributes != null)
{ addEventListener(new ManagedAttributeListener(this,managedAttributes.split(",")));
_managedAttributes = new HashMap<String, Object>();
String[] attributes = managedAttributes.split(",");
for (String attribute : attributes)
{
_managedAttributes.put(attribute.trim(),null);
}
Enumeration<String> e = _scontext.getAttributeNames();
while (e.hasMoreElements())
{
String name = e.nextElement();
Object value = _scontext.getAttribute(name);
checkManagedAttribute(name,value);
}
}
super.doStart(); super.doStart();
@ -845,13 +829,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (_errorHandler != null) if (_errorHandler != null)
_errorHandler.stop(); _errorHandler.stop();
Enumeration<String> e = _scontext.getAttributeNames();
while (e.hasMoreElements())
{
String name = e.nextElement();
checkManagedAttribute(name,null);
}
for (EventListener l : _programmaticListeners) for (EventListener l : _programmaticListeners)
removeEventListener(l); removeEventListener(l);
_programmaticListeners.clear(); _programmaticListeners.clear();
@ -907,7 +884,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
} }
return true; return true;
} }
public boolean checkContextPath(String uri) public boolean checkContextPath(String uri)
{ {
// Are we not the root context? // Are we not the root context?
@ -921,7 +898,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
} }
return true; return true;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@ -936,7 +913,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (!checkContextPath(target)) if (!checkContextPath(target))
return false; return false;
// Are we not the root context? // Are we not the root context?
// redirect null path infos // redirect null path infos
if (!_allowNullPathInfo && _contextPath.length() == target.length() && _contextPath.length()>1) if (!_allowNullPathInfo && _contextPath.length() == target.length() && _contextPath.length()>1)
@ -993,8 +970,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
// check the target. // check the target.
if (DispatcherType.REQUEST.equals(dispatch) || if (DispatcherType.REQUEST.equals(dispatch) ||
DispatcherType.ASYNC.equals(dispatch) || DispatcherType.ASYNC.equals(dispatch) ||
DispatcherType.ERROR.equals(dispatch) && baseRequest.getHttpChannelState().isAsync()) DispatcherType.ERROR.equals(dispatch) && baseRequest.getHttpChannelState().isAsync())
{ {
if (_compactPath) if (_compactPath)
target = URIUtil.compactPath(target); target = URIUtil.compactPath(target);
@ -1202,7 +1179,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
if (target.length()==t.length()) if (target.length()==t.length())
return true; return true;
// Check that the target prefix really is a path segment, thus // Check that the target prefix really is a path segment, thus
// it can end with /, a query, a target or a parameter // it can end with /, a query, a target or a parameter
char c=target.charAt(t.length()); char c=target.charAt(t.length());
@ -1226,7 +1203,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
_protectedTargets = null; _protectedTargets = null;
return; return;
} }
_protectedTargets = Arrays.copyOf(targets, targets.length); _protectedTargets = Arrays.copyOf(targets, targets.length);
} }
@ -1247,7 +1224,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@Override @Override
public void removeAttribute(String name) public void removeAttribute(String name)
{ {
checkManagedAttribute(name,null);
_attributes.removeAttribute(name); _attributes.removeAttribute(name);
} }
@ -1261,7 +1237,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@Override @Override
public void setAttribute( String name, Object value) public void setAttribute( String name, Object value)
{ {
checkManagedAttribute(name,value);
_attributes.setAttribute(name,value); _attributes.setAttribute(name,value);
} }
@ -1274,36 +1249,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
_attributes.clearAttributes(); _attributes.clearAttributes();
_attributes.addAll(attributes); _attributes.addAll(attributes);
Enumeration<String> e = _attributes.getAttributeNames();
while (e.hasMoreElements())
{
String name = e.nextElement();
checkManagedAttribute(name,attributes.getAttribute(name));
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void clearAttributes() public void clearAttributes()
{ {
Enumeration<String> e = _attributes.getAttributeNames();
while (e.hasMoreElements())
{
String name = e.nextElement();
checkManagedAttribute(name,null);
}
_attributes.clearAttributes(); _attributes.clearAttributes();
} }
/* ------------------------------------------------------------ */
public void checkManagedAttribute(String name, Object value)
{
if (_managedAttributes != null && _managedAttributes.containsKey(name))
{
setManagedAttribute(name,value);
}
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setManagedAttribute(String name, Object value) public void setManagedAttribute(String name, Object value)
{ {
@ -1613,7 +1567,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
encoding = _localeEncodingMap.get(locale.getLanguage()); encoding = _localeEncodingMap.get(locale.getLanguage());
return encoding; return encoding;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Get all of the locale encodings * Get all of the locale encodings
@ -1642,7 +1596,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
path = URIUtil.canonicalPath(path); path = URIUtil.canonicalPath(path);
Resource resource = _baseResource.addPath(path); Resource resource = _baseResource.addPath(path);
if (checkAlias(path,resource)) if (checkAlias(path,resource))
return resource; return resource;
return null; return null;
@ -1684,7 +1638,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
} }
return true; return true;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations. * Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations.
@ -1696,7 +1650,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
return Resource.newResource(url); return Resource.newResource(url);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations. * Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations.
@ -1786,7 +1740,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
return _aliasChecks; return _aliasChecks;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param checks list of AliasCheck instances * @param checks list of AliasCheck instances
@ -1796,7 +1750,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
_aliasChecks.clear(); _aliasChecks.clear();
_aliasChecks.addAll(checks); _aliasChecks.addAll(checks);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* clear the list of AliasChecks * clear the list of AliasChecks
@ -1947,7 +1901,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
try try
{ {
HttpURI uri = new HttpURI(null,null,0,uriInContext); HttpURI uri = new HttpURI(null,null,0,uriInContext);
String pathInfo=URIUtil.canonicalPath(uri.getDecodedPath()); String pathInfo=URIUtil.canonicalPath(uri.getDecodedPath());
if (pathInfo==null) if (pathInfo==null)
return null; return null;
@ -1955,7 +1909,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
String contextPath=getContextPath(); String contextPath=getContextPath();
if (contextPath!=null && contextPath.length()>0) if (contextPath!=null && contextPath.length()>0)
uri.setPath(URIUtil.addPaths(contextPath,uri.getPath())); uri.setPath(URIUtil.addPaths(contextPath,uri.getPath()));
return new Dispatcher(ContextHandler.this,uri,pathInfo); return new Dispatcher(ContextHandler.this,uri,pathInfo);
} }
catch (Exception e) catch (Exception e)
@ -2127,7 +2081,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@Override @Override
public synchronized void setAttribute(String name, Object value) public synchronized void setAttribute(String name, Object value)
{ {
checkManagedAttribute(name,value);
Object old_value = super.getAttribute(name); Object old_value = super.getAttribute(name);
if (value == null) if (value == null)
@ -2158,8 +2111,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@Override @Override
public synchronized void removeAttribute(String name) public synchronized void removeAttribute(String name)
{ {
checkManagedAttribute(name,null);
Object old_value = super.getAttribute(name); Object old_value = super.getAttribute(name);
super.removeAttribute(name); super.removeAttribute(name);
if (old_value != null &&!_contextAttributeListeners.isEmpty()) if (old_value != null &&!_contextAttributeListeners.isEmpty())
@ -2290,55 +2241,54 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
public void setExtendedListenerTypes (boolean extended) public void setExtendedListenerTypes (boolean extended)
{ {
_extendedListenerTypes = extended; _extendedListenerTypes = extended;
} }
public boolean isExtendedListenerTypes() public boolean isExtendedListenerTypes()
{ {
return _extendedListenerTypes; return _extendedListenerTypes;
} }
@Override
public ClassLoader getClassLoader()
{
if (!_enabled)
throw new UnsupportedOperationException();
@Override //no security manager just return the classloader
public ClassLoader getClassLoader() if (System.getSecurityManager() == null)
{ return _classLoader;
if (!_enabled) else
throw new UnsupportedOperationException(); {
//check to see if the classloader of the caller is the same as the context
//no security manager just return the classloader //classloader, or a parent of it
if (System.getSecurityManager() == null) try
return _classLoader; {
else Class<?> reflect = Loader.loadClass(getClass(), "sun.reflect.Reflection");
{ Method getCallerClass = reflect.getMethod("getCallerClass", Integer.TYPE);
//check to see if the classloader of the caller is the same as the context Class<?> caller = (Class<?>)getCallerClass.invoke(null, 2);
//classloader, or a parent of it
try
{
Class<?> reflect = Loader.loadClass(getClass(), "sun.reflect.Reflection");
Method getCallerClass = reflect.getMethod("getCallerClass", Integer.TYPE);
Class<?> caller = (Class<?>)getCallerClass.invoke(null, 2);
boolean ok = false; boolean ok = false;
ClassLoader callerLoader = caller.getClassLoader(); ClassLoader callerLoader = caller.getClassLoader();
while (!ok && callerLoader != null) while (!ok && callerLoader != null)
{ {
if (callerLoader == _classLoader) if (callerLoader == _classLoader)
ok = true; ok = true;
else else
callerLoader = callerLoader.getParent(); callerLoader = callerLoader.getParent();
} }
if (ok) if (ok)
return _classLoader; return _classLoader;
} }
catch (Exception e) catch (Exception e)
{ {
LOG.warn("Unable to check classloader of caller",e); LOG.warn("Unable to check classloader of caller",e);
} }
AccessController.checkPermission(new RuntimePermission("getClassLoader")); AccessController.checkPermission(new RuntimePermission("getClassLoader"));
return _classLoader; return _classLoader;
} }
} }
@Override @Override
@ -2372,8 +2322,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return _enabled; return _enabled;
} }
public <T> T createInstance (Class<T> clazz) throws Exception public <T> T createInstance (Class<T> clazz) throws Exception
{ {
T o = clazz.newInstance(); T o = clazz.newInstance();
@ -2530,7 +2478,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return null; return null;
} }
@Override @Override
public boolean setInitParameter(String name, String value) public boolean setInitParameter(String name, String value)
{ {
@ -2763,7 +2710,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return true; return true;
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Approve Aliases of a non existent directory. /** Approve Aliases of a non existent directory.
* If a directory "/foobar/" does not exist, then the resource is * If a directory "/foobar/" does not exist, then the resource is
@ -2776,15 +2723,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
if (resource.exists()) if (resource.exists())
return false; return false;
String a=resource.getAlias().toString(); String a=resource.getAlias().toString();
String r=resource.getURL().toString(); String r=resource.getURL().toString();
if (a.length()>r.length()) if (a.length()>r.length())
return a.startsWith(r) && a.length()==r.length()+1 && a.endsWith("/"); return a.startsWith(r) && a.length()==r.length()+1 && a.endsWith("/");
if (a.length()<r.length()) if (a.length()<r.length())
return r.startsWith(a) && r.length()==a.length()+1 && r.endsWith("/"); return r.startsWith(a) && r.length()==a.length()+1 && r.endsWith("/");
return a.equals(r); return a.equals(r);
} }
} }

View File

@ -0,0 +1,107 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.handler;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
/** Enable Jetty style JMX MBeans from within a Context
*/
public class ManagedAttributeListener implements ServletContextListener, ServletContextAttributeListener
{
private static final Logger LOG = Log.getLogger(ManagedAttributeListener.class);
final Set<String> _managedAttributes=new HashSet<>();
final ContextHandler _context;
public ManagedAttributeListener(ContextHandler context,String... managedAttributes)
{
_context=context;
for (String attr:managedAttributes)
_managedAttributes.add(attr);
if (LOG.isDebugEnabled())
LOG.debug("managedAttributes {}",_managedAttributes);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event)
{
if (_managedAttributes.contains(event.getName()))
updateBean(event.getName(),event.getValue(),event.getServletContext().getAttribute(event.getName()));
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event)
{
if (_managedAttributes.contains(event.getName()))
updateBean(event.getName(),event.getValue(),null);
}
@Override
public void attributeAdded(ServletContextAttributeEvent event)
{
if (_managedAttributes.contains(event.getName()))
updateBean(event.getName(),null,event.getValue());
}
@Override
public void contextInitialized(ServletContextEvent event)
{
// Update existing attributes
Enumeration<String> e = event.getServletContext().getAttributeNames();
while (e.hasMoreElements())
{
String name = e.nextElement();
if (_managedAttributes.contains(name))
updateBean(name,null,event.getServletContext().getAttribute(name));
}
}
@Override
public void contextDestroyed(ServletContextEvent event)
{
Enumeration<String> e = _context.getServletContext().getAttributeNames();
while (e.hasMoreElements())
{
String name = e.nextElement();
if (_managedAttributes.contains(name))
updateBean(name,event.getServletContext().getAttribute(name),null);
}
}
protected void updateBean(String name,Object oldBean,Object newBean)
{
LOG.info("update {} {}->{} on {}",name,oldBean,newBean,_context);
if (LOG.isDebugEnabled())
LOG.debug("update {} {}->{} on {}",name,oldBean,newBean,_context);
_context.updateBean(oldBean,newBean,false);
}
}