
org.simpleframework.xml.convert.ScannerBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simple-xml Show documentation
Show all versions of simple-xml Show documentation
Simple is a high performance XML serialization and configuration framework for Java
/*
* ScannerBuilder.java January 2010
*
* Copyright (C) 2010, Niall Gallagher
*
* 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.simpleframework.xml.convert;
import java.lang.annotation.Annotation;
import org.simpleframework.xml.util.ConcurrentCache;
/**
* The ScannerBuilder
is used to build and cache each
* scanner requested. Building and caching scanners ensures that
* annotations can be acquired from a class quickly as a scan only
* needs to be performed once. Each scanner built scans the class
* provided as well as all the classes in the hierarchy.
*
* @author Niall Gallagher
*
* @see org.simpleframework.xml.convert.ConverterScanner
*/
class ScannerBuilder extends ConcurrentCache {
/**
* Constructor for the ScannerBuilder
object. This
* will create a builder for annotation scanners. Each of the
* scanners build will be cached internally to ensure that any
* further requests for the scanner are quicker.
*/
public ScannerBuilder() {
super();
}
/**
* This is used to build Scanner
objects that are
* used to scan the provided class for annotations. Each scanner
* instance is cached once created to ensure it does not need to
* be built twice, which improves the performance.
*
* @param type this is the type to build a scanner object for
*
* @return this will return a scanner instance for the given type
*/
public Scanner build(Class> type) {
Scanner scanner = get(type);
if(scanner == null) {
scanner = new Entry(type);
put(type, scanner);
}
return scanner;
}
/**
* The Entry
object represents a scanner that is
* used to scan a specified type for annotations. All annotations
* scanned from the type are cached so that they do not need to
* be looked up twice. This ensures scanning is much quicker.
*
* @author Niall Gallagher
*/
private static class Entry extends ConcurrentCache implements Scanner {
/**
* This class is the subject for all annotation scans performed.
*/
private final Class root;
/**
* Constructor for the Entry
object is used to
* create a scanner that will scan the specified type. All
* annotations that are scanned are cached to ensure that they
* do not need to be looked up twice. This ensures that scans
* are quicker including ones that result in null.
*
* @param root this is the root class that is to be scanned
*/
public Entry(Class root) {
this.root = root;
}
/**
* This method will scan a class for the specified annotation.
* If the annotation is found on the class, or on one of the
* super types then it is returned. All scans will be cached
* to ensure scanning is only performed once.
*
* @param type this is the annotation type to be scanned for
*
* @return this will return the annotation if it is found
*/
public T scan(Class type) {
if(!contains(type)) {
T value = find(type);
if(type != null && value != null) {
put(type, value);
}
}
return (T)get(type);
}
/**
* This method will scan a class for the specified annotation.
* If the annotation is found on the class, or on one of the
* super types then it is returned. All scans will be cached
* to ensure scanning is only performed once.
*
* @param label this is the annotation type to be scanned for
*
* @return this will return the annotation if it is found
*/
private T find(Class label) {
Class> type = root;
while(type != null) {
T value = type.getAnnotation(label);
if(value != null) {
return value;
}
type = type.getSuperclass();
}
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy