/*
* Copyright 2007 T-Rank AS
*
* 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 no.trank.openpipe.api.document;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import no.trank.openpipe.util.Iterators;
/**
* A basic implementation of {@link AnnotatedField}.
*
* @version $Revision$
*/
public class BaseAnnotatedField implements AnnotatedField {
private final Map<String, List<? extends Annotation>> annotations = new LinkedHashMap<String, List<? extends Annotation>>();
private String value;
/**
* Constructs a <tt>BaseAnnotatedField</tt> with a value of <tt>null</tt>.
*/
public BaseAnnotatedField() {
}
/**
* Constructs a <tt>BaseAnnotatedField</tt> with a value of <tt>value</tt>.
*/
public BaseAnnotatedField(String value) {
this.value = value;
}
/**
* Constructs a <tt>BaseAnnotatedField</tt> with a value of <tt>value</tt> and the given annotations.
*/
public BaseAnnotatedField(String value, Map<String, ? extends List<? extends Annotation>> annotations) {
this.value = value;
this.annotations.putAll(annotations);
}
@Override
public String getValue() {
return value;
}
/**
* Sets the value of this field.
*
* @param value the new value of this field.
*/
public void setValue(String value) {
this.value = value;
}
@Override
public Set<String> getAnnotationTypes() {
return Collections.unmodifiableSet(annotations.keySet());
}
@Override
public boolean add(String type, List<? extends Annotation> annotations) {
final boolean res = !this.annotations.containsKey(type);
if (res) {
set(type, annotations);
}
return res;
}
@Override
public void set(String type, List<? extends Annotation> annotations) {
this.annotations.put(type, Collections.unmodifiableList(annotations));
}
@Override
public ListIterator<ResolvedAnnotation> iterator(String type) {
final List<? extends Annotation> list = annotations.get(type);
if (list != null && !list.isEmpty()) {
return new BaseAnnotationIterator(value, list.listIterator());
}
return Iterators.emptyIterator();
}
private static class BaseAnnotationIterator implements ListIterator<ResolvedAnnotation> {
private final String fieldValue;
private final ListIterator<? extends Annotation> iterator;
private BaseAnnotationIterator(String value, ListIterator<? extends Annotation> it) {
fieldValue = value;
iterator = it;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public ResolvedAnnotation next() {
return toResolvedAnnotation(iterator.next());
}
private ResolvedAnnotation toResolvedAnnotation(Annotation annotation) {
if (ResolvedAnnotation.class.isAssignableFrom(annotation.getClass())) {
return (ResolvedAnnotation) annotation;
}
return new BaseResolvedAnnotation(annotation, fieldValue);
}
@Override
public boolean hasPrevious() {
return iterator.hasPrevious();
}
@Override
public ResolvedAnnotation previous() {
return toResolvedAnnotation(iterator.previous());
}
@Override
public int nextIndex() {
return iterator.nextIndex();
}
@Override
public int previousIndex() {
return iterator.previousIndex();
}
@Override
public void set(ResolvedAnnotation resolvedAnnotation) {
throw new UnsupportedOperationException();
}
@Override
public void add(ResolvedAnnotation resolvedAnnotation) {
throw new UnsupportedOperationException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
@Override
public String toString() {
return "BaseAnnotatedField{" +
"annotations=" + annotations +
", value='" + value + '\'' +
'}';
}
}