private ViewConfigNode findNodeWithClass(Class nodeClass, ViewConfigNode viewConfigNode) { if (viewConfigNode == null || nodeClass == null) { return null; } if (nodeClass.equals(viewConfigNode.getSource())) { return viewConfigNode; } return findNodeWithClass(nodeClass, viewConfigNode.getParent()); }
// the meta-data returned by this method is merged and potentially customized by a // ConfigPreProcessor private Annotation getFinalMetaDataFromNode( ViewConfigNode viewConfigNode, Annotation annotation) { Class<? extends Annotation> targetType = annotation.annotationType(); // skip @View and @Folder, because they get created dynamically to support their optional usage // the dynamic generation depends on the level and if it is a synthetic information if (View.class.equals(targetType) || Folder.class.equals(targetType)) { return annotation; } // skip aggregated meta-data, because it can't be replaced // (there is no info available about the instance which replaced the original one // which might be equivalent to the annotation passed to this method) ViewMetaData viewMetaData = annotation.annotationType().getAnnotation(ViewMetaData.class); if (viewMetaData == null) { return annotation; } Aggregated aggregated = viewMetaData.annotationType().getAnnotation(Aggregated.class); if (aggregated == null || aggregated.value()) { return annotation; } for (Annotation nodeMetaData : viewConfigNode.getMetaData()) { if (targetType.equals(nodeMetaData.annotationType())) { return nodeMetaData; } } return annotation; }
@Override public List<Annotation> resolveInheritedMetaData(ViewConfigNode viewConfigNode) { List<Annotation> inheritedAnnotations = new ArrayList<Annotation>(); Set<Class> processedTypes = new HashSet<Class>(); processedTypes.add(ViewConfig.class); // filter the base interface in any case Stack<Class> classesToAnalyze = new Stack<Class>(); addInterfaces( processedTypes, classesToAnalyze, viewConfigNode.getSource()); // don't add the page-class itself while (!classesToAnalyze.empty()) { Class currentClass = classesToAnalyze.pop(); if (processedTypes.contains(currentClass)) { continue; } processedTypes.add(currentClass); addInterfaces(processedTypes, classesToAnalyze, currentClass); // don't add the annotations of the final view-config class itself (we just need the inherited // annotations) if (ViewConfigUtils.isFolderConfig(currentClass)) { inheritedAnnotations.addAll(findViewMetaData(currentClass, viewConfigNode)); } Class nextClass = currentClass.getSuperclass(); if (nextClass != null && !Object.class.equals(nextClass)) { if (!processedTypes.contains(nextClass)) { classesToAnalyze.push(nextClass); } } } // add meta-data inherited via stereotypes on the node itself inheritedAnnotations.addAll(findViewMetaData(viewConfigNode.getSource(), viewConfigNode)); return inheritedAnnotations; }
// for a real implementation see e.g.: // org.apache.deltaspike.security.api.authorization.annotation.Secured // org.apache.deltaspike.jsf.api.config.view.controller.PageBean @Override public TestSecured beforeAddToConfig(TestSecured metaData, ViewConfigNode viewConfigNode) { List<CallbackDescriptor> descriptors = viewConfigNode.getCallbackDescriptors(TestSecured.class); if (descriptors.isEmpty()) // just for testing different constellations - usually not needed! { descriptors.add(new TestSecuredDescriptor(metaData.value(), DefaultCallback.class)); } return metaData; // no change needed }
@Test public void testSimpleMetaDataTreeWithMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig002.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig002.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); }
protected List<Annotation> findViewMetaData(Class currentClass, ViewConfigNode viewConfigNode) { // don't include meta-data from the node itself, because it would be stored as inherited // meta-data if (currentClass.equals(viewConfigNode.getSource())) { return Collections.emptyList(); } List<Annotation> result = new ArrayList<Annotation>(); for (Annotation annotation : currentClass.getAnnotations()) { Class<? extends Annotation> annotationClass = annotation.annotationType(); if (annotationClass.getName().startsWith("java")) { continue; } addViewMetaData(annotation, result); } result = tryToReplaceWithMergedMetaDataFromAncestor( currentClass, viewConfigNode.getParent(), result); return result; }