Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -298,6 +299,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