Merge branch 'master' into javawebsocket-jsr

This commit is contained in:
Joakim Erdfelt 2013-06-03 09:06:38 -07:00
commit 020dd1022c
27 changed files with 505 additions and 337 deletions

View File

@ -540,9 +540,8 @@ public class AntWebAppContext extends WebAppContext
if (getDescriptor() != null) if (getDescriptor() != null)
{ {
try try (Resource r = Resource.newResource(getDescriptor());)
{ {
Resource r = Resource.newResource(getDescriptor());
scanList.add(r.getFile()); scanList.add(r.getFile());
} }
catch (IOException e) catch (IOException e)
@ -553,9 +552,8 @@ public class AntWebAppContext extends WebAppContext
if (getJettyEnvXml() != null) if (getJettyEnvXml() != null)
{ {
try try (Resource r = Resource.newResource(getJettyEnvXml());)
{ {
Resource r = Resource.newResource(getJettyEnvXml());
scanList.add(r.getFile()); scanList.add(r.getFile());
} }
catch (IOException e) catch (IOException e)
@ -566,11 +564,10 @@ public class AntWebAppContext extends WebAppContext
if (getDefaultsDescriptor() != null) if (getDefaultsDescriptor() != null)
{ {
try try (Resource r = Resource.newResource(getDefaultsDescriptor());)
{ {
if (!AntWebAppContext.WEB_DEFAULTS_XML.equals(getDefaultsDescriptor())) if (!WebAppContext.WEB_DEFAULTS_XML.equals(getDefaultsDescriptor()))
{ {
Resource r = Resource.newResource(getDefaultsDescriptor());
scanList.add(r.getFile()); scanList.add(r.getFile());
} }
} }

View File

@ -171,7 +171,7 @@ public interface HttpContent
@Override @Override
public void release() public void release()
{ {
_resource.release(); _resource.close();
} }
} }
} }

View File

@ -449,12 +449,28 @@ public abstract class AbstractJettyMojo extends AbstractMojo
{ {
if (getJettyXmlFiles() == null) if (getJettyXmlFiles() == null)
return; return;
XmlConfiguration last = null;
for ( File xmlFile : getJettyXmlFiles() ) for ( File xmlFile : getJettyXmlFiles() )
{ {
getLog().info( "Configuring Jetty from xml configuration file = " + xmlFile.getCanonicalPath() ); getLog().info( "Configuring Jetty from xml configuration file = " + xmlFile.getCanonicalPath() );
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(xmlFile)); XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(xmlFile));
xmlConfiguration.configure(this.server);
//chain ids from one config file to another
if (last == null)
xmlConfiguration.getIdMap().put("Server", this.server);
else
xmlConfiguration.getIdMap().putAll(last.getIdMap());
//Set the system properties each time in case the config file set a new one
Enumeration<?> ensysprop = System.getProperties().propertyNames();
while (ensysprop.hasMoreElements())
{
String name = (String)ensysprop.nextElement();
xmlConfiguration.getProperties().put(name,System.getProperty(name));
}
last = xmlConfiguration;
xmlConfiguration.configure();
} }
} }

View File

@ -405,9 +405,8 @@ public class JettyRunMojo extends AbstractJettyMojo
scanList = new ArrayList<File>(); scanList = new ArrayList<File>();
if (webApp.getDescriptor() != null) if (webApp.getDescriptor() != null)
{ {
try try (Resource r = Resource.newResource(webApp.getDescriptor());)
{ {
Resource r = Resource.newResource(webApp.getDescriptor());
scanList.add(r.getFile()); scanList.add(r.getFile());
} }
catch (IOException e) catch (IOException e)
@ -418,9 +417,8 @@ public class JettyRunMojo extends AbstractJettyMojo
if (webApp.getJettyEnvXml() != null) if (webApp.getJettyEnvXml() != null)
{ {
try try (Resource r = Resource.newResource(webApp.getJettyEnvXml());)
{ {
Resource r = Resource.newResource(webApp.getJettyEnvXml());
scanList.add(r.getFile()); scanList.add(r.getFile());
} }
catch (IOException e) catch (IOException e)
@ -431,13 +429,10 @@ public class JettyRunMojo extends AbstractJettyMojo
if (webApp.getDefaultsDescriptor() != null) if (webApp.getDefaultsDescriptor() != null)
{ {
try try (Resource r = Resource.newResource(webApp.getDefaultsDescriptor());)
{ {
if (!WebAppContext.WEB_DEFAULTS_XML.equals(webApp.getDefaultsDescriptor())) if (!WebAppContext.WEB_DEFAULTS_XML.equals(webApp.getDefaultsDescriptor()))
{
Resource r = Resource.newResource(webApp.getDefaultsDescriptor());
scanList.add(r.getFile()); scanList.add(r.getFile());
}
} }
catch (IOException e) catch (IOException e)
{ {
@ -447,9 +442,8 @@ public class JettyRunMojo extends AbstractJettyMojo
if (webApp.getOverrideDescriptor() != null) if (webApp.getOverrideDescriptor() != null)
{ {
try try (Resource r = Resource.newResource(webApp.getOverrideDescriptor());)
{ {
Resource r = Resource.newResource(webApp.getOverrideDescriptor());
scanList.add(r.getFile()); scanList.add(r.getFile());
} }
catch (IOException e) catch (IOException e)

View File

@ -169,7 +169,7 @@ public abstract class AbstractContextProvider extends AbstractLifeCycle implemen
jettyHome = jettyHome.substring(0,jettyHome.length()-1); jettyHome = jettyHome.substring(0,jettyHome.length()-1);
res = getFileAsResource(jettyHome, _contextFile); res = getFileAsResource(jettyHome, _contextFile);
if (LOG.isDebugEnabled()) LOG.debug("jetty home context file:"+res); LOG.debug("jetty home context file: {}",res);
} }
} }
} }
@ -179,8 +179,11 @@ public abstract class AbstractContextProvider extends AbstractLifeCycle implemen
{ {
if (bundleOverrideLocation != null) if (bundleOverrideLocation != null)
{ {
res = getFileAsResource(Resource.newResource(bundleOverrideLocation).getFile(), _contextFile); try(Resource location=Resource.newResource(bundleOverrideLocation))
if (LOG.isDebugEnabled()) LOG.debug("Bundle override location context file:"+res); {
res=location.addPath(_contextFile);
}
LOG.debug("Bundle override location context file: {}",res);
} }
} }
@ -295,22 +298,6 @@ public abstract class AbstractContextProvider extends AbstractLifeCycle implemen
} }
return r; return r;
} }
private Resource getFileAsResource (File dir, String file)
{
Resource r = null;
try
{
File asFile = new File (dir, file);
if (asFile.exists())
r = Resource.newResource(asFile);
}
catch (Exception e)
{
r = null;
}
return r;
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -118,17 +118,18 @@ public class Runner
if (".".equals(path) || "..".equals(path)) if (".".equals(path) || "..".equals(path))
continue; continue;
Resource item = lib.addPath(path); try(Resource item = lib.addPath(path);)
if (item.isDirectory())
addJars(item);
else
{ {
if (path.toLowerCase().endsWith(".jar") || if (item.isDirectory())
path.toLowerCase().endsWith(".zip")) addJars(item);
else
{ {
URL url = item.getURL(); if (path.toLowerCase().endsWith(".jar") ||
_classpath.add(url); path.toLowerCase().endsWith(".zip"))
{
URL url = item.getURL();
_classpath.add(url);
}
} }
} }
} }
@ -214,24 +215,30 @@ public class Runner
{ {
if ("--lib".equals(args[i])) if ("--lib".equals(args[i]))
{ {
Resource lib = Resource.newResource(args[++i]); try(Resource lib = Resource.newResource(args[++i]);)
if (!lib.exists() || !lib.isDirectory()) {
usage("No such lib directory "+lib); if (!lib.exists() || !lib.isDirectory())
_classpath.addJars(lib); usage("No such lib directory "+lib);
_classpath.addJars(lib);
}
} }
else if ("--jar".equals(args[i])) else if ("--jar".equals(args[i]))
{ {
Resource jar = Resource.newResource(args[++i]); try(Resource jar = Resource.newResource(args[++i]);)
if (!jar.exists() || jar.isDirectory()) {
usage("No such jar "+jar); if (!jar.exists() || jar.isDirectory())
_classpath.addPath(jar); usage("No such jar "+jar);
_classpath.addPath(jar);
}
} }
else if ("--classes".equals(args[i])) else if ("--classes".equals(args[i]))
{ {
Resource classes = Resource.newResource(args[++i]); try(Resource classes = Resource.newResource(args[++i]);)
if (!classes.exists() || !classes.isDirectory()) {
usage("No such classes directory "+classes); if (!classes.exists() || !classes.isDirectory())
_classpath.addPath(classes); usage("No such classes directory "+classes);
_classpath.addPath(classes);
}
} }
else if (args[i].startsWith("--")) else if (args[i].startsWith("--"))
i++; i++;
@ -315,8 +322,11 @@ public class Runner
{ {
for (String cfg:_configFiles) for (String cfg:_configFiles)
{ {
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(cfg).getURL()); try (Resource resource=Resource.newResource(cfg))
xmlConfiguration.configure(_server); {
XmlConfiguration xmlConfiguration = new XmlConfiguration(resource.getURL());
xmlConfiguration.configure(_server);
}
} }
} }
@ -416,34 +426,35 @@ public class Runner
} }
// Create a context // Create a context
Resource ctx = Resource.newResource(args[i]); try(Resource ctx = Resource.newResource(args[i]);)
if (!ctx.exists()) {
usage("Context '"+ctx+"' does not exist"); if (!ctx.exists())
usage("Context '"+ctx+"' does not exist");
if (contextPathSet && !(contextPath.startsWith("/")))
contextPath = "/"+contextPath;
// Configure the context if (contextPathSet && !(contextPath.startsWith("/")))
if (!ctx.isDirectory() && ctx.toString().toLowerCase().endsWith(".xml")) contextPath = "/"+contextPath;
{
// It is a context config file // Configure the context
XmlConfiguration xmlConfiguration=new XmlConfiguration(ctx.getURL()); if (!ctx.isDirectory() && ctx.toString().toLowerCase().endsWith(".xml"))
xmlConfiguration.getIdMap().put("Server",_server); {
ContextHandler handler=(ContextHandler)xmlConfiguration.configure(); // It is a context config file
if (contextPathSet) XmlConfiguration xmlConfiguration=new XmlConfiguration(ctx.getURL());
handler.setContextPath(contextPath); xmlConfiguration.getIdMap().put("Server",_server);
_contexts.addHandler(handler); ContextHandler handler=(ContextHandler)xmlConfiguration.configure();
handler.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", __containerIncludeJarPattern); if (contextPathSet)
handler.setContextPath(contextPath);
_contexts.addHandler(handler);
handler.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", __containerIncludeJarPattern);
}
else
{
// assume it is a WAR file
WebAppContext webapp = new WebAppContext(_contexts,ctx.toString(),contextPath);
webapp.setConfigurationClasses(__plusConfigurationClasses);
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
__containerIncludeJarPattern);
}
} }
else
{
// assume it is a WAR file
WebAppContext webapp = new WebAppContext(_contexts,ctx.toString(),contextPath);
webapp.setConfigurationClasses(__plusConfigurationClasses);
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
__containerIncludeJarPattern);
}
//reset //reset
contextPathSet = false; contextPathSet = false;
contextPath = __defaultContextPath; contextPath = __defaultContextPath;

View File

@ -444,7 +444,7 @@ public class ResourceCache
// Invalidate it // Invalidate it
_cachedSize.addAndGet(-_length); _cachedSize.addAndGet(-_length);
_cachedFiles.decrementAndGet(); _cachedFiles.decrementAndGet();
_resource.release(); _resource.close();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -567,7 +567,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (content!=null) if (content!=null)
content.release(); content.release();
else if (resource!=null) else if (resource!=null)
resource.release(); resource.close();
} }
} }
@ -658,7 +658,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (ifm!=null) if (ifm!=null)
{ {
boolean match=false; boolean match=false;
if (content!=null && content.getETag()!=null) if (content.getETag()!=null)
{ {
QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifm,", ",false,true); QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifm,", ",false,true);
while (!match && quoted.hasMoreTokens()) while (!match && quoted.hasMoreTokens())
@ -671,48 +671,39 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (!match) if (!match)
{ {
Response r = Response.getResponse(response); response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
r.reset(true);
r.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
return false; return false;
} }
} }
String ifnm=request.getHeader(HttpHeader.IF_NONE_MATCH.asString()); String if_non_match_etag=request.getHeader(HttpHeader.IF_NONE_MATCH.asString());
if (ifnm!=null && content!=null && content.getETag()!=null) if (if_non_match_etag!=null && content.getETag()!=null)
{ {
// Look for GzipFiltered version of etag // Look for GzipFiltered version of etag
if (content.getETag().toString().equals(request.getAttribute("o.e.j.s.GzipFilter.ETag"))) if (content.getETag().toString().equals(request.getAttribute("o.e.j.s.GzipFilter.ETag")))
{ {
Response r = Response.getResponse(response); response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
r.reset(true); response.setHeader(HttpHeader.ETAG.asString(),if_non_match_etag);
r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
r.getHttpFields().put(HttpHeader.ETAG,ifnm);
return false; return false;
} }
// Handle special case of exact match. // Handle special case of exact match.
if (content.getETag().toString().equals(ifnm)) if (content.getETag().toString().equals(if_non_match_etag))
{ {
Response r = Response.getResponse(response); response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
r.reset(true); response.setHeader(HttpHeader.ETAG.asString(),content.getETag());
r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
r.getHttpFields().put(HttpHeader.ETAG,content.getETag());
return false; return false;
} }
// Handle list of tags // Handle list of tags
QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifnm,", ",false,true); QuotedStringTokenizer quoted = new QuotedStringTokenizer(if_non_match_etag,", ",false,true);
while (quoted.hasMoreTokens()) while (quoted.hasMoreTokens())
{ {
String tag = quoted.nextToken(); String tag = quoted.nextToken();
if (content.getETag().toString().equals(tag)) if (content.getETag().toString().equals(tag))
{ {
Response r = Response.getResponse(response); response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
r.reset(true); response.setHeader(HttpHeader.ETAG.asString(),content.getETag());
r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
r.getHttpFields().put(HttpHeader.ETAG,content.getETag());
return false; return false;
} }
} }
@ -727,50 +718,33 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (ifms!=null) if (ifms!=null)
{ {
//Get jetty's Response impl //Get jetty's Response impl
Response r = Response.getResponse(response); String mdlm=content.getLastModified();
if (mdlm!=null && ifms.equals(mdlm))
if (content!=null)
{ {
String mdlm=content.getLastModified(); response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
if (mdlm!=null) if (_etags)
{ response.setHeader(HttpHeader.ETAG.asString(),content.getETag());
if (ifms.equals(mdlm)) response.flushBuffer();
{ return false;
r.reset(true);
r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
if (_etags)
r.getHttpFields().add(HttpHeader.ETAG,content.getETag());
r.flushBuffer();
return false;
}
}
} }
long ifmsl=request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString()); long ifmsl=request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString());
if (ifmsl!=-1) if (ifmsl!=-1 && resource.lastModified()/1000 <= ifmsl/1000)
{ {
if (resource.lastModified()/1000 <= ifmsl/1000) response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
{ if (_etags)
r.reset(true); response.setHeader(HttpHeader.ETAG.asString(),content.getETag());
r.setStatus(HttpServletResponse.SC_NOT_MODIFIED); response.flushBuffer();
if (_etags) return false;
r.getHttpFields().add(HttpHeader.ETAG,content.getETag());
r.flushBuffer();
return false;
}
} }
} }
// Parse the if[un]modified dates and compare to resource // Parse the if[un]modified dates and compare to resource
long date=request.getDateHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString()); long date=request.getDateHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString());
if (date!=-1 && resource.lastModified()/1000 > date/1000)
if (date!=-1)
{ {
if (resource.lastModified()/1000 > date/1000) response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
{ return false;
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return false;
}
} }
} }

View File

@ -26,7 +26,6 @@ import java.io.RandomAccessFile;
import java.nio.Buffer; import java.nio.Buffer;
import java.nio.BufferOverflowException; import java.nio.BufferOverflowException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode; import java.nio.channels.FileChannel.MapMode;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -372,12 +371,14 @@ public class BufferUtil
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static void readFrom(File file, ByteBuffer buffer) throws IOException public static void readFrom(File file, ByteBuffer buffer) throws IOException
{ {
RandomAccessFile raf = new RandomAccessFile(file,"r"); try(RandomAccessFile raf = new RandomAccessFile(file,"r");)
FileChannel channel = raf.getChannel(); {
long needed=raf.length(); FileChannel channel = raf.getChannel();
long needed=raf.length();
while (needed>0 && buffer.hasRemaining()) while (needed>0 && buffer.hasRemaining())
needed=needed-channel.read(buffer); needed=needed-channel.read(buffer);
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -36,6 +36,16 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/**
* The @ManagedAttribute annotation is used to indicate that a given method
* exposes a JMX attribute. This annotation is placed always on the reader
* method of a given attribute. Unless it is marked as read-only in the
* configuration of the annotation a corresponding setter is looked for
* following normal naming conventions. For example if this annotation is
* on a method called getFoo() then a method called setFoo() would be looked
* for and if found wired automatically into the jmx attribute.
*
*/
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Target( { ElementType.METHOD } ) @Target( { ElementType.METHOD } )

View File

@ -24,6 +24,14 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/**
* The @ManagedObject annotation is used on a class at the top level to
* indicate that it should be exposed as an mbean. It has only one attribute
* to it which is used as the description of the MBean. Should multiple
* @ManagedObject annotations be found in the chain of influence then the
* first description is used.
*
*/
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Target( { ElementType.TYPE } ) @Target( { ElementType.TYPE } )

View File

@ -36,6 +36,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/**
* The @ManagedOperation annotation is used to indicate that a given method
* should be considered a JMX operation.
*
*/
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Target( { ElementType.METHOD } ) @Target( { ElementType.METHOD } )

View File

@ -24,11 +24,28 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/**
* This annotation is used to describe variables in method
* signatures so that when rendered into tools like JConsole
* it is clear what the parameters are. For example:
*
* public void doodle(@Name(value="doodle", description="A description of the argument") String doodle)
*
*/
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Target( { ElementType.PARAMETER } ) @Target( { ElementType.PARAMETER } )
public @interface Name public @interface Name
{ {
/**
* the name of the parameter
* @return
*/
String value(); String value();
/**
* the description of the parameter
* @return
*/
String description() default ""; String description() default "";
} }

View File

@ -50,7 +50,10 @@ public class FileDestroyable implements Destroyable
public void addFile(String file) throws IOException public void addFile(String file) throws IOException
{ {
_files.add(Resource.newResource(file).getFile()); try(Resource r = Resource.newResource(file);)
{
_files.add(r.getFile());
}
} }
public void addFile(File file) public void addFile(File file)
@ -65,7 +68,10 @@ public class FileDestroyable implements Destroyable
public void removeFile(String file) throws IOException public void removeFile(String file) throws IOException
{ {
_files.remove(Resource.newResource(file).getFile()); try(Resource r = Resource.newResource(file);)
{
_files.remove(r.getFile());
}
} }
public void removeFile(File file) public void removeFile(File file)
@ -73,6 +79,7 @@ public class FileDestroyable implements Destroyable
_files.remove(file); _files.remove(file);
} }
@Override
public void destroy() public void destroy()
{ {
for (File file : _files) for (File file : _files)

View File

@ -20,10 +20,8 @@ package org.eclipse.jetty.util.resource;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -50,25 +48,24 @@ import org.eclipse.jetty.util.log.Logger;
* *
* *
*/ */
public class FileResource extends URLResource public class FileResource extends Resource
{ {
private static final Logger LOG = Log.getLogger(FileResource.class); private static final Logger LOG = Log.getLogger(FileResource.class);
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private File _file; private final File _file;
private transient URL _alias=null; private final String _uri;
private transient boolean _aliasChecked=false; private final URL _alias;
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
public FileResource(URL url) public FileResource(URL url)
throws IOException, URISyntaxException throws IOException, URISyntaxException
{ {
super(url,null); File file;
try try
{ {
// Try standard API to convert URL to file. // Try standard API to convert URL to file.
_file =new File(new URI(url.toString())); file =new File(url.toURI());
} }
catch (URISyntaxException e) catch (URISyntaxException e)
{ {
@ -76,48 +73,86 @@ public class FileResource extends URLResource
} }
catch (Exception e) catch (Exception e)
{ {
if (!url.toString().startsWith("file:"))
throw new IllegalArgumentException("!file:");
LOG.ignore(e); LOG.ignore(e);
try try
{ {
// Assume that File.toURL produced unencoded chars. So try // Assume that File.toURL produced unencoded chars. So try encoding them.
// encoding them.
String file_url="file:"+URIUtil.encodePath(url.toString().substring(5)); String file_url="file:"+URIUtil.encodePath(url.toString().substring(5));
URI uri = new URI(file_url); URI uri = new URI(file_url);
if (uri.getAuthority()==null) if (uri.getAuthority()==null)
_file = new File(uri); file = new File(uri);
else else
_file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile())); file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile()));
} }
catch (Exception e2) catch (Exception e2)
{ {
LOG.ignore(e2); LOG.ignore(e2);
// Still can't get the file. Doh! try good old hack! // Still can't get the file. Doh! try good old hack!
checkConnection(); URLConnection connection=url.openConnection();
Permission perm = _connection.getPermission(); Permission perm = connection.getPermission();
_file = new File(perm==null?url.getFile():perm.getName()); file = new File(perm==null?url.getFile():perm.getName());
} }
} }
if (_file.isDirectory())
{ _file=file;
if (!_urlString.endsWith("/")) _uri=normalizeURI(_file,url.toURI());
_urlString=_urlString+"/"; _alias=checkAlias(_file);
}
else
{
if (_urlString.endsWith("/"))
_urlString=_urlString.substring(0,_urlString.length()-1);
}
} }
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
FileResource(URL url, URLConnection connection, File file) public FileResource(URI uri)
{ {
super(url,connection); File file=new File(uri);
_file=file; _file=file;
if (_file.isDirectory() && !_urlString.endsWith("/")) _uri=normalizeURI(_file,uri);
_urlString=_urlString+"/"; _alias=checkAlias(_file);
}
/* -------------------------------------------------------- */
FileResource(File file)
{
_file=file;
_uri=normalizeURI(_file,_file.toURI());
_alias=checkAlias(_file);
}
/* -------------------------------------------------------- */
private static String normalizeURI(File file, URI uri)
{
String u =uri.toASCIIString();
if (file.isDirectory())
{
if(!u.endsWith("/"))
u+="/";
}
else if (file.exists() && u.endsWith("/"))
u=u.substring(0,u.length()-1);
return u;
}
/* -------------------------------------------------------- */
private static URL checkAlias(File file)
{
try
{
String abs=file.getAbsolutePath();
String can=file.getCanonicalPath();
if (!abs.equals(can))
{
LOG.debug("ALIAS abs={} can={}",abs,can);
return new File(can).toURI().toURL();
}
}
catch(IOException e)
{
LOG.warn(e);
}
return null;
} }
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
@ -125,45 +160,35 @@ public class FileResource extends URLResource
public Resource addPath(String path) public Resource addPath(String path)
throws IOException,MalformedURLException throws IOException,MalformedURLException
{ {
URLResource r=null;
String url=null;
path = org.eclipse.jetty.util.URIUtil.canonicalPath(path); path = org.eclipse.jetty.util.URIUtil.canonicalPath(path);
if (path==null)
throw new MalformedURLException();
if ("/".equals(path)) if ("/".equals(path))
return this; return this;
else if (!isDirectory())
{
r=(FileResource)super.addPath(path);
url=r._urlString;
}
else
{
if (path==null)
throw new MalformedURLException();
// treat all paths being added as relative
String rel=path;
if (path.startsWith("/"))
rel = path.substring(1);
url=URIUtil.addPaths(_urlString,URIUtil.encodePath(rel));
r=(URLResource)Resource.newResource(url);
}
String encoded=URIUtil.encodePath(path); path=URIUtil.encodePath(path);
int expected=r.toString().length()-encoded.length();
int index = r._urlString.lastIndexOf(encoded, expected);
if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory())) URI uri;
try
{ {
if (!(r instanceof BadResource)) if (_file.isDirectory())
{ {
((FileResource)r)._alias=new URL(url); // treat all paths being added as relative
((FileResource)r)._aliasChecked=true; uri=new URI(URIUtil.addPaths(_uri,path));
} }
} else
return r; {
uri=new URI(_uri+path);
}
}
catch(final URISyntaxException e)
{
throw new MalformedURLException(){{initCause(e);}};
}
return new FileResource(uri);
} }
@ -171,30 +196,6 @@ public class FileResource extends URLResource
@Override @Override
public URL getAlias() public URL getAlias()
{ {
if (!_aliasChecked)
{
try
{
String abs=_file.getAbsolutePath();
String can=_file.getCanonicalPath();
if (abs.length()!=can.length() || !abs.equals(can))
_alias=Resource.toURL(new File(can));
_aliasChecked=true;
if (_alias!=null && LOG.isDebugEnabled())
{
LOG.debug("ALIAS abs="+abs);
LOG.debug("ALIAS can="+can);
}
}
catch(Exception e)
{
LOG.warn(Log.EXCEPTION,e);
return getURL();
}
}
return _alias; return _alias;
} }
@ -220,12 +221,12 @@ public class FileResource extends URLResource
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
/** /**
* Returns true if the respresenetd resource is a container/directory. * Returns true if the resource is a container/directory.
*/ */
@Override @Override
public boolean isDirectory() public boolean isDirectory()
{ {
return _file.isDirectory(); return _file.exists() && _file.isDirectory() || _uri.endsWith("/");
} }
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
@ -320,18 +321,6 @@ public class FileResource extends URLResource
} }
return list; return list;
} }
/* ------------------------------------------------------------ */
/** Encode according to this resource type.
* File URIs are encoded.
* @param uri URI to encode.
* @return The uri unchanged.
*/
@Override
public String encode(String uri)
{
return uri;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -377,4 +366,35 @@ public class FileResource extends URLResource
IO.copy(getFile(),destination); IO.copy(getFile(),destination);
} }
} }
@Override
public boolean isContainedIn(Resource r) throws MalformedURLException
{
return false;
}
@Override
public void close()
{
}
@Override
public URL getURL()
{
try
{
return _file.toURI().toURL();
}
catch (MalformedURLException e)
{
throw new IllegalStateException(e);
}
}
@Override
public String toString()
{
return _uri;
}
} }

View File

@ -60,7 +60,7 @@ class JarFileResource extends JarResource
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public synchronized void release() public synchronized void close()
{ {
_list=null; _list=null;
_entry=null; _entry=null;
@ -83,7 +83,7 @@ class JarFileResource extends JarResource
} }
} }
_jarFile=null; _jarFile=null;
super.release(); super.close();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -374,18 +374,6 @@ class JarFileResource extends JarResource
return -1; return -1;
} }
/* ------------------------------------------------------------ */
/** Encode according to this resource type.
* File URIs are not encoded.
* @param uri URI to encode.
* @return The uri unchanged.
*/
@Override
public String encode(String uri)
{
return uri;
}
/** /**

View File

@ -55,10 +55,10 @@ public class JarResource extends URLResource
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public synchronized void release() public synchronized void close()
{ {
_jarConnection=null; _jarConnection=null;
super.release(); super.close();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -18,6 +18,7 @@
package org.eclipse.jetty.util.resource; package org.eclipse.jetty.util.resource;
import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -26,7 +27,6 @@ import java.io.OutputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Arrays; import java.util.Arrays;
@ -45,7 +45,7 @@ import org.eclipse.jetty.util.log.Logger;
/** /**
* Abstract resource class. * Abstract resource class.
*/ */
public abstract class Resource implements ResourceFactory public abstract class Resource implements ResourceFactory, Closeable
{ {
private static final Logger LOG = Log.getLogger(Resource.class); private static final Logger LOG = Log.getLogger(Resource.class);
public static boolean __defaultUseCaches = true; public static boolean __defaultUseCaches = true;
@ -149,7 +149,7 @@ public abstract class Resource implements ResourceFactory
* @param useCaches controls URLConnection caching * @param useCaches controls URLConnection caching
* @return A Resource object. * @return A Resource object.
*/ */
public static Resource newResource (String resource, boolean useCaches) public static Resource newResource(String resource, boolean useCaches)
throws MalformedURLException, IOException throws MalformedURLException, IOException
{ {
URL url=null; URL url=null;
@ -171,11 +171,7 @@ public abstract class Resource implements ResourceFactory
resource=resource.substring(2); resource=resource.substring(2);
File file=new File(resource).getCanonicalFile(); File file=new File(resource).getCanonicalFile();
url=Resource.toURL(file); return new FileResource(file);
URLConnection connection=url.openConnection();
connection.setUseCaches(useCaches);
return new FileResource(url,connection,file);
} }
catch(Exception e2) catch(Exception e2)
{ {
@ -194,15 +190,9 @@ public abstract class Resource implements ResourceFactory
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static Resource newResource (File file) public static Resource newResource(File file)
throws MalformedURLException, IOException
{ {
file = file.getCanonicalFile(); return new FileResource(file);
URL url = Resource.toURL(file);
URLConnection connection = url.openConnection();
FileResource fileResource = new FileResource(url, connection, file);
return fileResource;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -300,7 +290,7 @@ public abstract class Resource implements ResourceFactory
@Override @Override
protected void finalize() protected void finalize()
{ {
release(); close();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -309,9 +299,18 @@ public abstract class Resource implements ResourceFactory
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Release any temporary resources held by the resource. /** Release any temporary resources held by the resource.
* @deprecated use {@link #close()}
*/ */
public abstract void release(); public final void release()
{
close();
}
/* ------------------------------------------------------------ */
/** Release any temporary resources held by the resource.
*/
@Override
public abstract void close();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -420,19 +419,19 @@ public abstract class Resource implements ResourceFactory
/** /**
* Returns the resource contained inside the current resource with the * Returns the resource contained inside the current resource with the
* given name. * given name.
* @param path The path segment to add, which should be encoded by the * @param path The path segment to add, which is not encoded
* encode method.
*/ */
public abstract Resource addPath(String path) public abstract Resource addPath(String path)
throws IOException,MalformedURLException; throws IOException,MalformedURLException;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get a resource from withing this resource. /** Get a resource from within this resource.
* <p> * <p>
* This method is essentially an alias for {@link #addPath(String)}, but without checked exceptions. * This method is essentially an alias for {@link #addPath(String)}, but without checked exceptions.
* This method satisfied the {@link ResourceFactory} interface. * This method satisfied the {@link ResourceFactory} interface.
* @see org.eclipse.jetty.util.resource.ResourceFactory#getResource(java.lang.String) * @see org.eclipse.jetty.util.resource.ResourceFactory#getResource(java.lang.String)
*/ */
@Override
public Resource getResource(String path) public Resource getResource(String path)
{ {
try try
@ -447,14 +446,12 @@ public abstract class Resource implements ResourceFactory
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Encode according to this resource type. /**
* The default implementation calls URI.encodePath(uri) * @deprecated
* @param uri
* @return String encoded for this resource type.
*/ */
public String encode(String uri) public String encode(String uri)
{ {
return URIUtil.encodePath(uri); return null;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -21,7 +21,6 @@ package org.eclipse.jetty.util.resource;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
@ -32,7 +31,6 @@ import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -228,12 +226,15 @@ public class ResourceCollection extends Resource
Resource r = _resources[i].addPath(path); Resource r = _resources[i].addPath(path);
if (r.exists() && r.isDirectory()) if (r.exists() && r.isDirectory())
{ {
if (resources==null)
resources = new ArrayList<Resource>();
if (resource!=null) if (resource!=null)
{ {
resources = new ArrayList<Resource>();
resources.add(resource); resources.add(resource);
resource=null; resource=null;
} }
resources.add(r); resources.add(r);
} }
} }
@ -443,13 +444,13 @@ public class ResourceCollection extends Resource
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void release() public void close()
{ {
if(_resources==null) if(_resources==null)
throw new IllegalStateException("*resources* not set."); throw new IllegalStateException("*resources* not set.");
for(Resource r : _resources) for(Resource r : _resources)
r.release(); r.close();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -81,7 +81,7 @@ public class URLResource extends Resource
/** Release any resources held by the resource. /** Release any resources held by the resource.
*/ */
@Override @Override
public synchronized void release() public synchronized void close()
{ {
if (_in!=null) if (_in!=null)
{ {

View File

@ -0,0 +1,118 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.util.resource;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import junit.framework.Assert;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class ResourceAliasTest
{
static File __dir;
@BeforeClass
public static void beforeClass()
{
__dir=MavenTestingUtils.getTargetTestingDir("RAT");
}
@Before
public void before()
{
FS.ensureDirExists(__dir);
FS.ensureEmpty(__dir);
}
/* ------------------------------------------------------------ */
@Test
public void testNullCharEndingFilename() throws Exception
{
File file=new File(__dir,"test.txt");
assertFalse(file.exists());
file.createNewFile();
assertTrue(file.exists());
File file0=new File(__dir,"test.txt\0");
if (!file0.exists())
return; // this file system does not suffer this problem
assertTrue(file0.exists()); // This is an alias!
Resource dir = Resource.newResource(__dir);
// Test not alias paths
Resource resource = Resource.newResource(file);
assertTrue(resource.exists());
assertNull(resource.getAlias());
resource = Resource.newResource(file.getAbsoluteFile());
assertTrue(resource.exists());
assertNull(resource.getAlias());
resource = Resource.newResource(file.toURI());
assertTrue(resource.exists());
assertNull(resource.getAlias());
resource = Resource.newResource(file.toURI().toString());
assertTrue(resource.exists());
assertNull(resource.getAlias());
resource = dir.addPath("test.txt");
assertTrue(resource.exists());
assertNull(resource.getAlias());
// Test alias paths
resource = Resource.newResource(file0);
assertTrue(resource.exists());
assertNotNull(resource.getAlias());
resource = Resource.newResource(file0.getAbsoluteFile());
assertTrue(resource.exists());
assertNotNull(resource.getAlias());
resource = Resource.newResource(file0.toURI());
assertTrue(resource.exists());
assertNotNull(resource.getAlias());
resource = Resource.newResource(file0.toURI().toString());
assertTrue(resource.exists());
assertNotNull(resource.getAlias());
try
{
resource = dir.addPath("test.txt\0");
assertTrue(resource.exists());
assertNotNull(resource.getAlias());
}
catch(MalformedURLException e)
{
assertTrue(true);
}
}
}

View File

@ -33,12 +33,8 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.TimeZone;
import java.util.jar.JarFile;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import junit.framework.Assert;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.OS; import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
@ -329,13 +325,13 @@ public class ResourceTest
{ {
String s = "jar:"+__userURL+"TestData/test.zip!/subdir/numbers"; String s = "jar:"+__userURL+"TestData/test.zip!/subdir/numbers";
try(ZipFile zf = new ZipFile(MavenTestingUtils.getTestResourceFile("TestData/test.zip")))
ZipFile zf = new ZipFile(MavenTestingUtils.getTestResourceFile("TestData/test.zip")); {
long last = zf.getEntry("subdir/numbers").getTime();
long last = zf.getEntry("subdir/numbers").getTime();
Resource r = Resource.newResource(s); Resource r = Resource.newResource(s);
assertEquals(last,r.lastModified()); assertEquals(last,r.lastModified());
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -367,6 +363,7 @@ public class ResourceTest
assertEquals(1, dest.getParentFile().listFiles().length); assertEquals(1, dest.getParentFile().listFiles().length);
FilenameFilter dotdotFilenameFilter = new FilenameFilter() { FilenameFilter dotdotFilenameFilter = new FilenameFilter() {
@Override
public boolean accept(File directory, String name) public boolean accept(File directory, String name)
{ {
return name.equals("dotdot.txt"); return name.equals("dotdot.txt");
@ -376,6 +373,7 @@ public class ResourceTest
assertEquals(0, dest.getParentFile().listFiles(dotdotFilenameFilter).length); assertEquals(0, dest.getParentFile().listFiles(dotdotFilenameFilter).length);
FilenameFilter extractfileFilenameFilter = new FilenameFilter() { FilenameFilter extractfileFilenameFilter = new FilenameFilter() {
@Override
public boolean accept(File directory, String name) public boolean accept(File directory, String name)
{ {
return name.equals("extract-filenotdir"); return name.equals("extract-filenotdir");
@ -385,6 +383,7 @@ public class ResourceTest
assertEquals(0, dest.getParentFile().listFiles(extractfileFilenameFilter).length); assertEquals(0, dest.getParentFile().listFiles(extractfileFilenameFilter).length);
FilenameFilter currentDirectoryFilenameFilter = new FilenameFilter() { FilenameFilter currentDirectoryFilenameFilter = new FilenameFilter() {
@Override
public boolean accept(File directory, String name) public boolean accept(File directory, String name)
{ {
return name.equals("current.txt"); return name.equals("current.txt");
@ -405,15 +404,14 @@ public class ResourceTest
{ {
final String classPathName="Resource.class"; final String classPathName="Resource.class";
Resource resource=Resource.newClassPathResource(classPathName); try(Resource resource=Resource.newClassPathResource(classPathName);)
{
// A class path cannot be a directory
assertFalse("Class path cannot be a directory.",resource.isDirectory());
assertTrue(resource!=null); // A class path must exist
assertTrue("Class path resource does not exist.",resource.exists());
// A class path cannot be a directory }
assertFalse("Class path cannot be a directory.",resource.isDirectory());
// A class path must exist
assertTrue("Class path resource does not exist.",resource.exists());
} }
/** /**
@ -426,8 +424,6 @@ public class ResourceTest
Resource resource=Resource.newClassPathResource(classPathName); Resource resource=Resource.newClassPathResource(classPathName);
assertTrue(resource!=null);
// A class path cannot be a directory // A class path cannot be a directory
assertFalse("Class path cannot be a directory.",resource.isDirectory()); assertFalse("Class path cannot be a directory.",resource.isDirectory());
@ -445,9 +441,6 @@ public class ResourceTest
Resource resource=Resource.newClassPathResource(classPathName); Resource resource=Resource.newClassPathResource(classPathName);
assertTrue(resource!=null);
// A class path must be a directory // A class path must be a directory
assertTrue("Class path must be a directory.",resource.isDirectory()); assertTrue("Class path must be a directory.",resource.isDirectory());
@ -469,8 +462,6 @@ public class ResourceTest
// Will locate a resource in the class path // Will locate a resource in the class path
Resource resource=Resource.newClassPathResource(classPathName); Resource resource=Resource.newClassPathResource(classPathName);
assertTrue(resource!=null);
// A class path cannot be a directory // A class path cannot be a directory
assertFalse("Class path must be a directory.",resource.isDirectory()); assertFalse("Class path must be a directory.",resource.isDirectory());
@ -478,7 +469,6 @@ public class ResourceTest
File file=resource.getFile(); File file=resource.getFile();
assertTrue("File returned from class path should not be null.",file!=null);
assertEquals("File name from class path is not equal.",fileName,file.getName()); assertEquals("File name from class path is not equal.",fileName,file.getName());
assertTrue("File returned from class path should be a file.",file.isFile()); assertTrue("File returned from class path should be a file.",file.isFile());

View File

@ -66,7 +66,7 @@ public abstract class Descriptor
} }
finally finally
{ {
_xml.release(); _xml.close();
} }
} }
} }

View File

@ -167,10 +167,10 @@ public class OrderingTest
} }
/** /**
* @see org.eclipse.jetty.util.resource.Resource#release() * @see org.eclipse.jetty.util.resource.Resource#close()
*/ */
@Override @Override
public void release() public void close()
{ {
} }

View File

@ -60,7 +60,7 @@ public class WebAppClassLoaderTest
assertTrue(cantLoadClass("org.eclipse.jetty.webapp.Configuration")); assertTrue(cantLoadClass("org.eclipse.jetty.webapp.Configuration"));
Class clazzA = _loader.loadClass("org.acme.webapp.ClassInJarA"); Class<?> clazzA = _loader.loadClass("org.acme.webapp.ClassInJarA");
assertTrue(clazzA.getField("FROM_PARENT")!=null); assertTrue(clazzA.getField("FROM_PARENT")!=null);
} }

View File

@ -741,7 +741,6 @@ public class XmlConfiguration
private Object newObj(Object obj, XmlParser.Node node) throws Exception private Object newObj(Object obj, XmlParser.Node node) throws Exception
{ {
Class<?> oClass = nodeClass(node); Class<?> oClass = nodeClass(node);
int size = 0;
int argIndex = node.size(); int argIndex = node.size();
for (int i = 0; i < node.size(); i++) for (int i = 0; i < node.size(); i++)
{ {
@ -753,13 +752,12 @@ public class XmlConfiguration
argIndex = i; argIndex = i;
break; break;
} }
size++;
} }
Map<String, Object> namedArgMap = new HashMap<>(); Map<String, Object> namedArgMap = new HashMap<>();
List<Object> arguments = new LinkedList<>(); List<Object> arguments = new LinkedList<>();
for (int i = 0; i < size; i++) for (int i = 0; i < node.size(); i++)
{ {
Object o = node.get(i); Object o = node.get(i);

View File

@ -25,6 +25,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -541,6 +542,34 @@ public class XmlConfigurationTest
Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond()); Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond());
Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird()); Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird());
} }
@Test
public void testArgumentsGetIgnoredMissingDTD() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration(new ByteArrayInputStream(("" +
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
" <Arg>arg1</Arg> " +
" <Arg>arg2</Arg> " +
" <Arg>arg3</Arg> " +
" <Set name=\"nested\"> " +
" <New class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">\n" +
" <Arg>arg1</Arg>\n" +
" <Arg>arg2</Arg>\n" +
" <Arg>arg3</Arg>\n" +
" </New>" +
" </Set>" +
"</Configure>").getBytes("ISO-8859-1")));
// XmlConfiguration xmlConfiguration = new XmlConfiguration(url);
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
Assert.assertEquals("first parameter not wired correctly","arg1", atc.getFirst());
Assert.assertEquals("second parameter not wired correctly","arg2", atc.getSecond());
Assert.assertEquals("third parameter not wired correctly","arg3", atc.getThird());
Assert.assertEquals("nested first parameter not wired correctly","arg1", atc.getNested().getFirst());
Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond());
Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird());
}
@Test @Test
public void testNestedConstructorNamedInjectionUnorderedMixed() throws Exception public void testNestedConstructorNamedInjectionUnorderedMixed() throws Exception