Issue #3278 - ResourceCollection NPE
+ Adding tests + more NPE / ISE / IAE fixes Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
ebef147d93
commit
12628adc10
|
@ -84,8 +84,7 @@ public class ResourceCollection extends Resource
|
||||||
_resources = list.toArray(new Resource[list.size()]);
|
_resources = list.toArray(new Resource[list.size()]);
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
if(!r.exists() || !r.isDirectory())
|
assertResourceValid(r);
|
||||||
throw new IllegalArgumentException(r + " is not an existing directory.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,17 +97,34 @@ public class ResourceCollection extends Resource
|
||||||
*/
|
*/
|
||||||
public ResourceCollection(String[] resources)
|
public ResourceCollection(String[] resources)
|
||||||
{
|
{
|
||||||
_resources = new Resource[resources.length];
|
if(resources == null || resources.length ==0)
|
||||||
|
{
|
||||||
|
_resources = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<Resource> res = new ArrayList<>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for(int i=0; i<resources.length; i++)
|
for(String strResource: resources)
|
||||||
{
|
{
|
||||||
_resources[i] = Resource.newResource(resources[i]);
|
if(strResource == null || strResource.length() == 0)
|
||||||
if(!_resources[i].exists() || !_resources[i].isDirectory())
|
continue; // skip null and empty string only (whitespace only is valid)
|
||||||
throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
|
Resource resource = Resource.newResource(strResource);
|
||||||
|
assertResourceValid(resource);
|
||||||
|
res.add(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.isEmpty())
|
||||||
|
{
|
||||||
|
_resources = null;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
catch(IllegalArgumentException e)
|
|
||||||
|
_resources = res.toArray(new Resource[0]);
|
||||||
|
}
|
||||||
|
catch(RuntimeException e)
|
||||||
{
|
{
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +164,31 @@ public class ResourceCollection extends Resource
|
||||||
*/
|
*/
|
||||||
public void setResources(Resource[] resources)
|
public void setResources(Resource[] resources)
|
||||||
{
|
{
|
||||||
_resources = resources != null ? resources : new Resource[0];
|
if (resources == null || resources.length == 0)
|
||||||
|
{
|
||||||
|
_resources = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Resource> res = new ArrayList<>();
|
||||||
|
for (Resource resource : resources)
|
||||||
|
{
|
||||||
|
if (resource == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertResourceValid(resource);
|
||||||
|
res.add(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.isEmpty())
|
||||||
|
{
|
||||||
|
_resources = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_resources = res.toArray(new Resource[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -161,6 +201,9 @@ public class ResourceCollection extends Resource
|
||||||
*/
|
*/
|
||||||
public void setResourcesAsCSV(String csvResources)
|
public void setResourcesAsCSV(String csvResources)
|
||||||
{
|
{
|
||||||
|
if(csvResources == null)
|
||||||
|
throw new IllegalArgumentException("CSV String is null");
|
||||||
|
|
||||||
StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;");
|
StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;");
|
||||||
int len = tokenizer.countTokens();
|
int len = tokenizer.countTokens();
|
||||||
if(len==0)
|
if(len==0)
|
||||||
|
@ -169,25 +212,38 @@ public class ResourceCollection extends Resource
|
||||||
" argument must be a string containing one or more comma-separated resource strings.");
|
" argument must be a string containing one or more comma-separated resource strings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Resource> resources = new ArrayList<>();
|
List<Resource> res = new ArrayList<>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while(tokenizer.hasMoreTokens())
|
while(tokenizer.hasMoreTokens())
|
||||||
{
|
{
|
||||||
Resource resource = Resource.newResource(tokenizer.nextToken().trim());
|
String token = tokenizer.nextToken().trim();
|
||||||
if(!resource.exists() || !resource.isDirectory())
|
// TODO: we should not trim here, as whitespace is valid for paths
|
||||||
LOG.warn(" !exist "+resource);
|
if (token == null || token.length() == 0)
|
||||||
else
|
continue; // skip
|
||||||
resources.add(resource);
|
Resource resource = Resource.newResource(token);
|
||||||
|
assertResourceValid(resource);
|
||||||
|
res.add(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.isEmpty())
|
||||||
|
{
|
||||||
|
_resources = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_resources = res.toArray(new Resource[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (RuntimeException e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
_resources = resources.toArray(new Resource[resources.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -198,8 +254,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public Resource addPath(String path) throws IOException, MalformedURLException
|
public Resource addPath(String path) throws IOException, MalformedURLException
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
if(path==null)
|
if(path==null)
|
||||||
throw new MalformedURLException();
|
throw new MalformedURLException();
|
||||||
|
@ -227,7 +282,7 @@ public class ResourceCollection extends Resource
|
||||||
if (r.exists() && r.isDirectory())
|
if (r.exists() && r.isDirectory())
|
||||||
{
|
{
|
||||||
if (resources==null)
|
if (resources==null)
|
||||||
resources = new ArrayList<Resource>();
|
resources = new ArrayList<>();
|
||||||
|
|
||||||
if (resource!=null)
|
if (resource!=null)
|
||||||
{
|
{
|
||||||
|
@ -242,7 +297,7 @@ public class ResourceCollection extends Resource
|
||||||
if (resource!=null)
|
if (resource!=null)
|
||||||
return resource;
|
return resource;
|
||||||
if (resources!=null)
|
if (resources!=null)
|
||||||
return new ResourceCollection(resources.toArray(new Resource[resources.size()]));
|
return new ResourceCollection(resources.toArray(new Resource[0]));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +310,8 @@ public class ResourceCollection extends Resource
|
||||||
*/
|
*/
|
||||||
protected Object findResource(String path) throws IOException, MalformedURLException
|
protected Object findResource(String path) throws IOException, MalformedURLException
|
||||||
{
|
{
|
||||||
|
assertResourcesSet();
|
||||||
|
|
||||||
Resource resource=null;
|
Resource resource=null;
|
||||||
ArrayList<Resource> resources = null;
|
ArrayList<Resource> resources = null;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
@ -277,7 +334,7 @@ public class ResourceCollection extends Resource
|
||||||
{
|
{
|
||||||
if (resource!=null)
|
if (resource!=null)
|
||||||
{
|
{
|
||||||
resources = new ArrayList<Resource>();
|
resources = new ArrayList<>();
|
||||||
resources.add(resource);
|
resources.add(resource);
|
||||||
}
|
}
|
||||||
resources.add(r);
|
resources.add(r);
|
||||||
|
@ -302,8 +359,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public boolean exists()
|
public boolean exists()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -312,8 +368,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public File getFile() throws IOException
|
public File getFile() throws IOException
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
|
@ -328,8 +383,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public InputStream getInputStream() throws IOException
|
public InputStream getInputStream() throws IOException
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
|
@ -344,8 +398,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public ReadableByteChannel getReadableByteChannel() throws IOException
|
public ReadableByteChannel getReadableByteChannel() throws IOException
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
|
@ -360,8 +413,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
|
@ -376,8 +428,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public URL getURL()
|
public URL getURL()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
|
@ -392,8 +443,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public boolean isDirectory()
|
public boolean isDirectory()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -402,8 +452,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public long lastModified()
|
public long lastModified()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
|
@ -428,16 +477,15 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public String[] list()
|
public String[] list()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
HashSet<String> set = new HashSet<String>();
|
HashSet<String> set = new HashSet<>();
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
{
|
{
|
||||||
for(String s : r.list())
|
for(String s : r.list())
|
||||||
set.add(s);
|
set.add(s);
|
||||||
}
|
}
|
||||||
String[] result=set.toArray(new String[set.size()]);
|
String[] result=set.toArray(new String[0]);
|
||||||
Arrays.sort(result);
|
Arrays.sort(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -446,8 +494,7 @@ public class ResourceCollection extends Resource
|
||||||
@Override
|
@Override
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
if(_resources==null || _resources.length==0)
|
assertResourcesSet();
|
||||||
throw new IllegalStateException("*resources* not set.");
|
|
||||||
|
|
||||||
for(Resource r : _resources)
|
for(Resource r : _resources)
|
||||||
r.close();
|
r.close();
|
||||||
|
@ -465,6 +512,8 @@ public class ResourceCollection extends Resource
|
||||||
public void copyTo(File destination)
|
public void copyTo(File destination)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
assertResourcesSet();
|
||||||
|
|
||||||
for (int r=_resources.length;r-->0;)
|
for (int r=_resources.length;r-->0;)
|
||||||
_resources[r].copyTo(destination);
|
_resources[r].copyTo(destination);
|
||||||
}
|
}
|
||||||
|
@ -490,4 +539,19 @@ public class ResourceCollection extends Resource
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertResourcesSet()
|
||||||
|
{
|
||||||
|
if (_resources == null || _resources.length == 0)
|
||||||
|
throw new IllegalStateException("*resources* not set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertResourceValid(Resource resource)
|
||||||
|
{
|
||||||
|
if (!resource.exists() || !resource.isDirectory())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException(resource + " is not an existing directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,156 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.resource;
|
package org.eclipse.jetty.util.resource;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||||
|
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@ExtendWith(WorkDirExtension.class)
|
||||||
public class ResourceCollectionTest
|
public class ResourceCollectionTest
|
||||||
{
|
{
|
||||||
|
public WorkDir workdir;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnsetCollection_ThrowsISE()
|
||||||
|
{
|
||||||
|
ResourceCollection coll = new ResourceCollection();
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyResourceArray_ThrowsISE()
|
||||||
|
{
|
||||||
|
ResourceCollection coll = new ResourceCollection(new Resource[0]);
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResourceArrayWithNull_ThrowsISE()
|
||||||
|
{
|
||||||
|
ResourceCollection coll = new ResourceCollection(new Resource[]{null});
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyStringArray_ThrowsISE()
|
||||||
|
{
|
||||||
|
ResourceCollection coll = new ResourceCollection(new String[0]);
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringArrayWithNull_ThrowsISE()
|
||||||
|
{
|
||||||
|
ResourceCollection coll = new ResourceCollection(new String[]{null});
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullCsv_ThrowsIAE()
|
||||||
|
{
|
||||||
|
assertThrows(IllegalArgumentException.class, ()->{
|
||||||
|
String csv = null;
|
||||||
|
new ResourceCollection(csv); // throws IAE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyCsv_ThrowsIAE()
|
||||||
|
{
|
||||||
|
assertThrows(IllegalArgumentException.class, ()->{
|
||||||
|
String csv = "";
|
||||||
|
new ResourceCollection(csv); // throws IAE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBlankCsv_ThrowsIAE()
|
||||||
|
{
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
String csv = ",,,,";
|
||||||
|
new ResourceCollection(csv); // throws IAE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetResourceNull_ThrowsISE()
|
||||||
|
{
|
||||||
|
// Create a ResourceCollection with one valid entry
|
||||||
|
Path path = MavenTestingUtils.getTargetPath();
|
||||||
|
PathResource resource = new PathResource(path);
|
||||||
|
ResourceCollection coll = new ResourceCollection(resource);
|
||||||
|
|
||||||
|
// Reset collection to invalid state
|
||||||
|
coll.setResources(null);
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetResourceEmpty_ThrowsISE()
|
||||||
|
{
|
||||||
|
// Create a ResourceCollection with one valid entry
|
||||||
|
Path path = MavenTestingUtils.getTargetPath();
|
||||||
|
PathResource resource = new PathResource(path);
|
||||||
|
ResourceCollection coll = new ResourceCollection(resource);
|
||||||
|
|
||||||
|
// Reset collection to invalid state
|
||||||
|
coll.setResources(new Resource[0]);
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetResourceAllNulls_ThrowsISE()
|
||||||
|
{
|
||||||
|
// Create a ResourceCollection with one valid entry
|
||||||
|
Path path = MavenTestingUtils.getTargetPath();
|
||||||
|
PathResource resource = new PathResource(path);
|
||||||
|
ResourceCollection coll = new ResourceCollection(resource);
|
||||||
|
|
||||||
|
// Reset collection to invalid state
|
||||||
|
coll.setResources(new Resource[]{null,null,null});
|
||||||
|
|
||||||
|
assertThrowIllegalStateException(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertThrowIllegalStateException(ResourceCollection coll)
|
||||||
|
{
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.addPath("foo"));
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.findResource("bar"));
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.exists());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.getFile());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.getInputStream());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.getReadableByteChannel());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.getURL());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.getName());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.isDirectory());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.lastModified());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.list());
|
||||||
|
assertThrows(IllegalStateException.class, ()->coll.close());
|
||||||
|
assertThrows(IllegalStateException.class, ()->
|
||||||
|
{
|
||||||
|
Path destPath = workdir.getPathFile("bar");
|
||||||
|
coll.copyTo(destPath.toFile());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMutlipleSources1() throws Exception
|
public void testMutlipleSources1() throws Exception
|
||||||
|
|
Loading…
Reference in New Issue