You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2010/08/29 17:49:03 UTC

svn commit: r990597 - in /wicket/trunk: wicket-request/src/main/java/org/apache/wicket/request/mapper/ wicket/src/main/java/org/apache/wicket/ wicket/src/main/java/org/apache/wicket/markup/html/image/resource/ wicket/src/main/java/org/apache/wicket/req...

Author: jdonnerstag
Date: Sun Aug 29 15:49:02 2010
New Revision: 990597

URL: http://svn.apache.org/viewvc?rev=990597&view=rev
Log:
Started to javadoc ResourceReference and friends

WICKET-1996
Issue: WICKET-1996

Modified:
    wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/SharedResources.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/image/resource/LocalizedImageResource.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapper.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/AbstractResource.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ClassScanner.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ContentDisposition.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/JavascriptResourceReference.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReferenceRegistry.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/SharedResourceReference.java

Modified: wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java (original)
+++ wicket/trunk/wicket-request/src/main/java/org/apache/wicket/request/mapper/CompoundRequestMapper.java Sun Aug 29 15:49:02 2010
@@ -61,6 +61,15 @@ public class CompoundRequestMapper imple
 		{
 			return mapper;
 		}
+
+		/**
+		 * @see java.lang.Object#toString()
+		 */
+		@Override
+		public String toString()
+		{
+			return "Mapper: " + mapper.getClass().getName() + "; Score: " + compatibilityScore;
+		}
 	}
 
 	private final List<IRequestMapper> mappers = new CopyOnWriteArrayList<IRequestMapper>();

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/SharedResources.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/SharedResources.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/SharedResources.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/SharedResources.java Sun Aug 29 15:49:02 2010
@@ -117,6 +117,6 @@ public class SharedResources
 	public ResourceReference get(Class<?> scope, String name, Locale locale, String style,
 		String variation, boolean strict)
 	{
-		return registry.getResourceReference(scope, name, locale, style, variation, strict);
+		return registry.getResourceReference(scope, name, locale, style, variation, strict, true);
 	}
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/image/resource/LocalizedImageResource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/image/resource/LocalizedImageResource.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/image/resource/LocalizedImageResource.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/markup/html/image/resource/LocalizedImageResource.java Sun Aug 29 15:49:02 2010
@@ -24,6 +24,7 @@ import org.apache.wicket.IClusterable;
 import org.apache.wicket.IResourceFactory;
 import org.apache.wicket.IResourceListener;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ThreadContext;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.border.Border;
@@ -32,9 +33,9 @@ import org.apache.wicket.request.cycle.R
 import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.request.resource.IResource.Attributes;
 import org.apache.wicket.request.resource.PackageResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.request.resource.IResource.Attributes;
 import org.apache.wicket.util.lang.Objects;
 import org.apache.wicket.util.parse.metapattern.Group;
 import org.apache.wicket.util.parse.metapattern.MetaPattern;
@@ -183,10 +184,10 @@ public final class LocalizedImageResourc
 		// If we have a resource reference
 		if (resourceReference != null)
 		{
-			component.getApplication()
+			// Bind the reference to the application
+			ThreadContext.getApplication()
 				.getResourceReferenceRegistry()
 				.registerResourceReference(resourceReference);
-			// Bind the reference to the application
 		}
 	}
 
@@ -340,11 +341,8 @@ public final class LocalizedImageResourc
 		}
 
 		// Set the SRC attribute to point to the component or shared resource
-		tag.put(
-			"src",
-			RequestCycle.get()
-				.getOriginalResponse()
-				.encodeURL(Strings.replaceAll(url, "&", "&amp;")));
+		tag.put("src", RequestCycle.get().getOriginalResponse().encodeURL(
+			Strings.replaceAll(url, "&", "&amp;")));
 	}
 
 	/**
@@ -439,7 +437,7 @@ public final class LocalizedImageResourc
 			{
 				// Is resource already available via the application?
 				if (application.getResourceReferenceRegistry().getResourceReference(
-					Application.class, imageReferenceName, locale, style, variation, true) == null)
+					Application.class, imageReferenceName, locale, style, variation, true, false) == null)
 				{
 					// Resource not available yet, so create it with factory and
 					// share via Application

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java Sun Aug 29 15:49:02 2010
@@ -220,6 +220,9 @@ public class RequestCycle extends Reques
 				return true;
 			}
 
+			// Did not find any suitable handler, thus not executing the request
+			log.error("Unable to execute request. No suitable RequestHandler found. URL=" +
+				request.getUrl());
 		}
 		catch (Exception e)
 		{
@@ -230,7 +233,7 @@ public class RequestCycle extends Reques
 			}
 			else
 			{
-				log.error("Error during request processing", e);
+				log.error("Error during request processing. URL=" + request.getUrl(), e);
 			}
 			return true;
 		}

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapper.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/AbstractResourceReferenceMapper.java Sun Aug 29 15:49:02 2010
@@ -21,6 +21,7 @@ import java.util.Locale;
 import org.apache.wicket.request.Url;
 import org.apache.wicket.request.Url.QueryParameter;
 import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.string.Strings;
 
 /**
@@ -135,10 +136,8 @@ public abstract class AbstractResourceRe
 
 	protected ResourceReference.UrlAttributes getResourceReferenceAttributes(Url url)
 	{
-		if (url == null)
-		{
-			throw new IllegalStateException("Argument 'url' may not be null.");
-		}
+		Args.notNull(url, "url");
+
 		if (url.getQueryParameters().size() > 0)
 		{
 			QueryParameter param = url.getQueryParameters().get(0);

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java Sun Aug 29 15:49:02 2010
@@ -97,7 +97,7 @@ class BasicResourceReferenceMapper exten
 			{
 				ResourceReference res = getContext().getResourceReferenceRegistry()
 					.getResourceReference(scope, name.toString(), attributes.getLocale(),
-						attributes.getStyle(), attributes.getVariation(), true);
+						attributes.getStyle(), attributes.getVariation(), true, true);
 
 				if (res != null)
 				{

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/AbstractResource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/AbstractResource.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/AbstractResource.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/AbstractResource.java Sun Aug 29 15:49:02 2010
@@ -34,7 +34,7 @@ import org.apache.wicket.util.lang.Args;
 
 /**
  * Convenience resource implementation. The subclass must implement
- * {@link #newResourceResponse(org.apache.wicket.ng.resource.IResource.Attributes)} method.
+ * {@link #newResourceResponse(org.apache.wicket.request.resource.IResource.Attributes)} method.
  * 
  * @author Matej Knopp
  */
@@ -42,6 +42,8 @@ public abstract class AbstractResource i
 {
 	private static final long serialVersionUID = 1L;
 
+	private static final String CACHE_CONTROL = "Cache-Control";
+
 	/**
 	 * Construct.
 	 */
@@ -109,7 +111,6 @@ public abstract class AbstractResource i
 			this.errorMessage = errorMessage;
 		}
 
-
 		/**
 		 * @return error code or <code>null</code>
 		 */
@@ -325,7 +326,7 @@ public abstract class AbstractResource i
 		 * 
 		 * @param writeCallback
 		 */
-		public void setWriteCallback(WriteCallback writeCallback)
+		public void setWriteCallback(final WriteCallback writeCallback)
 		{
 			Args.notNull(writeCallback, "writeCallback");
 			this.writeCallback = writeCallback;
@@ -340,30 +341,42 @@ public abstract class AbstractResource i
 		}
 	}
 
-	protected void configureCache(WebRequest request, WebResponse response, ResourceResponse data,
-		Attributes attributes)
+	/**
+	 * Configure the web response header for client cache control.
+	 * 
+	 * @param request
+	 * @param response
+	 * @param data
+	 * @param attributes
+	 */
+	protected void configureCache(final WebRequest request, final WebResponse response,
+		final ResourceResponse data, final Attributes attributes)
 	{
 		if (data.isCacheable())
 		{
 			// If time is set also set cache headers.
 			response.setDateHeader("Expires", System.currentTimeMillis() +
 				(data.getCacheDuration() * 1000L));
-			response.setHeader("Cache-Control", "max-age=" + data.getCacheDuration());
+			response.setHeader(CACHE_CONTROL, "max-age=" + data.getCacheDuration());
 		}
 		else
 		{
-			response.setHeader("Cache-Control", "no-cache, must-revalidate");
+			response.setHeader(CACHE_CONTROL, "no-cache, must-revalidate");
 		}
 	}
 
-	public final void respond(Attributes attributes)
+	/**
+	 * 
+	 * @see org.apache.wicket.request.resource.IResource#respond(org.apache.wicket.request.resource.IResource.Attributes)
+	 */
+	public final void respond(final Attributes attributes)
 	{
+		// Get a "new" ResourceResponse to write a response
 		ResourceResponse data = newResourceResponse(attributes);
 
 		WebRequest request = (WebRequest)attributes.getRequest();
 		WebResponse response = (WebResponse)attributes.getResponse();
 
-
 		// 1. Last Modified
 		Date lastModified = data.getLastModified();
 		if (lastModified != null)
@@ -372,7 +385,6 @@ public abstract class AbstractResource i
 		}
 
 		// 2. Caching
-
 		configureCache(request, response, data, attributes);
 
 		if (!data.dataNeedsToBeWritten(attributes))
@@ -383,6 +395,7 @@ public abstract class AbstractResource i
 		else if (data.getErrorCode() != null)
 		{
 			response.sendError(data.getErrorCode(), data.getErrorMessage());
+			return;
 		}
 		else
 		{
@@ -397,7 +410,6 @@ public abstract class AbstractResource i
 			String mimeType = data.getContentType();
 			String encoding = null;
 
-
 			if (mimeType != null && mimeType.indexOf("text") != -1)
 			{
 				encoding = data.getTextEncoding();
@@ -406,7 +418,6 @@ public abstract class AbstractResource i
 			long contentLength = data.getContentLength();
 
 			// 3. Content Disposition
-
 			if (ContentDisposition.ATTACHMENT == disposition)
 			{
 				response.setAttachmentHeader(fileName);
@@ -417,7 +428,6 @@ public abstract class AbstractResource i
 			}
 
 			// 4. Mime Type (+ encoding)
-
 			if (mimeType != null)
 			{
 				if (encoding == null)
@@ -430,9 +440,7 @@ public abstract class AbstractResource i
 				}
 			}
 
-
 			// 5. Content Length
-
 			if (contentLength != -1)
 			{
 				response.setContentLength(contentLength);

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java Sun Aug 29 15:49:02 2010
@@ -90,9 +90,11 @@ public class ByteArrayResource extends A
 
 	protected void configureResponse(final ResourceResponse response, final Attributes attributes)
 	{
-
 	}
 
+	/**
+	 * @see org.apache.wicket.request.resource.AbstractResource#newResourceResponse(org.apache.wicket.request.resource.IResource.Attributes)
+	 */
 	@Override
 	protected ResourceResponse newResourceResponse(final Attributes attributes)
 	{
@@ -103,7 +105,6 @@ public class ByteArrayResource extends A
 
 		if (response.dataNeedsToBeWritten(attributes))
 		{
-
 			if (filename != null)
 			{
 				response.setFileName(filename);
@@ -113,6 +114,7 @@ public class ByteArrayResource extends A
 			{
 				response.setContentDisposition(ContentDisposition.INLINE);
 			}
+
 			response.setWriteCallback(new WriteCallback()
 			{
 				@Override
@@ -123,10 +125,8 @@ public class ByteArrayResource extends A
 			});
 
 			configureResponse(response, attributes);
-
 		}
 
 		return response;
 	}
-
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ClassScanner.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ClassScanner.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ClassScanner.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ClassScanner.java Sun Aug 29 15:49:02 2010
@@ -18,20 +18,38 @@ package org.apache.wicket.request.resour
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.wicket.util.collections.ConcurrentHashSet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 abstract class ClassScanner
 {
-	private final Set<String> scannedClasses = new HashSet<String>();;
+	private static Logger log = LoggerFactory.getLogger(ClassScanner.class);
+
+	private final Set<String> scannedClasses = new ConcurrentHashSet<String>();
+
+	abstract boolean foundResourceReference(ResourceReference reference);
+
+	ClassScanner()
+	{
+	}
 
-	abstract void foundResourceReference(ResourceReference reference);
+	public final void clearCache()
+	{
+		scannedClasses.clear();
+	}
 
-	public void scanClass(Class<?> klass)
+	public int scanClass(final Class<?> klass)
 	{
+		// scanClass gets recursively called. If klass == null, than recursion stops
+		if (klass == null)
+		{
+			return 0;
+		}
+
+		int count = 0;
 		String className = klass.getName();
 		if (scannedClasses.contains(className) == false)
 		{
@@ -47,7 +65,10 @@ abstract class ClassScanner
 						Object value = f.get(null);
 						if (value instanceof ResourceReference)
 						{
-							foundResourceReference((ResourceReference)value);
+							if (foundResourceReference((ResourceReference)value) == true)
+							{
+								count += 1;
+							}
 						}
 					}
 					catch (Exception e)
@@ -57,13 +78,8 @@ abstract class ClassScanner
 				}
 			}
 
-			klass = klass.getSuperclass();
-			if (klass != null)
-			{
-				scanClass(klass);
-			}
+			count += scanClass(klass.getSuperclass());
 		}
+		return count;
 	}
-
-	private static Logger log = LoggerFactory.getLogger(ClassScanner.class);
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ContentDisposition.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ContentDisposition.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ContentDisposition.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ContentDisposition.java Sun Aug 29 15:49:02 2010
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.wicket.request.resource;
 
 /**

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/JavascriptResourceReference.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/JavascriptResourceReference.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/JavascriptResourceReference.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/JavascriptResourceReference.java Sun Aug 29 15:49:02 2010
@@ -37,5 +37,4 @@ public class JavascriptResourceReference
 	{
 		super(scope, name);
 	}
-
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResource.java Sun Aug 29 15:49:02 2010
@@ -35,6 +35,10 @@ import org.slf4j.LoggerFactory;
 
 public class PackageResource implements IResource
 {
+	private static final Logger log = LoggerFactory.getLogger(PackageResource.class);
+
+	private static final long serialVersionUID = 1L;
+
 	/**
 	 * Exception thrown when the creation of a package resource is not allowed.
 	 */
@@ -53,8 +57,6 @@ public class PackageResource implements 
 		}
 	}
 
-	private static final long serialVersionUID = 1L;
-
 	/** The path to the resource */
 	private final String absolutePath;
 
@@ -130,7 +132,9 @@ public class PackageResource implements 
 		return style;
 	}
 
-
+	/**
+	 * @see org.apache.wicket.request.resource.IResource#respond(org.apache.wicket.request.resource.IResource.Attributes)
+	 */
 	public void respond(Attributes attributes)
 	{
 		// Locate resource
@@ -160,6 +164,12 @@ public class PackageResource implements 
 		new ResourceStreamResource(resourceStream).respond(attributes);
 	}
 
+	/**
+	 * 
+	 * @param scope
+	 * @param path
+	 * @return
+	 */
 	private boolean accept(Class<?> scope, String path)
 	{
 		IPackageResourceGuard guard = Application.get()
@@ -169,8 +179,6 @@ public class PackageResource implements 
 		return guard.accept(scope, path);
 	}
 
-	private static final Logger log = LoggerFactory.getLogger(PackageResource.class);
-
 	/**
 	 * Gets whether a resource for a given set of criteria exists.
 	 * 

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java Sun Aug 29 15:49:02 2010
@@ -29,6 +29,8 @@ public class PackageResourceReference ex
 {
 	private static final long serialVersionUID = 1L;
 
+	private transient ConcurrentMap<UrlAttributes, UrlAttributes> urlAttributesCacheMap;
+
 	public PackageResourceReference(Class<?> scope, String name, Locale locale, String style,
 		String variation)
 	{
@@ -105,8 +107,6 @@ public class PackageResourceReference ex
 		return res;
 	}
 
-	private transient ConcurrentMap<UrlAttributes, UrlAttributes> urlAttributesCacheMap;
-
 	@Override
 	public UrlAttributes getUrlAttributes()
 	{

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java Sun Aug 29 15:49:02 2010
@@ -255,7 +255,7 @@ public abstract class ResourceReference 
 		{
 			return Objects.hashCode(getLocale(), getStyle(), getVariation());
 		}
-	};
+	}
 
 	/**
 	 * Can be used to disable registering certain resource references in

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReferenceRegistry.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReferenceRegistry.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReferenceRegistry.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReferenceRegistry.java Sun Aug 29 15:49:02 2010
@@ -17,76 +17,54 @@
 package org.apache.wicket.request.resource;
 
 import java.util.Locale;
-import java.util.Map;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Generics;
 import org.apache.wicket.util.lang.Objects;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Allows to register and lookup {@link ResourceReference}s.
  * 
+ * @see org.apache.wicket.Application#getResourceReferenceRegistry()
+ * @see org.apache.wicket.Application#newResourceReferenceRegistry()
+ * 
  * @author Matej Knopp
+ * @author Juergen Donnerstag
  */
 public class ResourceReferenceRegistry
 {
-	private static class Key
-	{
-		private final String scope;
-		private final String name;
-		private final Locale locale;
-		private final String style;
-		private final String variation;
+	/** Log for reporting. */
+	private static final Logger log = LoggerFactory.getLogger(ResourceReferenceRegistry.class);
 
-		public Key(String scope, String name, Locale locale, String style, String variation)
-		{
-			Args.notNull(scope, "scope");
-			Args.notNull(name, "name");
-
-			this.scope = scope.intern();
-			this.name = name.intern();
-			this.locale = locale;
-			this.style = style != null ? style.intern() : null;
-			this.variation = variation != null ? variation.intern() : null;
-		}
-
-		/**
-		 * @see java.lang.Object#equals(java.lang.Object)
-		 */
-		@Override
-		public boolean equals(Object obj)
-		{
-			if (this == obj)
-			{
-				return true;
-			}
-			if (obj instanceof Key == false)
-			{
-				return false;
-			}
-			Key that = (Key)obj;
-			return Objects.equal(scope, that.scope) && //
-				Objects.equal(name, that.name) && //
-				Objects.equal(locale, that.locale) && //
-				Objects.equal(style, that.style) && //
-				Objects.equal(variation, that.variation);
-		}
-
-		/**
-		 * @see java.lang.Object#hashCode()
-		 */
+	// Scan classes and its superclasses for static ResourceReference fields. For each
+	// RR field found, the callback method is called and the RR gets registered. It's kind of
+	// auto-register all RRs in your Component hierarchy.
+	// TODO wouldn't annotations be similar but more obvious to what happens?
+	private ClassScanner scanner = new ClassScanner()
+	{
 		@Override
-		public int hashCode()
+		boolean foundResourceReference(final ResourceReference reference)
 		{
-			return Objects.hashCode(scope, name, locale, style, variation);
+			// register the RR found (static field of Scope class)
+			return registerResourceReference(reference);
 		}
 	};
 
-	private final Map<Key, ResourceReference> map = new ConcurrentHashMap<Key, ResourceReference>();
-	private final Queue<Key> autoAddedQueue = new ConcurrentLinkedQueue<Key>();
+	// The Map (registry) maintaining the resource references
+	private final ConcurrentHashMap<Key, ResourceReference> map = Generics.newConcurrentHashMap();
 
+	// If combinations of paramaters (Key) have no registered resource reference yet, a default
+	// resource reference can be created and added to the registry. The following list keeps track
+	// of all auto added references.
+	private Queue<Key> autoAddedQueue;
+
+	// max entries. If the queue is full and new references are auto generated, references are
+	// removed starting with the first entry and unregistered from the registry.
 	private int autoAddedCapacity = 1000;
 
 	/**
@@ -94,177 +72,278 @@ public class ResourceReferenceRegistry
 	 */
 	public ResourceReferenceRegistry()
 	{
+		// Initial the auto-add list for a maximum of 1000 entries
+		setAutoAddedCapacity(autoAddedCapacity);
 	}
 
 	/**
 	 * Registers the given {@link ResourceReference}.
+	 * <p>
+	 * {@link ResourceReference#canBeRegistered()} must return <code>true</code>. Else, the resource
+	 * reference will not be registered.
 	 * 
 	 * @param reference
+	 * @return True, if the resource was registered successfully or has been registered previously
+	 *         already.
 	 */
-	public void registerResourceReference(ResourceReference reference)
+	public final boolean registerResourceReference(final ResourceReference reference)
+	{
+		return null != _registerResourceReference(reference);
+	}
+
+	/**
+	 * Registers the given {@link ResourceReference}.
+	 * <p>
+	 * {@link ResourceReference#canBeRegistered()} must return <code>true</code>. Else, the resource
+	 * reference will not be registered.
+	 * 
+	 * @param reference
+	 * @return True, if the resource was registered successfully or has been registered previously
+	 *         already.
+	 */
+	private final Key _registerResourceReference(final ResourceReference reference)
 	{
 		Args.notNull(reference, "reference");
 
 		if (reference.canBeRegistered())
 		{
-
-			Key key = new Key(reference.getScope().getName(), reference.getName(),
-				reference.getLocale(), reference.getStyle(), reference.getVariation());
-
+			Key key = new Key(reference);
 			if (map.containsKey(key) == false)
 			{
 				map.put(key, reference);
 			}
+
+			return key;
 		}
+
+		log.warn("Resource reference not added to registry. reference.canBeRegistered() == false");
+		return null;
 	}
 
 	/**
 	 * Unregisters the given {@link ResourceReference}.
 	 * 
 	 * @param reference
+	 * @return Null, if the registry did not contain an entry for the resource reference.
 	 */
-	public void unregisterResourceReference(ResourceReference reference)
+	public final ResourceReference unregisterResourceReference(final ResourceReference reference)
 	{
 		Args.notNull(reference, "reference");
 
-		Key key = new Key(reference.getScope().getName(), reference.getName(),
-			reference.getLocale(), reference.getStyle(), reference.getVariation());
-		map.remove(key);
+		Key key = new Key(reference);
+
+		// remove from registry
+		ResourceReference removed = map.remove(key);
+
+		// remove from auto-added list, in case the RR was auto-added
+		if (autoAddedQueue != null)
+		{
+			autoAddedQueue.remove(key);
+		}
+
+		return removed;
 	}
 
 	/**
+	 * Get a resource reference matching the parameters from the registry or if not found and
+	 * requested, create an default resource reference and add it to the registry.
+	 * <p>
+	 * Part of the search is scanning the class (scope) and it's superclass for static
+	 * ResourceReference fields. Found fields get registered automatically (but are different from
+	 * auto-generated ResourceReferences).
+	 * 
+	 * @see #createDefaultResourceReference(Class, String, Locale, String, String)
+	 * @see ClassScanner
 	 * 
 	 * @param scope
+	 *            The scope of resource reference (e.g. the Component's class)
 	 * @param name
+	 *            The name of resource reference (e.g. filename)
 	 * @param locale
+	 *            see Component
 	 * @param style
+	 *            see Component
 	 * @param variation
+	 *            see Component
 	 * @param strict
+	 *            If true, "weaker" combination of scope, name, locale etc. are not tested
 	 * @param createIfNotFound
-	 * @return
+	 *            If true a default resource reference is created if no entry can be found in the
+	 *            registry. The newly created resource reference will be added to the registry.
+	 * @return Either the resource reference found in the registry or, if requested, a resource
+	 *         reference automatically created based on the parameters provided. The automatically
+	 *         created resource reference will automatically be added to the registry.
 	 */
-	protected ResourceReference getResourceReference(Class<?> scope, String name, Locale locale,
-		String style, String variation, boolean strict, boolean createIfNotFound)
+	public final ResourceReference getResourceReference(final Class<?> scope, final String name,
+		final Locale locale, final String style, final String variation, final boolean strict,
+		final boolean createIfNotFound)
 	{
-		Key key = new Key(scope.getName(), name, locale, style, variation);
-		ResourceReference res = map.get(key);
-		if (strict)
-		{
-			if (res == null && createIfNotFound)
-			{
-				res = addDefaultResourceReference(scope, name, locale, style, variation);
-			}
-		}
-		if (strict || res != null)
-		{
-			return res;
-		}
-		else
+		ResourceReference resource = _getResourceReference(scope, name, locale, style, variation,
+			strict);
+
+		// Nothing found so far?
+		if (resource == null)
 		{
-			res = getResourceReference(scope, name, locale, style, null, true, false);
-			if (res == null)
+			// Scan the class (scope) and it's super classes for static fields containing resource
+			// references. Such resources are registered as normal resource reference (not
+			// auto-added).
+			if (scanner.scanClass(scope) > 0)
 			{
-				res = getResourceReference(scope, name, locale, null, variation, true, false);
+				// At least one new resource reference got registered => Search the registry again
+				resource = _getResourceReference(scope, name, locale, style, variation, strict);
 			}
-			if (res == null)
-			{
-				res = getResourceReference(scope, name, locale, null, null, true, false);
-			}
-			if (res == null)
-			{
-				res = getResourceReference(scope, name, null, style, variation, true, false);
-			}
-			if (res == null)
-			{
-				res = getResourceReference(scope, name, null, style, null, true, false);
-			}
-			if (res == null)
-			{
-				res = getResourceReference(scope, name, null, null, variation, true, false);
-			}
-			if (res == null)
-			{
-				res = getResourceReference(scope, name, null, null, null, true, false);
-			}
-			if (res == null && createIfNotFound)
+
+			// Still nothing found => Shall a new reference be auto-created?
+			if ((resource == null) && createIfNotFound)
 			{
-				res = addDefaultResourceReference(scope, name, locale, style, variation);
+				resource = addDefaultResourceReference(scope, name, locale, style, variation);
 			}
-			return res;
 		}
-	}
 
-	private final ClassScanner scanner = new ClassScanner()
-	{
-		@Override
-		void foundResourceReference(ResourceReference reference)
-		{
-			registerResourceReference(reference);
-		}
-	};
+		return resource;
+	}
 
 	/**
-	 * Looks up resource reference with specified attributes. If the reference is not found and
-	 * <code>strict</code> is set to <code>false</code>, result of
-	 * {@link #createDefaultResourceReference(Class, String, Locale, String)} is returned.
+	 * Get a resource reference matching the parameters from the registry.
 	 * 
 	 * @param scope
-	 *            mandatory parameter
+	 *            The scope of resource reference (e.g. the Component's class)
 	 * @param name
-	 *            mandatory parameter
+	 *            The name of resource reference (e.g. filename)
 	 * @param locale
+	 *            see Component
 	 * @param style
+	 *            see Component
 	 * @param variation
+	 *            see Component
 	 * @param strict
-	 *            if <code>strict</code> is <code>true</code> only resources that match exactly are
-	 *            returned. Otherwise if there is no resource registered that is an exact match,
-	 *            also resources with <code>null</code> style and locale are tried. If still no
-	 *            resource is found, result of
-	 *            {@link #createDefaultResourceReference(Class, String, Locale, String)} is
-	 *            returned.
-	 * @return {@link ResourceReference} or <code>null</code>
+	 *            If true, "weaker" combination of scope, name, locale etc. are not tested
+	 * @return Either the resource reference found in the registry or null if not found
 	 */
-	public ResourceReference getResourceReference(Class<?> scope, String name, Locale locale,
-		String style, String variation, boolean strict)
+	private final ResourceReference _getResourceReference(final Class<?> scope, final String name,
+		final Locale locale, final String style, final String variation, final boolean strict)
 	{
-		ResourceReference reference = getResourceReference(scope, name, locale, style, variation,
-			strict, false);
+		// Create a registry key containing all of the relevant attributes
+		Key key = new Key(scope.getName(), name, locale, style, variation);
 
-		if (reference == null)
+		// Get resource reference matching exactly the attrs provided
+		ResourceReference res = map.get(key);
+		if ((res != null) || strict)
 		{
-			scanner.scanClass(scope);
+			return res;
 		}
 
-		// try again, it might have been registered by scanner; create default one if necessary
-		reference = getResourceReference(scope, name, locale, style, variation, strict, true);
-
-		return reference;
+		res = _getResourceReference(scope, name, locale, style, null, true);
+		if (res == null)
+		{
+			res = _getResourceReference(scope, name, locale, null, variation, true);
+		}
+		if (res == null)
+		{
+			res = _getResourceReference(scope, name, locale, null, null, true);
+		}
+		if (res == null)
+		{
+			res = _getResourceReference(scope, name, null, style, variation, true);
+		}
+		if (res == null)
+		{
+			res = _getResourceReference(scope, name, null, style, null, true);
+		}
+		if (res == null)
+		{
+			res = _getResourceReference(scope, name, null, null, variation, true);
+		}
+		if (res == null)
+		{
+			res = _getResourceReference(scope, name, null, null, null, true);
+		}
+		return res;
 	}
 
-
+	/**
+	 * Creates a default resource reference and registers it.
+	 * 
+	 * @param scope
+	 * @param name
+	 * @param locale
+	 * @param style
+	 * @param variation
+	 * @return The default resource created
+	 */
 	private ResourceReference addDefaultResourceReference(Class<?> scope, String name,
 		Locale locale, String style, String variation)
 	{
+		// Can be subclassed to create other than PackagedResourceReference
 		ResourceReference reference = createDefaultResourceReference(scope, name, locale, style,
 			variation);
 
 		if (reference != null)
 		{
-			Key key = new Key(scope.getName(), name, locale, style, variation);
-			if (autoAddedQueue.size() > getAutoAddedCapacity())
+			// number of RRs which can be auto-added is restricted (cache size). Remove entries, and
+			// unregister excessive ones, if needed.
+			enforceAutoAddedCacheSize(getAutoAddedCapacity());
+
+			// Register the new RR
+			Key key = _registerResourceReference(reference);
+
+			// Add it to the auto-added list
+			if (autoAddedQueue != null)
+			{
+				autoAddedQueue.add(key);
+			}
+		}
+		else
+		{
+			log.warn("Asked to auto-create a ResourceReference, but ResourceReferenceRegistry.createDefaultResourceReference() return null. " +
+				" [scope: " +
+				scope.getName() +
+				"; name: " +
+				name +
+				"; locale: " +
+				locale +
+				"; style: " + style + "; variation: " + variation + "]");
+		}
+		return reference;
+	}
+
+	/**
+	 * The Number of RRs which can be auto-added is restricted (cache size). Remove entries, and
+	 * unregister excessive ones, if needed.
+	 * 
+	 * @param maxSize
+	 *            Remove all entries, head first, until auto-added cache is smaller than maxSize.
+	 */
+	private void enforceAutoAddedCacheSize(int maxSize)
+	{
+		if (autoAddedQueue != null)
+		{
+			while (autoAddedQueue.size() > maxSize)
 			{
+				// remove entry from auto-added list
 				Key first = autoAddedQueue.remove();
+
+				// remove entry from registry
 				map.remove(first);
 			}
-			autoAddedQueue.add(key);
-
-			registerResourceReference(reference);
 		}
-		return reference;
 	}
 
-	protected ResourceReference createDefaultResourceReference(Class<?> scope, String name,
-		Locale locale, String style, String variation)
+	/**
+	 * Creates a default resource reference in case no registry entry and it was requested to create
+	 * one.
+	 * <p>
+	 * A {@link PackageResourceReference} will be created by default
+	 * 
+	 * @param scope
+	 * @param name
+	 * @param locale
+	 * @param style
+	 * @param variation
+	 * @return The RR created or null if not successful
+	 */
+	protected ResourceReference createDefaultResourceReference(final Class<?> scope,
+		final String name, final Locale locale, final String style, final String variation)
 	{
 		if (PackageResource.exists(scope, name, locale, style, variation))
 		{
@@ -276,14 +355,148 @@ public class ResourceReferenceRegistry
 		}
 	}
 
-
-	public void setAutoAddedCapacity(int autoAddedCapacity)
+	/**
+	 * Set the cache size in number of entries
+	 * 
+	 * @param autoAddedCapacity
+	 *            A value < 0 will disable aging of auto-create resource references. They will be
+	 *            created, added to the registry and live their until manually removed or the
+	 *            application shuts down.
+	 */
+	public final void setAutoAddedCapacity(final int autoAddedCapacity)
 	{
-		this.autoAddedCapacity = autoAddedCapacity;
+		// Disable aging of auto-added references?
+		if (autoAddedCapacity < 0)
+		{
+			// unregister all auto-added references
+			clearAutoAddedEntries();
+
+			// disable aging from now on
+			autoAddedQueue = null;
+		}
+		else
+		{
+			this.autoAddedCapacity = autoAddedCapacity;
+
+			if (autoAddedQueue == null)
+			{
+				autoAddedQueue = new ConcurrentLinkedQueue<Key>();
+			}
+			else
+			{
+				// remove all extra entries if necessary
+				enforceAutoAddedCacheSize(autoAddedCapacity);
+			}
+		}
 	}
 
-	public int getAutoAddedCapacity()
+	/**
+	 * Gets cache size in number of entries
+	 * 
+	 * @return capacity
+	 */
+	public final int getAutoAddedCapacity()
 	{
 		return autoAddedCapacity;
 	}
+
+	/**
+	 * Unregisters all auto-added Resource References
+	 */
+	public final void clearAutoAddedEntries()
+	{
+		enforceAutoAddedCacheSize(0);
+	}
+
+	/**
+	 * @return Number of auto-generated (and registered) resource references.
+	 */
+	public final int getAutoAddedCacheSize()
+	{
+		return autoAddedQueue == null ? -1 : autoAddedQueue.size();
+	}
+
+	/**
+	 * @return Number of registered resource references (normal and auto-generated)
+	 */
+	public final int getSize()
+	{
+		return map.size();
+	}
+
+	/**
+	 * The registry essentially is a Map and needs a Key to store, search and retrieve entries.
+	 */
+	private static class Key
+	{
+		private final String scope;
+		private final String name;
+		private final Locale locale;
+		private final String style;
+		private final String variation;
+
+		/**
+		 * Construct.
+		 * 
+		 * @param reference
+		 */
+		public Key(final ResourceReference reference)
+		{
+			this(reference.getScope().getName(), reference.getName(), reference.getLocale(),
+				reference.getStyle(), reference.getVariation());
+		}
+
+		/**
+		 * Construct.
+		 * 
+		 * @param scope
+		 * @param name
+		 * @param locale
+		 * @param style
+		 * @param variation
+		 */
+		public Key(final String scope, final String name, final Locale locale, final String style,
+			final String variation)
+		{
+			Args.notNull(scope, "scope");
+			Args.notNull(name, "name");
+
+			this.scope = scope.intern();
+			this.name = name.intern();
+			this.locale = locale;
+			this.style = style != null ? style.intern() : null;
+			this.variation = variation != null ? variation.intern() : null;
+		}
+
+		/**
+		 * @see java.lang.Object#equals(java.lang.Object)
+		 */
+		@Override
+		public boolean equals(final Object obj)
+		{
+			if (this == obj)
+			{
+				return true;
+			}
+			if (obj instanceof Key == false)
+			{
+				return false;
+			}
+			Key that = (Key)obj;
+			return Objects.equal(scope, that.scope) && //
+				Objects.equal(name, that.name) && //
+				Objects.equal(locale, that.locale) && //
+				Objects.equal(style, that.style) && //
+				Objects.equal(variation, that.variation);
+		}
+
+		/**
+		 * @see java.lang.Object#hashCode()
+		 */
+		@Override
+		public int hashCode()
+		{
+			return Objects.hashCode(scope, name, locale, style, variation);
+		}
+	}
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java Sun Aug 29 15:49:02 2010
@@ -33,6 +33,8 @@ public class ResourceStreamResource exte
 {
 	private static final long serialVersionUID = 1L;
 
+	private static final Logger logger = LoggerFactory.getLogger(ResourceStreamResource.class);
+
 	private final IResourceStream stream;
 	private String fileName;
 	private ContentDisposition contentDisposition = ContentDisposition.INLINE;
@@ -139,6 +141,4 @@ public class ResourceStreamResource exte
 			logger.error("Couldn't close ResourceStream", e);
 		}
 	}
-
-	private static final Logger logger = LoggerFactory.getLogger(ResourceStreamResource.class);
 }

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/SharedResourceReference.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/SharedResourceReference.java?rev=990597&r1=990596&r2=990597&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/SharedResourceReference.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/SharedResourceReference.java Sun Aug 29 15:49:02 2010
@@ -48,7 +48,7 @@ public class SharedResourceReference ext
 		ResourceReference ref = Application.get()
 			.getResourceReferenceRegistry()
 			.getResourceReference(getScope(), getName(), getLocale(), getStyle(), getVariation(),
-				false);
+				false, true);
 
 		if (ref == null)
 		{