blob: 47efce5b7521408959d2128484bd790d18e44580 [file] [log] [blame]
/*
* 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.felix.scrplugin.tags.annotation.defaulttag;
import java.util.*;
import org.apache.felix.scr.annotations.*;
import org.apache.felix.scrplugin.Constants;
import org.apache.felix.scrplugin.tags.JavaClassDescription;
import org.apache.felix.scrplugin.tags.JavaField;
import org.apache.felix.scrplugin.tags.annotation.AbstractTag;
import org.apache.felix.scrplugin.tags.annotation.Util;
import com.thoughtworks.qdox.model.Annotation;
/**
* Description of a java tag for components.
*/
public class PropertyTag extends AbstractTag {
protected final Property annotation;
/**
* @param annotation Annotation
* @param desc Description
*/
public PropertyTag(final Annotation annotation, final JavaClassDescription desc, JavaField field) {
super(annotation, desc, field);
this.annotation = new Property() {
public int cardinality() {
return Util.getIntValue(annotation, "cardinality", Property.class);
}
public String description() {
return Util.getStringValue(annotation, desc, "description", Property.class);
}
public String label() {
return Util.getStringValue(annotation, desc, "label", Property.class);
}
public String name() {
return Util.getStringValue(annotation, desc, "name", Property.class);
}
public PropertyOption[] options() {
final Object obj = annotation.getNamedParameter("options");
if ( obj != null ) {
if ( obj instanceof Annotation ) {
final Annotation annotation = (Annotation)obj;
return new PropertyOption[] {new PropertyOptionImpl(annotation, desc)};
}
@SuppressWarnings("unchecked")
final List<Annotation> annotations = (List<Annotation>) obj;
PropertyOption[] options = new PropertyOption[annotations.size()];
for (int index = 0; index < options.length; index++) {
final Annotation propAnnotation = annotations.get(index);
options[index] = new PropertyOptionImpl(propAnnotation, desc);
}
return options;
}
try {
return (PropertyOption[]) Property.class.getMethod("options").getDefaultValue();
} catch( NoSuchMethodException mnfe) {
// we ignore this
return null;
}
}
public boolean propertyPrivate() {
return Util.getBooleanValue(annotation, "propertyPrivate", Property.class);
}
public String[] value() {
// value property can be used as String[] or String property
return Util.getStringValues(annotation, desc, "value");
}
public Class<?>[] classValue() {
return Util.getClassArrayValue(annotation, "classValue", Property.class);
}
public boolean[] boolValue() {
return Util.getBooleanValues(annotation, desc, "boolValue");
}
public byte[] byteValue() {
return Util.getByteValues(annotation, desc, "byteValue");
}
public char[] charValue() {
return Util.getCharValues(annotation, desc, "charValue");
}
public double[] doubleValue() {
return Util.getDoubleValues(annotation, desc, "doubleValue");
}
public float[] floatValue() {
return Util.getFloatValues(annotation, desc, "floatValue");
}
public int[] intValue() {
return Util.getIntValues(annotation, desc, "intValue");
}
public long[] longValue() {
return Util.getLongValues(annotation, desc, "longValue");
}
public short[] shortValue() {
return Util.getShortValues(annotation, desc, "shortValue");
}
public PropertyUnbounded unbounded() {
return Util.getEnumValue(annotation, "unbounded", PropertyUnbounded.class, Property.class);
}
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return null;
}
};
}
@Override
public String getName() {
return Constants.PROPERTY;
}
@Override
public String getSourceName() {
return "Property";
}
@Override
public Map<String, String> createNamedParameterMap() {
final Map<String, String> map = new LinkedHashMap<String, String>();
map.put(Constants.PROPERTY_NAME, emptyToNull(this.annotation.name()));
map.put(Constants.PROPERTY_LABEL, emptyToNull(this.annotation.label()));
map.put(Constants.PROPERTY_DESCRIPTION, emptyToNull(this.annotation.description()));
String type = null;
Object[] values = this.annotation.value();
// we now check all options
if (values == null || values.length == 0 ) {
final Class<?>[] classValues = this.annotation.classValue();
if ( classValues == null || classValues.length == 0 ) {
long[] lValues = this.annotation.longValue();
if ( lValues == null || lValues.length == 0 ) {
double[] dValues = this.annotation.doubleValue();
if ( dValues == null || dValues.length == 0 ) {
float[] fValues = this.annotation.floatValue();
if ( fValues == null || fValues.length == 0 ) {
int[] iValues = this.annotation.intValue();
if ( iValues == null || iValues.length == 0 ) {
byte[] byteValues = this.annotation.byteValue();
if ( byteValues == null || byteValues.length == 0 ) {
char[] cValues = this.annotation.charValue();
if ( cValues == null || cValues.length == 0 ) {
boolean[] boolValues = this.annotation.boolValue();
if ( boolValues == null || boolValues.length == 0 ) {
short[] sValues = this.annotation.shortValue();
if ( sValues != null && sValues.length != 0 ) {
values = new Object[sValues.length];
for(int i=0;i<sValues.length;i++) {
values[i] = sValues[i];
}
type = "Short";
}
} else {
values = new Object[boolValues.length];
for(int i=0;i<boolValues.length;i++) {
values[i] = boolValues[i];
}
type = "Boolean";
}
} else {
values = new Object[cValues.length];
for(int i=0;i<cValues.length;i++) {
values[i] = cValues[i];
}
type = "Char";
}
} else {
values = new Object[byteValues.length];
for(int i=0;i<byteValues.length;i++) {
values[i] = byteValues[i];
}
type = "Byte";
}
} else {
values = new Object[iValues.length];
for(int i=0;i<iValues.length;i++) {
values[i] = iValues[i];
}
type = "Integer";
}
} else {
values = new Object[fValues.length];
for(int i=0;i<fValues.length;i++) {
values[i] = fValues[i];
}
type = "Float";
}
} else {
values = new Object[dValues.length];
for(int i=0;i<dValues.length;i++) {
values[i] = dValues[i];
}
type = "Double";
}
} else {
values = new Object[lValues.length];
for(int i=0;i<lValues.length;i++) {
values[i] = lValues[i];
}
type = "Long";
}
} else {
values = new Object[classValues.length];
for(int i=0;i<classValues.length;i++) {
values[i] = classValues[i].getName();
}
type = "String";
}
} else {
type = "String";
}
if ( values != null && values.length > 0 ) {
map.put(Constants.PROPERTY_TYPE, type);
if (values.length == 1) {
map.put(Constants.PROPERTY_VALUE, values[0].toString());
} else {
for (int i = 0; i < values.length; i++) {
map.put(Constants.PROPERTY_MULTIVALUE_PREFIX + '.' + i, values[i].toString());
}
}
}
// cardinality handling
final PropertyUnbounded pu = this.annotation.unbounded();
if ( pu != PropertyUnbounded.DEFAULT ) {
if ( pu == PropertyUnbounded.ARRAY ) {
map.put(Constants.PROPERTY_CARDINALITY, "+");
} else {
map.put(Constants.PROPERTY_CARDINALITY, "-");
}
} else if (this.annotation.cardinality() != 0) {
if ( this.annotation.cardinality() == Integer.MAX_VALUE ) {
map.put(Constants.PROPERTY_CARDINALITY, "+");
} else if ( this.annotation.cardinality() == Integer.MIN_VALUE ) {
map.put(Constants.PROPERTY_CARDINALITY, "-");
} else {
map.put(Constants.PROPERTY_CARDINALITY, String.valueOf(this.annotation.cardinality()));
}
}
map.put(Constants.PROPERTY_PRIVATE, String.valueOf(this.annotation.propertyPrivate()));
return map;
}
@Override
public String[] getParameters() {
List<String> parameters = new ArrayList<String>();
String[] defaultParameters = super.getParameters();
if (defaultParameters != null) {
parameters.addAll(Arrays.asList(defaultParameters));
}
// if defined: add options as parameters to the end of parameter list
// (strange parsing due to qdox tag restrictions...)
if (this.annotation.options().length > 0) {
parameters.add(Constants.PROPERTY_OPTIONS);
for (PropertyOption option : this.annotation.options()) {
parameters.add(option.name());
parameters.add("=");
parameters.add(option.value());
}
}
return parameters.toArray(new String[parameters.size()]);
}
protected static class PropertyOptionImpl implements PropertyOption {
private final Annotation annotation;
private final JavaClassDescription description;
public PropertyOptionImpl(final Annotation annotation,
final JavaClassDescription desc) {
this.annotation = annotation;
this.description = desc;
}
public String name() {
final String[] names = Util.getAnnotationValues(annotation, "name", description);
if ( names != null && names.length > 0 ) {
return names[0];
}
return null;
}
public String value() {
final String[] values = Util.getAnnotationValues(annotation, "value", description);
if ( values != null && values.length > 0 ) {
return values[0];
}
return null;
}
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return PropertyOption.class;
}
}
}