/* $Id: FromAnnotationsRuleSet.java 992746 2010-09-05 09:31:53Z simonetripodi $
*
* 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.commons.digester.annotations;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.RuleSet;
Since: 2.1
/**
* A {@link RuleSet} implementation that's able to inject {@link Rule}s created
* with the annotations analysis.
*
* @since 2.1
*/
public final class FromAnnotationsRuleSet implements RuleSet {
The data structure that stores the patterns/AnnotationRuleProvider
pairs. /**
* The data structure that stores the patterns/{@link AnnotationRuleProvider}
* pairs.
*/
private final Map<String, List<AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>>> rules =
new LinkedHashMap<String, List<AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>>>();
Maintains all the classes that this RuleSet produces mapping for.
/**
* Maintains all the classes that this RuleSet produces mapping for.
*/
private final Set<Class<?>> mappedClasses = new HashSet<Class<?>>();
private final DigesterLoader digesterLoader;
The namespace URI.
/**
* The namespace URI.
*/
private volatile String namespaceURI;
Created a new FromAnnotationsRuleSet
instance. Params: - digesterLoader – the parent DigesterLoader.
/**
* Created a new {@code FromAnnotationsRuleSet} instance.
*
* @param digesterLoader the parent DigesterLoader.
*/
protected FromAnnotationsRuleSet(DigesterLoader digesterLoader) {
this.digesterLoader = digesterLoader;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public void addRuleInstances(Digester digester) {
String pattern;
Rule rule;
for (Entry<String, List<AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>>> entry :
this.rules.entrySet()) {
pattern = entry.getKey();
for (AnnotationRuleProvider<Annotation, AnnotatedElement, Rule> provider : entry.getValue()) {
rule = provider.get();
if (this.namespaceURI != null) {
rule.setNamespaceURI(this.namespaceURI);
}
digester.addRule(pattern, rule);
}
}
}
Analyzes the target class and adds the AnnotationRuleProvider
s to this FromAnnotationsRuleSet
. Params: - target – the class has to be analyzed.
/**
* Analyzes the target class and adds the {@link AnnotationRuleProvider}s to
* this {@link FromAnnotationsRuleSet}.
*
* @param target the class has to be analyzed.
*/
public void addRules(Class<?> target) {
this.digesterLoader.addRulesTo(target, this);
}
Builds and register an AnnotationRuleProvider
for a specific pattern. Params: - pattern – the pattern has to be associated to the rule provider.
- klass – the
AnnotationRuleProvider
type has to be instantiated. - annotation – the current visited annotation.
- element – the current visited element.
Type parameters: - <T> – the
AnnotationRuleProvider
type.
/**
* Builds and register an {@link AnnotationRuleProvider} for a specific
* pattern.
*
* @param <T> the {@link AnnotationRuleProvider} type.
* @param pattern the pattern has to be associated to the rule provider.
* @param klass the {@link AnnotationRuleProvider} type has to be instantiated.
* @param annotation the current visited annotation.
* @param element the current visited element.
*/
public <A extends Annotation, E extends AnnotatedElement, R extends Rule, T extends AnnotationRuleProvider<A, E, R>>
void addRuleProvider(String pattern,
Class<T> klass,
A annotation,
E element) {
T annotationRuleProvider =
this.digesterLoader.getAnnotationRuleProviderFactory().newInstance(klass);
annotationRuleProvider.init(annotation, element);
this.addRuleProvider(pattern, annotationRuleProvider);
}
Register an AnnotationRuleProvider
for a specific pattern. Params: - pattern – the pattern has to be associated to the rule provider.
- ruleProvider – the provider that builds the digester rule.
/**
* Register an {@link AnnotationRuleProvider} for a specific pattern.
*
* @param pattern the pattern has to be associated to the rule provider.
* @param ruleProvider the provider that builds the digester rule.
*/
@SuppressWarnings("unchecked")
public void addRuleProvider(String pattern,
AnnotationRuleProvider<? extends Annotation, ? extends AnnotatedElement, ? extends Rule> ruleProvider) {
List<AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>> rules;
if (this.rules.containsKey(pattern)) {
rules = this.rules.get(pattern);
} else {
rules = new ArrayList<AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>>();
this.rules.put(pattern, rules);
}
rules.add((AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>) ruleProvider);
}
Retrieves a specific instance of the AnnotationRuleProvider
for the input pattern. Params: - pattern – the input pattern
- providerClass – the
AnnotationRuleProvider
class
Type parameters: - <T> – the
AnnotationRuleProvider
type
Returns: an AnnotationRuleProvider
for the input pattern if found, null otherwise.
/**
* Retrieves a specific instance of the {@link AnnotationRuleProvider} for
* the input pattern.
*
* @param <T> the {@link AnnotationRuleProvider} type
* @param pattern the input pattern
* @param providerClass the {@link AnnotationRuleProvider} class
* @return an {@link AnnotationRuleProvider} for the input pattern if found,
* null otherwise.
*/
public <T extends AnnotationRuleProvider<? extends Annotation, ? extends AnnotatedElement, ? extends Rule>>
T getProvider(String pattern, Class<T> providerClass) {
if (!this.rules.containsKey(pattern)) {
return null;
}
for (AnnotationRuleProvider<Annotation, AnnotatedElement, Rule> rule : this.rules.get(pattern)) {
if (providerClass.isInstance(rule)) {
return providerClass.cast(rule);
}
}
return null;
}
Add created AnnotationRuleProvider
s created in another analysis session. Params: - ruleSet – the
RuleSet
created in another analysis session.
/**
* Add created {@link AnnotationRuleProvider}s created in another analysis
* session.
*
* @param ruleSet the {@code RuleSet} created in another analysis session.
*/
public void addRulesProviderFrom(final FromAnnotationsRuleSet ruleSet) {
this.rules.putAll(ruleSet.getRules());
}
Checks if this RuleSet builds Digester mapping rules for the input type.
Params: - clazz – the input type.
Returns: true, if this RuleSet builds Digester mapping rules for the input
type, false otherwise.
/**
* Checks if this RuleSet builds Digester mapping rules for the input type.
*
* @param clazz the input type.
* @return true, if this RuleSet builds Digester mapping rules for the input
* type, false otherwise.
*/
protected boolean mapsClass(Class<?> clazz) {
return this.mappedClasses.contains(clazz);
}
Remember that this RuleSet is able to build Digester mapping rules for
the input type.
Params: - clazz – the input type.
/**
* Remember that this RuleSet is able to build Digester mapping rules for
* the input type.
*
* @param clazz the input type.
*/
protected void addMappedClass(Class<?> clazz) {
this.mappedClasses.add(clazz);
}
Returns the data structure the patterns/AnnotationRuleProvider
pairs. Returns: the data structure the patterns/AnnotationRuleProvider
pairs.
/**
* Returns the data structure the patterns/{@link AnnotationRuleProvider}
* pairs.
*
* @return the data structure the patterns/{@link AnnotationRuleProvider}
* pairs.
*/
private Map<String, List<AnnotationRuleProvider<Annotation, AnnotatedElement, Rule>>> getRules() {
return this.rules;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public String getNamespaceURI() {
return this.namespaceURI;
}
Sets the namespace URI that will be applied to all Rule instances
created from this RuleSet.
Params: - namespaceURI – the namespace URI that will be applied to all Rule
instances created from this RuleSet.
/**
* Sets the namespace URI that will be applied to all Rule instances
* created from this RuleSet.
*
* @param namespaceURI the namespace URI that will be applied to all Rule
* instances created from this RuleSet.
*/
public void setNamespaceURI(String namespaceURI) {
this.namespaceURI = namespaceURI;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "{ mappedClasses="
+ this.mappedClasses
+ ", rules="
+ this.rules.toString()
+ ", namespaceURI="
+ this.namespaceURI
+ " }";
}
}