You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/02/21 02:11:30 UTC
svn commit: r509848 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/services/
main/java/org/apache/tapestry/test/pagelevel/
test/java/org/apache/tapestry/internal/services/
Author: hlship
Date: Tue Feb 20 17:11:29 2007
New Revision: 509848
URL: http://svn.apache.org/viewvc?view=rev&rev=509848
Log:
Add getResourcePaths() to Context (part of an attempt to resolve TAPESTRY-1287)
Added:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassLocatorImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Context.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/pagelevel/ContextForPageTester.java
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassLocatorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassLocatorImpl.java?view=diff&rev=509848&r1=509847&r2=509848
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassLocatorImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassLocatorImpl.java Tue Feb 20 17:11:29 2007
@@ -15,6 +15,7 @@
package org.apache.tapestry.internal.services;
import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -56,7 +57,10 @@
try
{
- return findClassesWithinPath(packagePath);
+ Collection<String> result = findClassesWithinPath(packagePath);
+
+ return result;
+
}
catch (IOException ex)
{
@@ -71,7 +75,11 @@
Enumeration<URL> urls = _contextClassLoader.getResources(packagePath);
while (urls.hasMoreElements())
- scanURL(packagePath, result, urls.nextElement());
+ {
+ URL url = urls.nextElement();
+
+ scanURL(packagePath, result, url);
+ }
return result;
}
@@ -106,7 +114,21 @@
private void scan(String packagePath, URL packageURL, Collection<String> componentClassNames,
Stack<Queued> queue) throws IOException
{
- InputStream is = new BufferedInputStream(packageURL.openStream());
+ InputStream is = null;
+
+ try
+ {
+ is = new BufferedInputStream(packageURL.openStream());
+ }
+ catch (FileNotFoundException ex)
+ {
+ // This can happen for certain application servers (JBoss 4.0.5 for example), that
+ // export part of the exploded WAR for deployment, but leave part (WEB-INF/classes)
+ // unexploded.
+
+ return;
+ }
+
Reader reader = new InputStreamReader(is);
LineNumberReader lineReader = new LineNumberReader(reader);
@@ -189,4 +211,5 @@
componentClassNames.add(className);
}
}
+
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java?view=diff&rev=509848&r1=509847&r2=509848
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java Tue Feb 20 17:11:29 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,41 +12,86 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.services;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.servlet.ServletContext;
-
-import org.apache.tapestry.services.Context;
-
-
-
-public class ContextImpl implements Context
-{
- private final ServletContext _servletContext;
-
- public ContextImpl(ServletContext servletContext)
- {
- _servletContext = servletContext;
- }
-
- public URL getResource(String path)
- {
- try
- {
- return _servletContext.getResource(path);
- }
- catch (MalformedURLException ex)
- {
- throw new RuntimeException(ex);
- }
- }
-
- public String getInitParameter(String name)
- {
- return _servletContext.getInitParameter(name);
- }
-
-}
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newStack;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tapestry.ioc.util.Stack;
+import org.apache.tapestry.services.Context;
+
+public class ContextImpl implements Context
+{
+ private final ServletContext _servletContext;
+
+ public ContextImpl(ServletContext servletContext)
+ {
+ _servletContext = servletContext;
+ }
+
+ public URL getResource(String path)
+ {
+ try
+ {
+ return _servletContext.getResource(path);
+ }
+ catch (MalformedURLException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public String getInitParameter(String name)
+ {
+ return _servletContext.getInitParameter(name);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<String> getResourcePaths(String path)
+ {
+ List<String> result = newList();
+ Stack<String> queue = newStack();
+
+ queue.push(path);
+
+ while (!queue.isEmpty())
+ {
+ String current = queue.pop();
+
+ System.err.println("Searching: " + current);
+
+ Set<String> matches = (Set<String>) _servletContext.getResourcePaths(current);
+
+ // Tomcat 5.5.20 inside JBoss 4.0.2 has been observed to do this!
+ // Perhaps other servers do as well.
+
+ if (matches == null)
+ continue;
+
+ for (String match : matches)
+ {
+ System.err.println("Found: " + match);
+
+ // Folders are queued up for further expansion.
+
+ if (match.endsWith("/"))
+ queue.push(match);
+ else
+ result.add(match);
+ }
+
+ }
+
+ Collections.sort(result);
+
+ return result;
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Context.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Context.java?view=diff&rev=509848&r1=509847&r2=509848
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Context.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/Context.java Tue Feb 20 17:11:29 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package org.apache.tapestry.services;
import java.net.URL;
+import java.util.List;
/**
* An API agnostic version of {@link javax.servlet.ServletContext}, used to bridge the gaps between
@@ -33,4 +34,15 @@
/** Returns an initial parameter value defined by servlet. */
String getInitParameter(String name);
+
+ /**
+ * Looks for resources within the web application within the supplied path. The list will be
+ * recurively expanded, as necessary. The path must start with a leading slash, and usually ends
+ * with a slash as well.
+ *
+ * @param path
+ * to search for (should start with a leading slash)
+ * @return the matches, sorted alphabetically
+ */
+ List<String> getResourcePaths(String path);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=509848&r1=509847&r2=509848
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Tue Feb 20 17:11:29 2007
@@ -561,6 +561,7 @@
ComponentEventResultProcessor.class,
ComponentMessagesSource.class,
ComponentSource.class,
+ Context.class,
DefaultComponentParameterBindingSource.class,
Environment.class,
FieldValidatorDefaultSource.class,
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/pagelevel/ContextForPageTester.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/pagelevel/ContextForPageTester.java?view=diff&rev=509848&r1=509847&r2=509848
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/pagelevel/ContextForPageTester.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/pagelevel/ContextForPageTester.java Tue Feb 20 17:11:29 2007
@@ -17,6 +17,7 @@
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.List;
import org.apache.tapestry.services.Context;
@@ -37,7 +38,7 @@
public URL getResource(String path)
{
File f = new File(_contextRoot + path);
-
+
if (!f.exists() || !f.isFile())
{
return null;
@@ -50,6 +51,12 @@
{
throw new RuntimeException(ex);
}
+ }
+
+ public List<String> getResourcePaths(String path)
+ {
+ throw new UnsupportedOperationException(
+ "getResourcePaths() is not supported for ContextForPageTester.");
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java?view=auto&rev=509848
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java Tue Feb 20 17:11:29 2007
@@ -0,0 +1,139 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.testng.annotations.Test;
+
+public class ContextImplTest extends InternalBaseTestCase
+{
+ @Test
+ public void get_resource_exists() throws Exception
+ {
+ String path = "/foo";
+ URL url = getClass().getResource("ContextImplTest.class");
+
+ ServletContext servletContext = newServletContext();
+
+ expect(servletContext.getResource(path)).andReturn(url);
+
+ replay();
+
+ URL result = new ContextImpl(servletContext).getResource(path);
+
+ assertSame(result, url);
+
+ verify();
+ }
+
+ @Test
+ public void get_resource_exception() throws Exception
+ {
+ String path = "/foo";
+ Throwable t = new MalformedURLException("/foo is not a URL.");
+
+ ServletContext servletContext = newServletContext();
+
+ expect(servletContext.getResource(path)).andThrow(t);
+
+ replay();
+
+ try
+ {
+ new ContextImpl(servletContext).getResource(path);
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertEquals(ex.getMessage(), "java.net.MalformedURLException: /foo is not a URL.");
+ assertSame(ex.getCause(), t);
+ }
+
+ verify();
+ }
+
+ @Test
+ public void get_resource_paths() throws Exception
+ {
+ ServletContext servletContext = newServletContext();
+
+ train_getResourcePaths(
+ servletContext,
+ "/foo",
+ "/foo/alpha.html",
+ "/foo/beta/",
+ "/foo/gamma.html");
+ train_getResourcePaths(
+ servletContext,
+ "/foo/beta/",
+ "/foo/beta/b.html",
+ "/foo/beta/a.html",
+ "/foo/beta/c/");
+ train_getResourcePaths(servletContext, "/foo/beta/c/", "/foo/beta/c/c.html");
+
+ replay();
+
+ List<String> actual = new ContextImpl(servletContext).getResourcePaths("/foo");
+
+ assertEquals(actual, Arrays.asList(
+ "/foo/alpha.html",
+ "/foo/beta/a.html",
+ "/foo/beta/b.html",
+ "/foo/beta/c/c.html",
+ "/foo/gamma.html"));
+
+ verify();
+ }
+
+ /** Tomcat 5.5.20 appears to sometimes return null if it can't find a match. */
+ @Test
+ public void ignore_null_from_get_resource_paths() throws Exception
+ {
+ ServletContext servletContext = newServletContext();
+
+ expect(servletContext.getResourcePaths("/foo")).andReturn(null);
+
+ replay();
+
+ List<String> actual = new ContextImpl(servletContext).getResourcePaths("/foo");
+
+ assertTrue(actual.isEmpty());
+
+ verify();
+
+ }
+
+ protected final ServletContext newServletContext()
+ {
+ return newMock(ServletContext.class);
+ }
+
+ protected final void train_getResourcePaths(ServletContext context, String path,
+ String... paths)
+ {
+ Set<String> set = CollectionFactory.newSet(Arrays.asList(paths));
+
+ expect(context.getResourcePaths(path)).andReturn(set);
+ }
+}