JBossWeb SVN: r859 - trunk/webapps/docs.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-18 11:30:54 -0500 (Tue, 18 Nov 2008)
New Revision: 859
Modified:
trunk/webapps/docs/apr.xml
Log:
- Correctly point to JBoss Native.
Modified: trunk/webapps/docs/apr.xml
===================================================================
--- trunk/webapps/docs/apr.xml 2008-11-18 12:54:46 UTC (rev 858)
+++ trunk/webapps/docs/apr.xml 2008-11-18 16:30:54 UTC (rev 859)
@@ -17,7 +17,7 @@
<section name="Introduction">
<p>
- Tomcat can use the <a href="http://apr.apache.org/">Apache Portable Runtime</a> to
+ JBoss Web can use the <a href="http://apr.apache.org/">Apache Portable Runtime</a> to
provide superior scalability, performance, and better integration with native server
technologies. The Apache Portable Runtime is a highly portable library that is at
the heart of Apache HTTP Server 2.x. APR has many uses, including access to advanced IO
@@ -33,7 +33,7 @@
</p>
<p>
- <a href="http://labs.jboss.com/jbossweb/native.html">JBoss Web Native</a> provides bundle for severals platforms.
+ <a href="http://www.jboss.org/jbossweb/native.html">JBoss Native</a> provides bundle for severals platforms.
The bundles contain APR, OpenSSL and tc-native ready to use.
</p>
@@ -69,7 +69,7 @@
<p>
Most Linux distributions will ship packages for APR and OpenSSL. The JNI wrapper (libtcnative) will
then have to be compiled. It depends on APR, OpenSSL, and the Java headers.
- Some ready to use bundles are available <a href="http://labs.jboss.com/jbossweb/downloads/jboss-native/">here</a>.
+ Some ready to use bundles are available <a href="http://labs.jboss.com/jbossweb/downloads/jboss-native/">here</a>.
</p>
<p>
@@ -83,8 +83,7 @@
</p>
<p>
- The wrapper library sources are located in the JBoss Web binary bundle, in the
- <code>bin/tomcat-native.tar.gz</code> archive.
+ The wrapper library sources are located <a href="http://labs.jboss.com/jbossweb/downloads/jboss-native/">here</a>.
Once the build environment is installed and the source archive is extracted, the wrapper library
can be compiled using (from the folder containing the configure script):
<source>./configure && make && make install</source>
16 years, 1 month
JBossWeb SVN: r858 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-18 07:54:46 -0500 (Tue, 18 Nov 2008)
New Revision: 858
Modified:
trunk/java/org/apache/catalina/startup/HostConfig.java
trunk/webapps/docs/changelog.xml
Log:
- port minor deployer patch.
Modified: trunk/java/org/apache/catalina/startup/HostConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/HostConfig.java 2008-11-17 12:45:06 UTC (rev 857)
+++ trunk/java/org/apache/catalina/startup/HostConfig.java 2008-11-18 12:54:46 UTC (rev 858)
@@ -950,6 +950,7 @@
digester.reset();
}
}
+ configBase.mkdirs();
File xmlCopy = new File(configBase, file + ".xml");
InputStream is = null;
OutputStream os = null;
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-17 12:45:06 UTC (rev 857)
+++ trunk/webapps/docs/changelog.xml 2008-11-18 12:54:46 UTC (rev 858)
@@ -39,6 +39,9 @@
<fix>
If throwing an exception for a non serializable attribute, mention the attribute name in the exception. (mturk)
</fix>
+ <fix>
+ Create configBase also when dealing with directory deployment. (markt)
+ </fix>
</changelog>
</subsection>
</section>
16 years, 1 month
JBossWeb SVN: r857 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-17 07:45:06 -0500 (Mon, 17 Nov 2008)
New Revision: 857
Modified:
trunk/java/org/apache/catalina/session/LocalStrings.properties
trunk/java/org/apache/catalina/session/StandardSession.java
trunk/webapps/docs/changelog.xml
Log:
- Add attribute name to the ISE.
Modified: trunk/java/org/apache/catalina/session/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/session/LocalStrings.properties 2008-11-14 12:47:16 UTC (rev 856)
+++ trunk/java/org/apache/catalina/session/LocalStrings.properties 2008-11-17 12:45:06 UTC (rev 857)
@@ -48,7 +48,7 @@
standardSession.notSerializable=Cannot serialize session attribute {0} for session {1}
standardSession.removeAttribute.ise=removeAttribute: Session already invalidated
standardSession.sessionEvent=Session event listener threw exception
-standardSession.setAttribute.iae=setAttribute: Non-serializable attribute
+standardSession.setAttribute.iae=setAttribute: Non-serializable attribute {0}
standardSession.setAttribute.ise=setAttribute: Session already invalidated
standardSession.setAttribute.namenull=setAttribute: name parameter cannot be null
standardSession.sessionCreated=Created Session id = {0}
Modified: trunk/java/org/apache/catalina/session/StandardSession.java
===================================================================
--- trunk/java/org/apache/catalina/session/StandardSession.java 2008-11-14 12:47:16 UTC (rev 856)
+++ trunk/java/org/apache/catalina/session/StandardSession.java 2008-11-17 12:45:06 UTC (rev 857)
@@ -1295,7 +1295,7 @@
if ((manager != null) && manager.getDistributable() &&
!(value instanceof Serializable))
throw new IllegalArgumentException
- (sm.getString("standardSession.setAttribute.iae"));
+ (sm.getString("standardSession.setAttribute.iae", name));
// Construct an event with the new value
HttpSessionBindingEvent event = null;
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-14 12:47:16 UTC (rev 856)
+++ trunk/webapps/docs/changelog.xml 2008-11-17 12:45:06 UTC (rev 857)
@@ -36,6 +36,9 @@
<bug>42673</bug>: In SSI, correctly handle includes with multi-level contexts.
Patch provided by Peter Jodeleit. (markt)
</fix>
+ <fix>
+ If throwing an exception for a non serializable attribute, mention the attribute name in the exception. (mturk)
+ </fix>
</changelog>
</subsection>
</section>
16 years, 1 month
JBossWeb SVN: r856 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-14 07:47:16 -0500 (Fri, 14 Nov 2008)
New Revision: 856
Modified:
trunk/java/org/apache/catalina/session/StandardSession.java
trunk/webapps/docs/changelog.xml
Log:
- Remove trace like logging of session values.
Modified: trunk/java/org/apache/catalina/session/StandardSession.java
===================================================================
--- trunk/java/org/apache/catalina/session/StandardSession.java 2008-11-12 15:12:35 UTC (rev 855)
+++ trunk/java/org/apache/catalina/session/StandardSession.java 2008-11-14 12:47:16 UTC (rev 856)
@@ -1443,9 +1443,6 @@
Object value = (Object) stream.readObject();
if ((value instanceof String) && (value.equals(NOT_SERIALIZED)))
continue;
- if (manager.getContainer().getLogger().isDebugEnabled())
- manager.getContainer().getLogger().debug(" loading attribute '" + name +
- "' with value '" + value + "'");
attributes.put(name, value);
}
isValid = isValidSave;
@@ -1517,10 +1514,6 @@
stream.writeObject((String) saveNames.get(i));
try {
stream.writeObject(saveValues.get(i));
- if (manager.getContainer().getLogger().isDebugEnabled())
- manager.getContainer().getLogger().debug
- (" storing attribute '" + saveNames.get(i) +
- "' with value '" + saveValues.get(i) + "'");
} catch (NotSerializableException e) {
manager.getContainer().getLogger().warn
(sm.getString("standardSession.notSerializable",
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-12 15:12:35 UTC (rev 855)
+++ trunk/webapps/docs/changelog.xml 2008-11-14 12:47:16 UTC (rev 856)
@@ -111,6 +111,9 @@
<fix>
Only reset the buffer and usage of IS or writer when forwarding to a custom error page. (markt, remm)
</fix>
+ <fix>
+ Remove verbose attribute value logging during session passivation. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
16 years, 1 month
JBossWeb SVN: r855 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-12 10:12:35 -0500 (Wed, 12 Nov 2008)
New Revision: 855
Modified:
trunk/java/org/apache/catalina/ssi/SSIServletExternalResolver.java
trunk/webapps/docs/changelog.xml
Log:
- 42673: Port SSI fix.
Modified: trunk/java/org/apache/catalina/ssi/SSIServletExternalResolver.java
===================================================================
--- trunk/java/org/apache/catalina/ssi/SSIServletExternalResolver.java 2008-11-12 15:07:26 UTC (rev 854)
+++ trunk/java/org/apache/catalina/ssi/SSIServletExternalResolver.java 2008-11-12 15:12:35 UTC (rev 855)
@@ -353,14 +353,12 @@
}
- protected String getPathWithoutContext(String servletPath) {
- String retVal = null;
- int secondSlash = servletPath.indexOf('/', 1);
- if (secondSlash >= 0) {
- //cut off context
- retVal = servletPath.substring(secondSlash);
+ protected String getPathWithoutContext(final String contextPath,
+ final String servletPath) {
+ if (servletPath.startsWith(contextPath)) {
+ return servletPath.substring(contextPath.length());
}
- return retVal;
+ return servletPath;
}
@@ -419,7 +417,8 @@
// ie:
// '/file1.shtml' vs '/appName1/file1.shtml'
if (!isRootContext(normContext)) {
- String noContext = getPathWithoutContext(normalized);
+ String noContext = getPathWithoutContext(
+ normContext.getContextPath(), normalized);
if (noContext == null) {
throw new IOException(
"Couldn't remove context from path: "
@@ -571,4 +570,4 @@
return path;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-12 15:07:26 UTC (rev 854)
+++ trunk/webapps/docs/changelog.xml 2008-11-12 15:12:35 UTC (rev 855)
@@ -32,6 +32,10 @@
<fix>
<bug>42747</bug>: Harmonize handling of context.xml between war and exploded folder. (markt)
</fix>
+ <fix>
+ <bug>42673</bug>: In SSI, correctly handle includes with multi-level contexts.
+ Patch provided by Peter Jodeleit. (markt)
+ </fix>
</changelog>
</subsection>
</section>
16 years, 1 month
JBossWeb SVN: r854 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-12 10:07:26 -0500 (Wed, 12 Nov 2008)
New Revision: 854
Modified:
trunk/java/org/apache/catalina/startup/HostConfig.java
trunk/webapps/docs/changelog.xml
Log:
- Harmonize context.xml handling.
Modified: trunk/java/org/apache/catalina/startup/HostConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/HostConfig.java 2008-11-12 14:59:30 UTC (rev 853)
+++ trunk/java/org/apache/catalina/startup/HostConfig.java 2008-11-12 15:07:26 UTC (rev 854)
@@ -21,9 +21,11 @@
import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -41,6 +43,7 @@
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.core.ContainerBase;
import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.util.IOTools;
import org.apache.catalina.util.StringManager;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.modeler.Registry;
@@ -122,14 +125,15 @@
/**
* Map of deployed applications.
*/
- protected HashMap deployed = new HashMap();
+ protected HashMap<String, DeployedApplication> deployed =
+ new HashMap<String, DeployedApplication>();
/**
* List of applications which are being serviced, and shouldn't be
* deployed/undeployed/redeployed at the moment.
*/
- protected ArrayList serviced = new ArrayList();
+ protected ArrayList<String> serviced = new ArrayList<String>();
/**
@@ -346,12 +350,12 @@
* on which the application was deployed
*/
public long getDeploymentTime(String name) {
- DeployedApplication app = (DeployedApplication) deployed.get(name);
- if (app == null) {
- return 0L;
- } else {
- return app.timestamp;
- }
+ DeployedApplication app = deployed.get(name);
+ if (app == null) {
+ return 0L;
+ } else {
+ return app.timestamp;
+ }
}
@@ -363,7 +367,7 @@
* exist
*/
public boolean isDeployed(String name) {
- DeployedApplication app = (DeployedApplication) deployed.get(name);
+ DeployedApplication app = deployed.get(name);
if (app == null) {
return false;
} else {
@@ -591,7 +595,7 @@
}
}
if (context instanceof Lifecycle) {
- Class clazz = Class.forName(host.getConfigClass());
+ Class<?> clazz = Class.forName(host.getConfigClass());
LifecycleListener listener =
(LifecycleListener) clazz.newInstance();
((Lifecycle) context).addLifecycleListener(listener);
@@ -599,7 +603,7 @@
context.setConfigFile(contextXml.getAbsolutePath());
context.setPath(contextPath);
// Add the associated docBase to the redeployed list if it's a WAR
- boolean isWar = false;
+ boolean isExternalWar = false;
boolean isExternal = false;
if (context.getDocBase() != null) {
File docBase = new File(context.getDocBase());
@@ -607,14 +611,15 @@
docBase = new File(appBase(), context.getDocBase());
}
// If external docBase, register .xml as redeploy first
- if (!docBase.getCanonicalPath().startsWith(appBase().getAbsolutePath() + File.separator)) {
+ if (!docBase.getCanonicalPath().startsWith(
+ appBase().getAbsolutePath() + File.separator)) {
isExternal = true;
deployedApp.redeployResources.put
(contextXml.getAbsolutePath(), new Long(contextXml.lastModified()));
deployedApp.redeployResources.put(docBase.getAbsolutePath(),
new Long(docBase.lastModified()));
if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) {
- isWar = true;
+ isExternalWar = true;
}
} else {
log.warn(sm.getString("hostConfig.deployDescriptor.localDocBaseSpecified",
@@ -636,15 +641,19 @@
name = path;
}
}
- File expandedDocBase = new File(name);
- File warDocBase = new File(name + ".war");
- if (!expandedDocBase.isAbsolute()) {
- expandedDocBase = new File(appBase(), name);
- warDocBase = new File(appBase(), name + ".war");
+ // default to appBase dir + name
+ File expandedDocBase = new File(appBase(), name);
+ if (context.getDocBase() != null) {
+ // first assume docBase is absolute
+ expandedDocBase = new File(context.getDocBase());
+ if (!expandedDocBase.isAbsolute()) {
+ // if docBase specified and relative, it must be relative to appBase
+ expandedDocBase = new File(appBase(), context.getDocBase());
+ }
}
// Add the eventual unpacked WAR and all the resources which will be
// watched inside it
- if (isWar && unpackWARs) {
+ if (isExternalWar && unpackWARs) {
deployedApp.redeployResources.put(expandedDocBase.getAbsolutePath(),
new Long(expandedDocBase.lastModified()));
deployedApp.redeployResources.put
@@ -652,9 +661,12 @@
addWatchedResources(deployedApp, expandedDocBase.getAbsolutePath(), context);
} else {
// Find an existing matching war and expanded folder
- if (warDocBase.exists()) {
- deployedApp.redeployResources.put(warDocBase.getAbsolutePath(),
- new Long(warDocBase.lastModified()));
+ if (!isExternal) {
+ File warDocBase = new File(expandedDocBase.getAbsolutePath() + ".war");
+ if (warDocBase.exists()) {
+ deployedApp.redeployResources.put(warDocBase.getAbsolutePath(),
+ new Long(warDocBase.lastModified()));
+ }
}
if (expandedDocBase.exists()) {
deployedApp.redeployResources.put(expandedDocBase.getAbsolutePath(),
@@ -722,10 +734,10 @@
/**
* @param contextPath
- * @param dir
+ * @param war
* @param file
*/
- protected void deployWAR(String contextPath, File dir, String file) {
+ protected void deployWAR(String contextPath, File war, String file) {
if (deploymentExists(contextPath))
return;
@@ -739,7 +751,7 @@
(configBase, file.substring(0, file.lastIndexOf(".")) + ".xml");
if (deployXML && !xml.exists()) {
try {
- jar = new JarFile(dir);
+ jar = new JarFile(war);
entry = jar.getJarEntry(Constants.ApplicationContextXml);
if (entry != null) {
istream = jar.getInputStream(entry);
@@ -772,7 +784,7 @@
try {
ostream.close();
} catch (Throwable t) {
- ;
+ // Ignore
}
ostream = null;
}
@@ -780,7 +792,7 @@
try {
istream.close();
} catch (Throwable t) {
- ;
+ // Ignore
}
istream = null;
}
@@ -790,7 +802,7 @@
try {
jar.close();
} catch (Throwable t) {
- ;
+ // Ignore
}
jar = null;
}
@@ -803,25 +815,40 @@
if(log.isInfoEnabled())
log.info(sm.getString("hostConfig.deployJar", file));
- // Populate redeploy resources with the WAR file
- deployedApp.redeployResources.put
- (dir.getAbsolutePath(), new Long(dir.lastModified()));
+ try {
+ Context context = null;
+ if (deployXML && xml.exists()) {
+ synchronized (digester) {
+ try {
+ context = (Context) digester.parse(xml);
+ if (context == null) {
+ log.error(sm.getString("hostConfig.deployDescriptor.error",
+ file));
+ return;
+ }
+ } finally {
+ digester.reset();
+ }
+ }
+ context.setConfigFile(xml.getAbsolutePath());
+ deployedApp.redeployResources.put
+ (xml.getAbsolutePath(), new Long(xml.lastModified()));
+ } else {
+ context = (Context) Class.forName(contextClass).newInstance();
+ }
- try {
- Context context = (Context) Class.forName(contextClass).newInstance();
+ // Populate redeploy resources with the WAR file
+ deployedApp.redeployResources.put
+ (war.getAbsolutePath(), new Long(war.lastModified()));
+
if (context instanceof Lifecycle) {
- Class clazz = Class.forName(host.getConfigClass());
+ Class<?> clazz = Class.forName(host.getConfigClass());
LifecycleListener listener =
(LifecycleListener) clazz.newInstance();
((Lifecycle) context).addLifecycleListener(listener);
}
context.setPath(contextPath);
context.setDocBase(file);
- if (xml.exists()) {
- context.setConfigFile(xml.getAbsolutePath());
- deployedApp.redeployResources.put
- (xml.getAbsolutePath(), new Long(xml.lastModified()));
- }
host.addChild(context);
// If we're unpacking WARs, the docBase will be mutated after
// starting the context
@@ -905,26 +932,62 @@
if( log.isDebugEnabled() )
log.debug(sm.getString("hostConfig.deployDir", file));
try {
- Context context = (Context) Class.forName(contextClass).newInstance();
+ Context context = null;
+ File xml = new File(dir, Constants.ApplicationContextXml);
+ if (deployXML && xml.exists()) {
+ // Will only do this on initial deployment. On subsequent
+ // deployments the copied xml file means we'll use
+ // deployDescriptor() instead
+ synchronized (digester) {
+ try {
+ context = (Context) digester.parse(xml);
+ if (context == null) {
+ log.error(sm.getString("hostConfig.deployDescriptor.error",
+ xml));
+ return;
+ }
+ } finally {
+ digester.reset();
+ }
+ }
+ File xmlCopy = new File(configBase, file + ".xml");
+ InputStream is = null;
+ OutputStream os = null;
+ try {
+ is = new FileInputStream(xml);
+ os = new FileOutputStream(xmlCopy);
+ IOTools.flow(is, os);
+ // Don't catch IOE - let the outer try/catch handle it
+ } finally {
+ try {
+ if (is != null) is.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ try {
+ if (os != null) os.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ }
+ context.setConfigFile(xmlCopy.getAbsolutePath());
+ deployedApp.redeployResources.put
+ (xmlCopy.getAbsolutePath(), new Long(xmlCopy.lastModified()));
+ } else {
+ context = (Context) Class.forName(contextClass).newInstance();
+ }
+
if (context instanceof Lifecycle) {
- Class clazz = Class.forName(host.getConfigClass());
+ Class<?> clazz = Class.forName(host.getConfigClass());
LifecycleListener listener =
(LifecycleListener) clazz.newInstance();
((Lifecycle) context).addLifecycleListener(listener);
}
context.setPath(contextPath);
context.setDocBase(file);
- File configFile = new File(dir, Constants.ApplicationContextXml);
- if (deployXML) {
- context.setConfigFile(configFile.getAbsolutePath());
- }
host.addChild(context);
deployedApp.redeployResources.put(dir.getAbsolutePath(),
new Long(dir.lastModified()));
- if (deployXML) {
- deployedApp.redeployResources.put(configFile.getAbsolutePath(),
- new Long(configFile.lastModified()));
- }
addWatchedResources(deployedApp, dir.getAbsolutePath(), context);
} catch (Throwable t) {
log.error(sm.getString("hostConfig.deployDir.error", file), t);
@@ -967,9 +1030,13 @@
if (docBase != null) {
resource = new File(docBaseFile, watchedResources[i]);
} else {
+ if(log.isDebugEnabled())
+ log.debug("Ignoring non-existent WatchedResource '" + resource.getAbsolutePath() + "'");
continue;
}
}
+ if(log.isDebugEnabled())
+ log.debug("Watching WatchedResource '" + resource.getAbsolutePath() + "'");
app.reloadResources.put(resource.getAbsolutePath(),
new Long(resource.lastModified()));
}
@@ -980,13 +1047,15 @@
* Check resources for redeployment and reloading.
*/
protected synchronized void checkResources(DeployedApplication app) {
- String[] resources = (String[]) app.redeployResources.keySet().toArray(new String[0]);
+ String[] resources =
+ app.redeployResources.keySet().toArray(new String[0]);
for (int i = 0; i < resources.length; i++) {
File resource = new File(resources[i]);
if (log.isDebugEnabled())
log.debug("Checking context[" + app.name + "] redeploy resource " + resource);
if (resource.exists()) {
- long lastModified = ((Long) app.redeployResources.get(resources[i])).longValue();
+ long lastModified =
+ app.redeployResources.get(resources[i]).longValue();
if ((!resource.isDirectory()) && resource.lastModified() > lastModified) {
// Undeploy application
if (log.isInfoEnabled())
@@ -1024,7 +1093,8 @@
return;
}
} else {
- long lastModified = ((Long) app.redeployResources.get(resources[i])).longValue();
+ long lastModified =
+ app.redeployResources.get(resources[i]).longValue();
if (lastModified == 0L) {
continue;
}
@@ -1061,7 +1131,8 @@
}
}
// Delete reload resources as well (to remove any remaining .xml descriptor)
- String[] resources2 = (String[]) app.reloadResources.keySet().toArray(new String[0]);
+ String[] resources2 =
+ app.reloadResources.keySet().toArray(new String[0]);
for (int j = 0; j < resources2.length; j++) {
try {
File current = new File(resources2[j]);
@@ -1082,12 +1153,12 @@
return;
}
}
- resources = (String[]) app.reloadResources.keySet().toArray(new String[0]);
+ resources = app.reloadResources.keySet().toArray(new String[0]);
for (int i = 0; i < resources.length; i++) {
File resource = new File(resources[i]);
if (log.isDebugEnabled())
log.debug("Checking context[" + app.name + "] reload resource " + resource);
- long lastModified = ((Long) app.reloadResources.get(resources[i])).longValue();
+ long lastModified = app.reloadResources.get(resources[i]).longValue();
if ((!resource.exists() && lastModified != 0L)
|| (resource.lastModified() != lastModified)) {
// Reload application
@@ -1174,8 +1245,8 @@
log.debug(sm.getString("hostConfig.undeploying"));
// Soft undeploy all contexts we have deployed
- DeployedApplication[] apps =
- (DeployedApplication[]) deployed.values().toArray(new DeployedApplication[0]);
+ DeployedApplication[] apps =
+ deployed.values().toArray(new DeployedApplication[0]);
for (int i = 0; i < apps.length; i++) {
try {
host.removeChild(host.findChild(apps[i].name));
@@ -1198,7 +1269,7 @@
if (host.getAutoDeploy()) {
// Check for resources modification to trigger redeployment
DeployedApplication[] apps =
- (DeployedApplication[]) deployed.values().toArray(new DeployedApplication[0]);
+ deployed.values().toArray(new DeployedApplication[0]);
for (int i = 0; i < apps.length; i++) {
if (!isServiced(apps[i].name))
checkResources(apps[i]);
@@ -1214,7 +1285,7 @@
* Check status of a specific webapp, for use with stuff like management webapps.
*/
public void check(String name) {
- DeployedApplication app = (DeployedApplication) deployed.get(name);
+ DeployedApplication app = deployed.get(name);
if (app != null) {
checkResources(app);
} else {
@@ -1295,38 +1366,40 @@
* the monitored resources.
*/
protected class DeployedApplication {
- public DeployedApplication(String name) {
- this.name = name;
- }
-
- /**
- * Application context path. The assertion is that
- * (host.getChild(name) != null).
- */
- public String name;
-
- /**
- * Any modification of the specified (static) resources will cause a
- * redeployment of the application. If any of the specified resources is
- * removed, the application will be undeployed. Typically, this will
- * contain resources like the context.xml file, a compressed WAR path.
+ public DeployedApplication(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Application context path. The assertion is that
+ * (host.getChild(name) != null).
+ */
+ public String name;
+
+ /**
+ * Any modification of the specified (static) resources will cause a
+ * redeployment of the application. If any of the specified resources is
+ * removed, the application will be undeployed. Typically, this will
+ * contain resources like the context.xml file, a compressed WAR path.
* The value is the last modification time.
- */
- public LinkedHashMap redeployResources = new LinkedHashMap();
+ */
+ public LinkedHashMap<String, Long> redeployResources =
+ new LinkedHashMap<String, Long>();
- /**
- * Any modification of the specified (static) resources will cause a
- * reload of the application. This will typically contain resources
- * such as the web.xml of a webapp, but can be configured to contain
- * additional descriptors.
+ /**
+ * Any modification of the specified (static) resources will cause a
+ * reload of the application. This will typically contain resources
+ * such as the web.xml of a webapp, but can be configured to contain
+ * additional descriptors.
* The value is the last modification time.
- */
- public HashMap reloadResources = new HashMap();
+ */
+ public HashMap<String, Long> reloadResources =
+ new HashMap<String, Long>();
- /**
- * Instant where the application was last put in service.
- */
- public long timestamp = System.currentTimeMillis();
+ /**
+ * Instant where the application was last put in service.
+ */
+ public long timestamp = System.currentTimeMillis();
}
}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-12 14:59:30 UTC (rev 853)
+++ trunk/webapps/docs/changelog.xml 2008-11-12 15:07:26 UTC (rev 854)
@@ -26,8 +26,11 @@
<fix>
<bug>42707</bug>: Adding host aliases should be dynamic. (markt)
</fix>
+ <update>
+ JNDI realm feature additions. (rjung)
+ </update>
<fix>
- JNDI realm feature additions. (rjung)
+ <bug>42747</bug>: Harmonize handling of context.xml between war and exploded folder. (markt)
</fix>
</changelog>
</subsection>
16 years, 1 month
JBossWeb SVN: r853 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-12 09:59:30 -0500 (Wed, 12 Nov 2008)
New Revision: 853
Modified:
trunk/java/org/apache/catalina/realm/JNDIRealm.java
trunk/webapps/docs/changelog.xml
Log:
- Port JNDI realm updates (not very useful, but does not hurt).
Modified: trunk/java/org/apache/catalina/realm/JNDIRealm.java
===================================================================
--- trunk/java/org/apache/catalina/realm/JNDIRealm.java 2008-11-12 14:57:19 UTC (rev 852)
+++ trunk/java/org/apache/catalina/realm/JNDIRealm.java 2008-11-12 14:59:30 UTC (rev 853)
@@ -5,9 +5,9 @@
* The ASF licenses this file to You 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.
@@ -22,8 +22,13 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import javax.naming.Context;
import javax.naming.CommunicationException;
@@ -35,6 +40,7 @@
import javax.naming.NameParser;
import javax.naming.Name;
import javax.naming.AuthenticationException;
+import javax.naming.PartialResultException;
import javax.naming.ServiceUnavailableException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
@@ -132,6 +138,14 @@
* in the user's element whose name is configured by the
* <code>userRoleName</code> property.</li>
*
+ * <li>A default role can be assigned to each user that was successfully
+ * authenticated by setting the <code>commonRole</code> property to the
+ * name of this role. The role doesn't have to exist in the directory.</li>
+ *
+ * <li>If the directory server contains nested roles, you can search for roles
+ * recursively by setting <code>roleRecursionLimit</code> to some positive value.
+ * The default value is <code>0</code>, so role searches do not recurse.</li>
+ *
* <li>Note that the standard <code><security-role-ref></code> element in
* the web application deployment descriptor allows applications to refer
* to roles programmatically by names other than those used in the
@@ -195,14 +209,14 @@
*/
protected String contextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
-
+
/**
* How aliases should be dereferenced during search operations.
*/
protected String derefAliases = null;
/**
- * Constant that holds the name of the environment property for specifying
+ * Constant that holds the name of the environment property for specifying
* the manner in which aliases should be dereferenced.
*/
public final static String DEREF_ALIASES = "java.naming.ldap.derefAliases";
@@ -228,10 +242,21 @@
/**
- * How should we handle referrals? Microsoft Active Directory can't handle
- * the default case, so an application authenticating against AD must
- * set referrals to "follow".
+ * Should we ignore PartialResultExceptions when iterating over NamingEnumerations?
+ * Microsoft Active Directory often returns referrals, which lead
+ * to PartialResultExceptions. Unfortunately there's no stable way to detect,
+ * if the Exceptions really come from an AD referral.
+ * Set to true to ignore PartialResultExceptions.
*/
+ protected boolean adCompat = false;
+
+
+ /**
+ * How should we handle referrals? Microsoft Active Directory often returns
+ * referrals. If you need to follow them set referrals to "follow".
+ * Caution: if your DNS is not part of AD, the LDAP client lib might try
+ * to resolve your domain name in DNS to find another LDAP server.
+ */
protected String referrals = null;
@@ -294,6 +319,13 @@
/**
+ * The maximum recursion depth when resolving roles recursively.
+ * By default we don't resolve roles recursively.
+ */
+ protected int roleRecursionLimit = 0;
+
+
+ /**
* The base element for role searches.
*/
protected String roleBase = "";
@@ -343,10 +375,11 @@
protected int connectionAttempt = 0;
/**
- * The current user pattern to be used for lookup and binding of a user.
+ * Add this role to every authenticated user
*/
- protected int curUserPattern = 0;
+ protected String commonRole = null;
+
// ------------------------------------------------------------- Properties
/**
@@ -461,11 +494,11 @@
*/
public java.lang.String getDerefAliases() {
return derefAliases;
- }
-
+ }
+
/**
* Set the value for derefAliases to be used when searching the directory.
- *
+ *
* @param derefAliases New value of property derefAliases.
*/
public void setDerefAliases(java.lang.String derefAliases) {
@@ -494,6 +527,23 @@
/**
+ * Returns the current settings for handling PartialResultExceptions
+ */
+ public boolean getAdCompat () {
+ return adCompat;
+ }
+
+
+ /**
+ * How do we handle PartialResultExceptions?
+ * True: ignore all PartialResultExceptions.
+ */
+ public void setAdCompat (boolean adCompat) {
+ this.adCompat = adCompat;
+ }
+
+
+ /**
* Returns the current settings for handling JNDI referrals.
*/
public String getReferrals () {
@@ -602,6 +652,28 @@
/**
+ * Return the maximum recursion depth for role searches.
+ */
+ public int getRoleRecursionLimit() {
+
+ return (this.roleRecursionLimit);
+
+ }
+
+
+ /**
+ * Set the maximum recursion depth for role searches.
+ *
+ * @param roleRecursionLimit The new recursion limit
+ */
+ public void setRoleRecursionLimit(int roleRecursionLimit) {
+
+ this.roleRecursionLimit = roleRecursionLimit;
+
+ }
+
+
+ /**
* Return the base element for role searches.
*/
public String getRoleBase() {
@@ -776,6 +848,28 @@
}
+ /**
+ * Return the common role
+ */
+ public String getCommonRole() {
+
+ return commonRole;
+
+ }
+
+
+ /**
+ * Set the common role
+ *
+ * @param commonRole The common role
+ */
+ public void setCommonRole(String commonRole) {
+
+ this.commonRole = commonRole;
+
+ }
+
+
// ---------------------------------------------------------- Realm Methods
@@ -875,6 +969,8 @@
close(context);
// Return "not authenticated" for this request
+ if (containerLog.isDebugEnabled())
+ containerLog.debug("Returning null principal.");
return (null);
}
@@ -905,21 +1001,30 @@
throws NamingException {
if (username == null || username.equals("")
- || credentials == null || credentials.equals(""))
+ || credentials == null || credentials.equals("")) {
+ if (containerLog.isDebugEnabled())
+ containerLog.debug("username null or empty: returning null principal.");
return (null);
+ }
if (userPatternArray != null) {
- for (curUserPattern = 0;
+ for (int curUserPattern = 0;
curUserPattern < userPatternFormatArray.length;
curUserPattern++) {
// Retrieve user information
- User user = getUser(context, username);
+ User user = getUser(context, username, credentials, curUserPattern);
if (user != null) {
try {
// Check the user's credentials
if (checkCredentials(context, user, credentials)) {
// Search for additional roles
List<String> roles = getRoles(context, user);
+ if (containerLog.isDebugEnabled()) {
+ Iterator<String> it = roles.iterator();
+ while (it.hasNext()) {
+ containerLog.debug("Found role: " + it.next());
+ }
+ }
return (new GenericPrincipal(this,
username,
credentials,
@@ -938,7 +1043,7 @@
return null;
} else {
// Retrieve user information
- User user = getUser(context, username);
+ User user = getUser(context, username, credentials);
if (user == null)
return (null);
@@ -948,6 +1053,12 @@
// Search for additional roles
List<String> roles = getRoles(context, user);
+ if (containerLog.isDebugEnabled()) {
+ Iterator<String> it = roles.iterator();
+ while (it.hasNext()) {
+ containerLog.debug("Found role: " + it.next());
+ }
+ }
// Create and return a suitable Principal for this user
return (new GenericPrincipal(this, username, credentials, roles));
@@ -960,6 +1071,45 @@
* with the specified username, if found in the directory;
* otherwise return <code>null</code>.
*
+ * @param context The directory context
+ * @param username Username to be looked up
+ *
+ * @exception NamingException if a directory server error occurs
+ *
+ * @see #getUser(DirContext, String, String, int)
+ */
+ protected User getUser(DirContext context, String username)
+ throws NamingException {
+
+ return getUser(context, username, null, -1);
+ }
+
+
+ /**
+ * Return a User object containing information about the user
+ * with the specified username, if found in the directory;
+ * otherwise return <code>null</code>.
+ *
+ * @param context The directory context
+ * @param username Username to be looked up
+ * @param credentials User credentials (optional)
+ *
+ * @exception NamingException if a directory server error occurs
+ *
+ * @see #getUser(DirContext, String, int)
+ */
+ protected User getUser(DirContext context, String username, String credentials)
+ throws NamingException {
+
+ return getUser(context, username, credentials, -1);
+ }
+
+
+ /**
+ * Return a User object containing information about the user
+ * with the specified username, if found in the directory;
+ * otherwise return <code>null</code>.
+ *
* If the <code>userPassword</code> configuration attribute is
* specified, the value of that attribute is retrieved from the
* user's directory entry. If the <code>userRoleName</code>
@@ -968,10 +1118,13 @@
*
* @param context The directory context
* @param username Username to be looked up
+ * @param credentials User credentials (optional)
+ * @param curUserPattern Index into userPatternFormatArray
*
* @exception NamingException if a directory server error occurs
*/
- protected User getUser(DirContext context, String username)
+ protected User getUser(DirContext context, String username,
+ String credentials, int curUserPattern)
throws NamingException {
User user = null;
@@ -986,8 +1139,8 @@
list.toArray(attrIds);
// Use pattern or search for user entry
- if (userPatternFormatArray != null) {
- user = getUserByPattern(context, username, attrIds);
+ if (userPatternFormatArray != null && curUserPattern >= 0) {
+ user = getUserByPattern(context, username, credentials, attrIds, curUserPattern);
} else {
user = getUserBySearch(context, username, attrIds);
}
@@ -997,29 +1150,24 @@
/**
- * Use the <code>UserPattern</code> configuration attribute to
- * locate the directory entry for the user with the specified
- * username and return a User object; otherwise return
- * <code>null</code>.
+ * Use the distinguished name to locate the directory
+ * entry for the user with the specified username and
+ * return a User object; otherwise return <code>null</code>.
*
* @param context The directory context
* @param username The username
* @param attrIds String[]containing names of attributes to
+ * @param dn Distinguished name of the user
* retrieve.
*
* @exception NamingException if a directory server error occurs
*/
protected User getUserByPattern(DirContext context,
- String username,
- String[] attrIds)
+ String username,
+ String[] attrIds,
+ String dn)
throws NamingException {
- if (username == null || userPatternFormatArray[curUserPattern] == null)
- return (null);
-
- // Form the dn from the user pattern
- String dn = userPatternFormatArray[curUserPattern].format(new String[] { username });
-
// Get required attributes from user entry
Attributes attrs = null;
try {
@@ -1045,6 +1193,71 @@
/**
+ * Use the <code>UserPattern</code> configuration attribute to
+ * locate the directory entry for the user with the specified
+ * username and return a User object; otherwise return
+ * <code>null</code>.
+ *
+ * @param context The directory context
+ * @param username The username
+ * @param credentials User credentials (optional)
+ * @param attrIds String[]containing names of attributes to
+ * @param curUserPattern Index into userPatternFormatArray
+ *
+ * @exception NamingException if a directory server error occurs
+ * @see #getUserByPattern(DirContext, String, String[], String)
+ */
+ protected User getUserByPattern(DirContext context,
+ String username,
+ String credentials,
+ String[] attrIds,
+ int curUserPattern)
+ throws NamingException {
+
+ User user = null;
+
+ if (username == null || userPatternFormatArray[curUserPattern] == null)
+ return (null);
+
+ // Form the dn from the user pattern
+ String dn = userPatternFormatArray[curUserPattern].format(new String[] { username });
+
+ try {
+ user = getUserByPattern(context, username, attrIds, dn);
+ } catch (NameNotFoundException e) {
+ return (null);
+ } catch (NamingException e) {
+ // If the getUserByPattern() call fails, try it again with the
+ // credentials of the user that we're searching for
+ try {
+ // Set up security environment to bind as the user
+ context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
+ context.addToEnvironment(Context.SECURITY_CREDENTIALS, credentials);
+
+ user = getUserByPattern(context, username, attrIds, dn);
+ } finally {
+ // Restore the original security environment
+ if (connectionName != null) {
+ context.addToEnvironment(Context.SECURITY_PRINCIPAL,
+ connectionName);
+ } else {
+ context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
+ }
+
+ if (connectionPassword != null) {
+ context.addToEnvironment(Context.SECURITY_CREDENTIALS,
+ connectionPassword);
+ }
+ else {
+ context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
+ }
+ }
+ }
+ return user;
+ }
+
+
+ /**
* Search the directory to return a User object containing
* information about the user with the specified username, if
* found in the directory; otherwise return <code>null</code>.
@@ -1056,8 +1269,8 @@
* @exception NamingException if a directory server error occurs
*/
protected User getUserBySearch(DirContext context,
- String username,
- String[] attrIds)
+ String username,
+ String[] attrIds)
throws NamingException {
if (username == null || userSearchFormat == null)
@@ -1086,32 +1299,34 @@
// Fail if no entries found
- if (results == null || !results.hasMore()) {
- return (null);
+ try {
+ if (results == null || !results.hasMore()) {
+ return (null);
+ }
+ } catch (PartialResultException ex) {
+ if (!adCompat)
+ throw ex;
+ else
+ return (null);
}
// Get result for the first entry found
SearchResult result = (SearchResult)results.next();
// Check no further entries were found
- if (results.hasMore()) {
- if(containerLog.isInfoEnabled())
- containerLog.info("username " + username + " has multiple entries");
- return (null);
+ try {
+ if (results.hasMore()) {
+ if(containerLog.isInfoEnabled())
+ containerLog.info("username " + username + " has multiple entries");
+ return (null);
+ }
+ } catch (PartialResultException ex) {
+ if (!adCompat)
+ throw ex;
}
- // Get the entry's distinguished name
- NameParser parser = context.getNameParser("");
- Name contextName = parser.parse(context.getNameInNamespace());
- Name baseName = parser.parse(userBase);
+ String dn = getDistinguishedName(context, userBase, result);
- // Bugzilla 32269
- Name entryName = parser.parse(new CompositeName(result.getName()).get(0));
-
- Name name = contextName.addAll(baseName);
- name = name.addAll(entryName);
- String dn = name.toString();
-
if (containerLog.isTraceEnabled())
containerLog.trace(" entry found for " + username + " with dn " + dn);
@@ -1333,6 +1548,69 @@
/**
+ * Add roles to a user and search for other roles containing them themselves.
+ * We search recursively with a limited depth.
+ * By default the depth is 0, and we only use direct roles.
+ * The search needs to use the distinguished role names,
+ * but to return the role names.
+ *
+ * @param depth Recursion depth, starting at zero
+ * @param context The directory context we are searching
+ * @param recursiveMap The cumulative result map of role names and DNs.
+ * @param recursiveSet The cumulative result set of role names.
+ * @param groupName The role name to add to the list.
+ * @param groupDName The distinguished name of the role.
+ *
+ * @exception NamingException if a directory server error occurs
+ */
+ private void getRolesRecursive(int depth, DirContext context, Map<String, String> recursiveMap, Set<String> recursiveSet,
+ String groupName, String groupDName) throws NamingException {
+ if (containerLog.isTraceEnabled())
+ containerLog.trace("Recursive search depth " + depth + " for group '" + groupDName + " (" + groupName + ")'");
+ // Adding the given group to the result set if not already found
+ if (!recursiveSet.contains(groupDName)) {
+ recursiveSet.add(groupDName);
+ recursiveMap.put(groupDName, groupName);
+ if (depth >= roleRecursionLimit) {
+ if (roleRecursionLimit > 0)
+ containerLog.warn("Terminating recursive role search because of recursion limit " +
+ roleRecursionLimit + ", results might be incomplete");
+ return;
+ }
+ // Prepare the parameters for searching groups
+ String filter = roleFormat.format(new String[] { groupDName });
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope(roleSubtree ? SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE);
+ controls.setReturningAttributes(new String[] { roleName });
+ if (containerLog.isTraceEnabled()) {
+ containerLog.trace("Recursive search in role base '" + roleBase + "' for attribute '" + roleName + "'" +
+ " with filter expression '" + filter + "'");
+ }
+ // Searching groups that assign the given group
+ NamingEnumeration results = context.search(roleBase, filter, controls);
+ if (results != null) {
+ // Iterate over the resulting groups
+ try {
+ while (results.hasMore()) {
+ SearchResult result = (SearchResult) results.next();
+ Attributes attrs = result.getAttributes();
+ if (attrs == null)
+ continue;
+ String dname = getDistinguishedName(context, roleBase, result);
+ String name = getAttributeValue(roleName, attrs);
+ if (name != null && dname != null) {
+ getRolesRecursive(depth+1, context, recursiveMap, recursiveSet, name, dname);
+ }
+ }
+ } catch (PartialResultException ex) {
+ if (!adCompat)
+ throw ex;
+ }
+ }
+ }
+ }
+
+ /**
* Return a List of roles associated with the given User. Any
* roles present in the user's directory entry are supplemented by
* a directory search. If no roles are associated with this user,
@@ -1363,7 +1641,19 @@
if (list == null) {
list = new ArrayList<String>();
}
+ if (commonRole != null)
+ list.add(commonRole);
+ if (containerLog.isTraceEnabled()) {
+ if (list != null) {
+ containerLog.trace(" Found " + list.size() + " user internal roles");
+ for (int i=0; i<list.size(); i++)
+ containerLog.trace( " Found user internal role " + list.get(i));
+ } else {
+ containerLog.trace(" Found no user internal roles");
+ }
+ }
+
// Are we configured to do role searches?
if ((roleFormat == null) || (roleName == null))
return (list);
@@ -1382,26 +1672,52 @@
context.search(roleBase, filter, controls);
if (results == null)
return (list); // Should never happen, but just in case ...
- while (results.hasMore()) {
- SearchResult result = (SearchResult) results.next();
- Attributes attrs = result.getAttributes();
- if (attrs == null)
- continue;
- list = addAttributeValues(roleName, attrs, list);
+
+ HashMap<String, String> groupMap = new HashMap<String, String>();
+ try {
+ while (results.hasMore()) {
+ SearchResult result = (SearchResult) results.next();
+ Attributes attrs = result.getAttributes();
+ if (attrs == null)
+ continue;
+ String dname = getDistinguishedName(context, roleBase, result);
+ String name = getAttributeValue(roleName, attrs);
+ if (name != null && dname != null) {
+ groupMap.put(dname, name);
+ }
+ }
+ } catch (PartialResultException ex) {
+ if (!adCompat)
+ throw ex;
}
-
+ Set<String> keys = groupMap.keySet();
if (containerLog.isTraceEnabled()) {
- if (list != null) {
- containerLog.trace(" Returning " + list.size() + " roles");
- for (int i=0; i<list.size(); i++)
- containerLog.trace( " Found role " + list.get(i));
- } else {
- containerLog.trace(" getRoles about to return null ");
+ containerLog.trace(" Found " + keys.size() + " direct roles");
+ for (Iterator<String> i = keys.iterator(); i.hasNext();) {
+ Object k = i.next();
+ containerLog.trace( " Found direct role " + k + " -> " + groupMap.get(k));
}
}
- return (list);
+ HashSet<String> recursiveSet = new HashSet<String>();
+ HashMap<String, String> recursiveMap = new HashMap<String, String>();
+
+ for (Iterator<String> i = keys.iterator(); i.hasNext();) {
+ String k = i.next();
+ getRolesRecursive(0, context, recursiveMap, recursiveSet, groupMap.get(k), k);
+ }
+
+ HashSet<String> resultSet = new HashSet<String>(list);
+ resultSet.addAll(recursiveMap.values());
+
+ if (containerLog.isTraceEnabled()) {
+ containerLog.trace(" Returning " + resultSet.size() + " roles");
+ for (Iterator<String> i = resultSet.iterator(); i.hasNext();)
+ containerLog.trace( " Found role " + i.next());
+ }
+
+ return new ArrayList<String>(resultSet);
}
@@ -1463,9 +1779,14 @@
if (attr == null)
return (values);
NamingEnumeration e = attr.getAll();
- while(e.hasMore()) {
- String value = (String)e.next();
- values.add(value);
+ try {
+ while(e.hasMore()) {
+ String value = (String)e.next();
+ values.add(value);
+ }
+ } catch (PartialResultException ex) {
+ if (!adCompat)
+ throw ex;
}
return values;
}
@@ -1597,9 +1918,9 @@
protected synchronized Principal getPrincipal(DirContext context,
String username)
throws NamingException {
-
+
User user = getUser(context, username);
-
+
return new GenericPrincipal(this, user.username, user.password ,
getRoles(context, user));
}
@@ -1821,6 +2142,30 @@
}
+ /**
+ * Returns the distinguished name of a search result.
+ *
+ * @param context Our DirContext
+ * @param base The base DN
+ * @param result The search result
+ * @return String containing the distinguished name
+ */
+ protected String getDistinguishedName(DirContext context, String base, SearchResult result)
+ throws NamingException {
+ // Get the entry's distinguished name
+ NameParser parser = context.getNameParser("");
+ Name contextName = parser.parse(context.getNameInNamespace());
+ Name baseName = parser.parse(base);
+
+ // Bugzilla 32269
+ Name entryName = parser.parse(new CompositeName(result.getName()).get(0));
+
+ Name name = contextName.addAll(baseName);
+ name = name.addAll(entryName);
+ return name.toString();
+ }
+
+
}
// ------------------------------------------------------ Private Classes
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-12 14:57:19 UTC (rev 852)
+++ trunk/webapps/docs/changelog.xml 2008-11-12 14:59:30 UTC (rev 853)
@@ -26,6 +26,9 @@
<fix>
<bug>42707</bug>: Adding host aliases should be dynamic. (markt)
</fix>
+ <fix>
+ JNDI realm feature additions. (rjung)
+ </fix>
</changelog>
</subsection>
</section>
16 years, 1 month
JBossWeb SVN: r852 - in trunk: java/org/apache/tomcat/util/http/mapper and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-12 09:57:19 -0500 (Wed, 12 Nov 2008)
New Revision: 852
Modified:
trunk/java/org/apache/catalina/connector/MapperListener.java
trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java
trunk/webapps/docs/changelog.xml
Log:
- Host aliases should be dynamic.
Modified: trunk/java/org/apache/catalina/connector/MapperListener.java
===================================================================
--- trunk/java/org/apache/catalina/connector/MapperListener.java 2008-11-12 14:46:39 UTC (rev 851)
+++ trunk/java/org/apache/catalina/connector/MapperListener.java 2008-11-12 14:57:19 UTC (rev 852)
@@ -26,6 +26,10 @@
import javax.management.ObjectInstance;
import javax.management.ObjectName;
+import org.apache.catalina.ContainerEvent;
+import org.apache.catalina.ContainerListener;
+import org.apache.catalina.Host;
+import org.apache.catalina.ServerFactory;
import org.apache.catalina.core.StandardContext;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.mapper.Mapper;
@@ -42,7 +46,7 @@
* @author Costin Manolache
*/
public class MapperListener
- implements NotificationListener
+ implements NotificationListener, ContainerListener
{
private static Logger log = Logger.getLogger(MapperListener.class);
@@ -251,6 +255,18 @@
}
+ // --------------------------------------------- Container Listener methods
+
+ public void containerEvent(ContainerEvent event) {
+
+ if (event.getType() == Host.ADD_ALIAS_EVENT) {
+ mapper.addHostAlias(((Host) event.getSource()).getName(),
+ event.getData().toString());
+ } else if (event.getType() == Host.REMOVE_ALIAS_EVENT) {
+ mapper.removeHostAlias(event.getData().toString());
+ }
+ }
+
// ------------------------------------------------------ Protected Methods
private void registerEngine()
@@ -293,7 +309,7 @@
if (!isRegisteredWithAlias)
log.warn(sm.getString("mapperListener.unknownDefaultHost", defaultHost));
}
- // This should probablt be called later
+ // This should probably be called later
if( defaultHost != null ) {
mapper.setDefaultHostName(defaultHost);
}
@@ -306,9 +322,11 @@
throws Exception {
String name=objectName.getKeyProperty("host");
if( name != null ) {
- String[] aliases = (String[])
- mBeanServer.invoke(objectName, "findAliases", null, null);
+ Host host = (Host) ServerFactory.getServer().findService(
+ domain).getContainer().findChild(name);
+ String[] aliases = host.findAliases();
mapper.addHost(name, aliases, objectName);
+ host.addContainerListener(this);
if(log.isDebugEnabled())
log.debug(sm.getString
("mapperListener.registerHost", name, domain));
Modified: trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java 2008-11-12 14:46:39 UTC (rev 851)
+++ trunk/java/org/apache/tomcat/util/http/mapper/Mapper.java 2008-11-12 14:57:19 UTC (rev 852)
@@ -146,6 +146,47 @@
/**
+ * Add an alias to an existing host.
+ * @param name The name of the host
+ * @param alias The alias to add
+ */
+ public synchronized void addHostAlias(String name, String alias) {
+ int pos = find(hosts, name);
+ if (pos < 0) {
+ // Should not be adding an alias for a host that doesn't exist but
+ // just in case...
+ return;
+ }
+ Host realHost = hosts[pos];
+
+ Host[] newHosts = new Host[hosts.length + 1];
+ Host newHost = new Host();
+ newHost.name = alias;
+ newHost.contextList = realHost.contextList;
+ newHost.object = realHost;
+ if (insertMap(hosts, newHosts, newHost)) {
+ hosts = newHosts;
+ }
+ }
+
+ /**
+ * Remove a host alias
+ * @param alias The alias to remove
+ */
+ public synchronized void removeHostAlias(String alias) {
+ // Find and remove the alias
+ int pos = find(hosts, alias);
+ if (pos < 0) {
+ return;
+ }
+ Host[] newHosts = new Host[hosts.length - 1];
+ if (removeMap(hosts, newHosts, alias)) {
+ hosts = newHosts;
+ }
+
+ }
+
+ /**
* Set context, used for wrapper mapping (request dispatcher).
*
* @param welcomeResources Welcome files defined for this context
@@ -923,7 +964,7 @@
/**
- * Find a map elemnt given its name in a sorted array of map elements.
+ * Find a map element given its name in a sorted array of map elements.
* This will return the index for the closest inferior or equal item in the
* given array.
*/
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-12 14:46:39 UTC (rev 851)
+++ trunk/webapps/docs/changelog.xml 2008-11-12 14:57:19 UTC (rev 852)
@@ -23,6 +23,9 @@
<bug>46011</bug>: Make Principal accessible (if set) via Subject.getSubject(AccessController.getContext()) when processing filters.
Based on a patch provided by tsveg1. (markt)
</fix>
+ <fix>
+ <bug>42707</bug>: Adding host aliases should be dynamic. (markt)
+ </fix>
</changelog>
</subsection>
</section>
16 years, 1 month
JBossWeb SVN: r851 - in trunk: java/org/apache/catalina/security and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-12 09:46:39 -0500 (Wed, 12 Nov 2008)
New Revision: 851
Modified:
trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
trunk/java/org/apache/catalina/security/SecurityUtil.java
trunk/webapps/docs/changelog.xml
Log:
- 46011: Make principal accessible to filters.
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterChain.java 2008-11-05 22:28:30 UTC (rev 850)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterChain.java 2008-11-12 14:46:39 UTC (rev 851)
@@ -228,7 +228,7 @@
Object[] args = new Object[]{req, res, this};
SecurityUtil.doAsPrivilege
- ("doFilter", filter, classType, args);
+ ("doFilter", filter, classType, args, principal);
args = null;
} else {
@@ -409,7 +409,7 @@
Object[] args = new Object[]{ev, this};
SecurityUtil.doAsPrivilege
- ("doFilterEvent", (Filter) filter, cometClassType, args);
+ ("doFilterEvent", (Filter) filter, cometClassType, args, principal);
args = null;
} else {
Modified: trunk/java/org/apache/catalina/security/SecurityUtil.java
===================================================================
--- trunk/java/org/apache/catalina/security/SecurityUtil.java 2008-11-05 22:28:30 UTC (rev 850)
+++ trunk/java/org/apache/catalina/security/SecurityUtil.java 2008-11-12 14:46:39 UTC (rev 851)
@@ -196,6 +196,31 @@
final Class[] targetType,
final Object[] targetArguments)
throws java.lang.Exception{
+
+ doAsPrivilege(
+ methodName, targetObject, targetType, targetArguments, null);
+ }
+
+ /**
+ * Perform work as a particular <code>Subject</code>. Here the work
+ * will be granted to a <code>null</code> subject.
+ *
+ * @param methodName the method to apply the security restriction
+ * @param targetObject the <code>Filter</code> on which the method will
+ * be called.
+ * @param targetType <code>Class</code> array used to instanciate a
+ * <code>Method</code> object.
+ * @param targetArguments <code>Object</code> array contains the
+ * runtime parameters instance.
+ * @param principal the <code>Principal</code> to which the security
+ * privilege apply
+ */
+ public static void doAsPrivilege(final String methodName,
+ final Filter targetObject,
+ final Class[] targetType,
+ final Object[] targetArguments,
+ Principal principal)
+ throws java.lang.Exception{
Method method = null;
Method[] methodsCache = null;
@@ -215,7 +240,7 @@
targetType);
}
- execute(method, targetObject, targetArguments, null);
+ execute(method, targetObject, targetArguments, principal);
}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2008-11-05 22:28:30 UTC (rev 850)
+++ trunk/webapps/docs/changelog.xml 2008-11-12 14:46:39 UTC (rev 851)
@@ -16,6 +16,17 @@
<body>
+<section name="JBoss Web 2.1.2.CR1 (remm)">
+ <subsection name="Catalina">
+ <changelog>
+ <fix>
+ <bug>46011</bug>: Make Principal accessible (if set) via Subject.getSubject(AccessController.getContext()) when processing filters.
+ Based on a patch provided by tsveg1. (markt)
+ </fix>
+ </changelog>
+ </subsection>
+</section>
+
<section name="JBoss Web 2.1.1.GA (remm)">
<subsection name="General">
<changelog>
16 years, 1 month
JBossWeb SVN: r850 - trunk.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2008-11-05 17:28:30 -0500 (Wed, 05 Nov 2008)
New Revision: 850
Modified:
trunk/PATCHES.txt
Log:
- Update patches list.
Modified: trunk/PATCHES.txt
===================================================================
--- trunk/PATCHES.txt 2008-11-04 15:05:55 UTC (rev 849)
+++ trunk/PATCHES.txt 2008-11-05 22:28:30 UTC (rev 850)
@@ -1,16 +1,20 @@
-Patched dropped
+Dropped Tomcat patches
+SVN URL: http://svn.apache.org/viewvc?rev=XXXXXX&view=rev
-http://svn.apache.org/viewvc?rev=701358&view=rev
+701358:
Some symlink fix (too many checks needed)
-http://svn.apache.org/viewvc?rev=701355&view=rev
+701355:
XML parser in webapp fix (significant refactoring, partial)
-http://svn.apache.org/viewvc?rev=709821&view=rev
+709821:
Endline configuration for PrintWriter based on a server system property
-http://svn.apache.org/viewvc?rev=709018&view=rev
+709018:
Async logger is not ready
-http://svn.apache.org/viewvc?rev=710179&view=rev
+710179:
Invoker servlet removal
+
+711711, 711714, 711716, 711720:
+Useless session access time refactoring
16 years, 1 month