Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.apache.fesod.sheet.read.metadata.holder.xls.XlsReadWorkbookHolder;
import org.apache.fesod.sheet.read.metadata.holder.xlsx.XlsxReadWorkbookHolder;
import org.apache.fesod.sheet.support.ExcelTypeEnum;
import org.apache.fesod.sheet.util.AnnotatedClassUtils;
import org.apache.fesod.sheet.util.ClassUtils;
import org.apache.fesod.sheet.util.DateUtils;
import org.apache.fesod.sheet.util.FileUtils;
Expand Down Expand Up @@ -294,6 +295,7 @@ private void removeThreadLocalCache() {
NumberDataFormatterUtils.removeThreadLocalCache();
DateUtils.removeThreadLocalCache();
ClassUtils.removeThreadLocalCache();
AnnotatedClassUtils.removeThreadLocalCache();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.fesod.sheet.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Objects;

/**
* Descriptor abstract base class, providing generic annotation extraction logic.
*/
public abstract class AbstractAnnotatedElementDescriptor<E extends AnnotatedElement>
implements AnnotatedElementDescriptor<E> {

protected final E annotatedElement;
protected final AnnotationMap annotationMap;

protected AbstractAnnotatedElementDescriptor(E annotatedElement, AnnotationMap annotationMap) {
this.annotatedElement = annotatedElement;
this.annotationMap = annotationMap;
}

/**
* Get the original annotated element.
*/
@Override
public E getAnnotatedElement() {
return annotatedElement;
}

/**
* Get a wrapper for all annotation (include composable annotation) attribute key-value pairs.
*/
@Override
public AnnotationMap getAnnotationMap() {
return annotationMap;
}

/**
* Determine whether the specified annotation exists on this element.
*/
@Override
public boolean hasAnnotation(Class<? extends Annotation> type) {
return Objects.nonNull(annotationMap) && annotationMap.hasAnnotation(type);
}

/**
* Get the number of annotations.
*/
@Override
public int getAnnotationCount() {
return Objects.nonNull(annotationMap) ? annotationMap.size() : 0;
}

/**
* Get the attributes of a specified annotation.
*/
@Override
public AnnotationAttributes getAnnotation(Class<? extends Annotation> type) {
return Objects.nonNull(annotationMap) ? annotationMap.getAttributes(type) : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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.fesod.sheet.annotation;

import java.lang.annotation.Annotation;
import lombok.Getter;

/**
* A value object representing a declarative attribute aliasing instruction.
*/
@Getter
public class AliasFor {

/**
* The source annotation that declares the alias.
*/
private final Class<? extends Annotation> marked;

/**
* The target meta-annotation being aliased.
*/
private final Class<? extends Annotation> target;

/**
* The name of the attribute in the source annotation.
*/
private final String customAttribute;

/**
* The name of the attribute in the target annotation to be overridden.
*/
private final String attribute;

/**
* The value of the attribute in the target annotation to be overridden.
*/
private final Object value;

public AliasFor(
Class<? extends Annotation> marked, Class<? extends Annotation> target, String attribute, Object value) {
this(marked, target, attribute, attribute, value);
}

public AliasFor(
Class<? extends Annotation> marked,
Class<? extends Annotation> target,
String customAttribute,
String attribute,
Object value) {
this.marked = marked;
this.target = target;
this.customAttribute = customAttribute;
this.attribute = attribute;
this.value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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.fesod.sheet.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;

/**
* A generic interface for describing annotation elements.
*
* @param <E> The specific type of annotated element, such as {@code Class}, {@code Field}.
*/
public interface AnnotatedElementDescriptor<E extends AnnotatedElement> {

/**
* Get the original annotated element.
*/
E getAnnotatedElement();

/**
* Get a wrapper for all annotation (include composable annotation) attribute key-value pairs.
*/
AnnotationMap getAnnotationMap();

/**
* Determine whether the specified annotation exists on this element.
*/
boolean hasAnnotation(Class<? extends Annotation> type);

/**
* Get the number of annotations.
*/
int getAnnotationCount();

/**
* Get the attributes of a specified annotation.
*/
AnnotationAttributes getAnnotation(Class<? extends Annotation> type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.fesod.sheet.annotation;

import java.lang.reflect.Field;
import lombok.Getter;
import org.apache.commons.lang3.Validate;

/**
* A field-level annotation descriptor.
*/
public class AnnotatedFieldDescriptor extends AbstractAnnotatedElementDescriptor<Field> {

/**
* The field name matching cglib
*/
@Getter
private final String fieldName;

public AnnotatedFieldDescriptor(Field annotatedElement, String fieldName, AnnotationMap annotationMap) {
super(Validate.notNull(annotatedElement, "Field must not be null"), annotationMap);
this.fieldName = Validate.notBlank(fieldName, "Field name must not be blank");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.fesod.sheet.annotation;

/**
* A class-level annotation descriptor.
*/
public class AnnotatedTypeDescriptor extends AbstractAnnotatedElementDescriptor<Class<?>> {

public static final AnnotatedTypeDescriptor EMPTY = new AnnotatedTypeDescriptor(null, null);

public AnnotatedTypeDescriptor(Class<?> annotatedElement, AnnotationMap annotationMap) {
super(annotatedElement, annotationMap);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.fesod.sheet.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.Validate;

/**
* Implement key-value pairs of annotation attributes based on {@link LinkedHashMap}.
*/
@Getter
@EqualsAndHashCode(callSuper = true)
public class AnnotationAttributes extends LinkedHashMap<String, Object> {

private final Class<? extends Annotation> annotationType;
private final String annotationName;

@Setter
private int distance;

public AnnotationAttributes(Class<? extends Annotation> annotationType) {
this.annotationType = annotationType;
this.annotationName = annotationType.getCanonicalName();
this.distance = 0;
}

public AnnotationAttributes(Class<? extends Annotation> annotationType, Map<String, Object> attrs) {
super(attrs);
this.annotationType = annotationType;
this.annotationName = annotationType.getCanonicalName();
this.distance = 0;
}

public boolean isAnnotationTypeEqual(Class<? extends Annotation> annotationType) {
return this.annotationType.equals(annotationType);
}

@SuppressWarnings("unchecked")
public <T> T getRequiredAttribute(String attrName, Class<T> type) {
Validate.notBlank(attrName, "attributeName must not be null or blank");
Object result = get(attrName);

if (Objects.isNull(result)) {
throw new IllegalArgumentException(
String.format("Attribute '%s' not found for annotation '%s'", attrName, annotationName));
}
if (!type.isInstance(result)
&& type.isArray()
&& type.getComponentType().isInstance(result)) {
Object array = Array.newInstance(type.getComponentType(), 1);
Array.set(array, 0, result);
result = array;
}
if (!type.isInstance(result)) {
throw new IllegalArgumentException(String.format(
"Attribute '%s' is of type %s, but %s was expected for annotation [%s]",
attrName, result.getClass().getSimpleName(), type.getSimpleName(), annotationName));
}

return (T) result;
}
}
Loading
Loading