Issue: 841 @ResourceDependency, library=="this", script backed annotations
This used to work but has been broken for a long time. I found some
time to investigate it today. The problem is that the logic that
converts a library name of "this" into the library name of the current
composite component was somehow lost in the case of a script backed
component.
This changebundle hacks this through by pushing the top level component
down to ResourceDependencyHandler where that map is created which is
later used to create the resource.
SECTION: changes
M jsf-ri/src/com/sun/faces/application/annotation/Scanner.java
M jsf-ri/src/com/sun/faces/application/annotation/ListenerForScanner.java
- Add params to scan() method.
M jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyScanner.java
- Add params to scan() method.
- pass params to ResourceDependencyHandler ctor
M jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyHandler.java
- take params in ctor, store as ivar
- in map building code, leverage params to get the component that is the
top level component in the composite component. As in other cases
where "this" is turned into the current library name, this information
comes from the Resource entry in the top level components attr map.
M jsf-ri/src/com/sun/faces/application/annotation/AnnotationManager.java
- pass through params
M jsf-ri/src/com/sun/faces/application/ApplicationImpl.java
- IMPORTANT, this must be in the spec as well.
Make sure that the thing that starts the annotation processing on the
script based component has access to the resource from which the top
level component was created.
SECTION: diffs
Index: jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyScanner.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyScanner.java (revision 5688)
+++ jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyScanner.java (working copy)
@@ -23,7 +23,7 @@
}
- public RuntimeAnnotationHandler scan(Class<?> clazz) {
+ public RuntimeAnnotationHandler scan(Class<?> clazz, Object... params) {
Util.notNull("clazz", clazz);
@@ -34,7 +34,7 @@
} else {
ResourceDependencies deps = clazz.getAnnotation(ResourceDependencies.class);
if (deps != null) {
- handler = new ResourceDependencyHandler(deps.value());
+ handler = new ResourceDependencyHandler(deps.value(), params);
}
}
Index: jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyHandler.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyHandler.java (revision 5688)
+++ jsf-ri/src/com/sun/faces/application/annotation/ResourceDependencyHandler.java (working copy)
@@ -10,6 +10,7 @@
import javax.faces.context.FacesContext;
import com.sun.faces.el.ELUtils;
+import javax.faces.application.Resource;
/**
* {_at_link RuntimeAnnotationHandler} responsible for processing {_at_link ResourceDependency} annotations.
@@ -18,12 +19,14 @@
private ResourceDependency[] dependencies;
private Map<ResourceDependency,Expressions> expressionsMap;
+ private Object[] params;
// ------------------------------------------------------------ Constructors
- public ResourceDependencyHandler(ResourceDependency[] dependencies) {
+ public ResourceDependencyHandler(ResourceDependency[] dependencies, Object... params) {
+ this.params = params;
this.dependencies = dependencies;
expressionsMap = new HashMap<ResourceDependency,Expressions>(dependencies.length, 1.0f);
@@ -32,6 +35,19 @@
exprs.name = dep.name();
String lib = dep.library();
if (lib.length() > 0) {
+ // Take special action to resolve the "this" library name
+ if ("this".equals(lib)) {
+ UIComponent currentComponent = (UIComponent) params[0];
+ Resource componentResource = (Resource)
+ currentComponent.getAttributes().get(Resource.COMPONENT_RESOURCE_KEY);
+ if (null != componentResource) {
+ String libName = null;
+ if (null != (libName = componentResource.getLibraryName())) {
+ lib = libName;
+ }
+ }
+ }
+
exprs.library = lib;
}
String tgt = dep.target();
Index: jsf-ri/src/com/sun/faces/application/annotation/AnnotationManager.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/annotation/AnnotationManager.java (revision 5688)
+++ jsf-ri/src/com/sun/faces/application/annotation/AnnotationManager.java (working copy)
@@ -243,7 +243,8 @@
ProcessingTarget processingTarget,
Object... params) {
- Map<Class<? extends Annotation>, RuntimeAnnotationHandler> map = getHandlerMap(targetClass, processingTarget);
+ Map<Class<? extends Annotation>, RuntimeAnnotationHandler> map =
+ getHandlerMap(targetClass, processingTarget, params);
if (map != null && !map.isEmpty()) {
for (RuntimeAnnotationHandler handler : map.values()) {
handler.apply(ctx, params);
@@ -261,14 +262,15 @@
* value
*/
private Map<Class<? extends Annotation>, RuntimeAnnotationHandler> getHandlerMap(Class<?> targetClass,
- ProcessingTarget processingTarget) {
+ ProcessingTarget processingTarget,
+ Object... params) {
while (true) {
Future<Map<Class<? extends Annotation>, RuntimeAnnotationHandler>> f =
cache.get(targetClass);
if (f == null) {
ProcessAnnotationsTask t =
- new ProcessAnnotationsTask(targetClass, processingTarget.scanners);
+ new ProcessAnnotationsTask(targetClass, processingTarget.scanners, params);
FutureTask<Map<Class<? extends Annotation>, RuntimeAnnotationHandler>> ft =
new FutureTask<Map<Class<? extends Annotation>, RuntimeAnnotationHandler>>(t);
f = cache.putIfAbsent(targetClass, ft);
@@ -317,16 +319,18 @@
Collections.EMPTY_MAP;
private Class<?> clazz;
private Scanner[] scanners;
+ private Object[] params;
// -------------------------------------------------------- Constructors
- public ProcessAnnotationsTask(Class<?> clazz, Scanner[] scanners) {
+ public ProcessAnnotationsTask(Class<?> clazz, Scanner[] scanners, Object... params) {
this.clazz = clazz;
this.scanners = scanners;
+ this.params = params;
}
@@ -338,7 +342,7 @@
Map<Class<? extends Annotation>, RuntimeAnnotationHandler> map = null;
for (Scanner scanner : scanners) {
- RuntimeAnnotationHandler handler = scanner.scan(clazz);
+ RuntimeAnnotationHandler handler = scanner.scan(clazz, params);
if (handler != null) {
if (map == null) {
map = new HashMap<Class<? extends Annotation>, RuntimeAnnotationHandler>(2, 1.0f);
Index: jsf-ri/src/com/sun/faces/application/annotation/ListenerForScanner.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/annotation/ListenerForScanner.java (revision 5688)
+++ jsf-ri/src/com/sun/faces/application/annotation/ListenerForScanner.java (working copy)
@@ -23,7 +23,7 @@
}
- public RuntimeAnnotationHandler scan(Class<?> clazz) {
+ public RuntimeAnnotationHandler scan(Class<?> clazz, Object... params) {
Util.notNull("clazz", clazz);
Index: jsf-ri/src/com/sun/faces/application/annotation/Scanner.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/annotation/Scanner.java (revision 5688)
+++ jsf-ri/src/com/sun/faces/application/annotation/Scanner.java (working copy)
@@ -23,10 +23,11 @@
/**
* Scan the target class for the {_at_link java.lang.annotation.Annotation}s this scanner handles.
* @param clazz the target class
+ * @param params one or more parameters, from {_at_link AnnotationManager#applyAnnotations}
* @return a new {_at_link RuntimeAnnotationHandler} instance capable of processing the
* annotations defined on this class. If no relevant {_at_link java.lang.annotation.Annotation}s
* are found, return <code>null</code>.
*/
- public RuntimeAnnotationHandler scan(Class<?> clazz);
+ public RuntimeAnnotationHandler scan(Class<?> clazz, Object... params);
}
Index: jsf-ri/src/com/sun/faces/application/ApplicationImpl.java
===================================================================
--- jsf-ri/src/com/sun/faces/application/ApplicationImpl.java (revision 5688)
+++ jsf-ri/src/com/sun/faces/application/ApplicationImpl.java (working copy)
@@ -902,14 +902,14 @@
// Step 2. If that didn't work, if a script based resource can be
- // found for the componentResource,
+ // found for the scriptComponentResource,
// see if a component can be generated from it
if (null == result) {
Resource scriptComponentResource = pdl.getScriptComponentResource(context, componentResource);
if (null != scriptComponentResource) {
result = createComponentFromScriptResource(context,
- scriptComponentResource);
+ scriptComponentResource, componentResource);
}
}
@@ -1597,11 +1597,12 @@
private UIComponent createComponentFromScriptResource(FacesContext context,
+ Resource scriptComponentResource,
Resource componentResource) {
UIComponent result = null;
- String className = componentResource.getResourceName();
+ String className = scriptComponentResource.getResourceName();
int lastDot = className.lastIndexOf('.');
className = className.substring(0, lastDot);
@@ -1624,6 +1625,8 @@
}
if (result != null) {
+ result.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY,
+ componentResource);
associate.getAnnotationManager()
.applyComponentAnnotations(context, result);
}
--