All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.content.commons.mappingcontext.ContentPropertyMappingContextVisitor Maven / Gradle / Ivy

There is a newer version: 3.0.15
Show newest version
package org.springframework.content.commons.mappingcontext;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.content.commons.annotations.ContentId;
import org.springframework.content.commons.annotations.ContentLength;
import org.springframework.content.commons.annotations.MimeType;
import org.springframework.content.commons.annotations.OriginalFileName;
import org.springframework.util.StringUtils;

import lombok.Getter;

/**
 * Returns a map of "path"'s to content properties for the given class.
 *
 * @author warrenpa
 *
 */
@Getter
public class ContentPropertyMappingContextVisitor implements ClassVisitor {

    private static final Log LOGGER = LogFactory.getLog(ContentPropertyMappingContextVisitor.class);

    private Map, Boolean> looseModes = new HashMap<>();
    private Map> properties = new HashMap<>();
    private CharSequence keySeparator;
    private CharSequence contentPropertySeparator;

    public ContentPropertyMappingContextVisitor(CharSequence keySeparator, CharSequence contentPropertySeparator) {
        this.keySeparator = keySeparator;
        this.contentPropertySeparator = contentPropertySeparator;
    }

    public Map getProperties() {
        Map props = new HashMap<>();
        for (Map property : properties.values()) {
            props.putAll(property);
        }

        return props;
    }

    @Override
    public boolean visitClass(String path, Class klazz) {

        properties.put(key(path, klazz), new HashMap());

        int numContentIds = 0;
        for (Field field : klazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(ContentId.class)) {
                numContentIds++;
            }
        }
        looseModes.put(klazz, numContentIds == 1);
        LOGGER.trace(String.format("Loose mode enabled: %s", looseModes.get(klazz)));
        return true;
    }

    private String key(String path, Class klazz) {
        return klazz.getCanonicalName() + "." + path;
    }

    @Override
    public boolean visitClassEnd(String path, Class klazz) {

        boolean looseMode = looseModes.get(klazz);
        Map props = properties.get(key(path, klazz));

        if (looseMode && props.size() >= 1) {

            LOGGER.trace(String.format("Loose mode enabled. Collapsing properties for %s", klazz.getCanonicalName()));

            ContentProperty contentProperty = new ContentProperty();
            for (ContentProperty property : props.values()) {
                if (property.getContentIdPropertyPath() != null) {
                    contentProperty.setContentPropertyPath(property.getContentPropertyPath());
                    contentProperty.setContentIdPropertyPath(property.getContentIdPropertyPath());
                }
                if (property.getContentLengthPropertyPath() != null) {
                    contentProperty.setContentLengthPropertyPath(property.getContentLengthPropertyPath());
                }
                if (property.getMimeTypePropertyPath() != null) {
                    contentProperty.setMimeTypePropertyPath(property.getMimeTypePropertyPath());
                }
                if (property.getOriginalFileNamePropertyPath() != null) {
                    contentProperty.setOriginalFileNamePropertyPath(property.getOriginalFileNamePropertyPath());
                }
            }

            Map newClassProps = new HashMap();
            properties.put(key(path, klazz), newClassProps);

            if (isNotRootContentProperty(path)) {
                newClassProps.put(path, contentProperty);
            } else {
                newClassProps.put(contentProperty.getContentPropertyPath(), contentProperty);
            }
        }
        return true;
    }

    @Override
    public boolean visitField(String path, Class klazz, Field f) {
        LOGGER.trace(String.format("Visiting %s.%s", f.getDeclaringClass().getCanonicalName(), f.getName()));

        if (f.isAnnotationPresent(ContentId.class)) {
            LOGGER.trace(String.format("%s.%s is @ContentId", f.getDeclaringClass().getCanonicalName(), f.getName()));
            String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
            if (StringUtils.hasLength(propertyName)) {
                Map classProperties = properties.get(key(path, klazz));
                ContentProperty property = classProperties.get(propertyName);
                if (property == null) {
                    property = new ContentProperty();
                    classProperties.put(propertyName, property);
                }
                updateContentProperty(property::setContentPropertyPath, fullyQualify(path, this.propertyName(f.getName()), this.getContentPropertySeparator()));
                updateContentProperty(property::setContentIdPropertyPath, fullyQualify(path, f.getName(), this.getContentPropertySeparator()));
            }
        } else if (f.isAnnotationPresent(ContentLength.class)) {
            LOGGER.trace(String.format("%s.%s is @ContentLength", f.getDeclaringClass().getCanonicalName(), f.getName()));
            String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
            if (StringUtils.hasLength(propertyName)) {
                Map classProperties = properties.get(key(path, klazz));
                ContentProperty property = classProperties.get(propertyName);
                if (property == null) {
                    property = new ContentProperty();
                    classProperties.put(propertyName, property);
                }
                updateContentProperty(property::setContentLengthPropertyPath, fullyQualify(path, f.getName(), this.getContentPropertySeparator()));
            }
        } else if (f.isAnnotationPresent(MimeType.class)) {
            LOGGER.trace(String.format("%s.%s is @MimeType", f.getDeclaringClass().getCanonicalName(), f.getName()));
            String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
            if (StringUtils.hasLength(propertyName)) {
                Map classProperties = properties.get(key(path, klazz));
                ContentProperty property = classProperties.get(propertyName);
                if (property == null) {
                    property = new ContentProperty();
                    classProperties.put(propertyName, property);
                }
                updateContentProperty(property::setMimeTypePropertyPath, fullyQualify(path, f.getName(), this.getContentPropertySeparator()));
            }
        } else if (f.isAnnotationPresent(OriginalFileName.class)) {
            LOGGER.trace(String.format("%s.%s is @OriginalFileName", f.getDeclaringClass().getCanonicalName(), f.getName()));
            String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
            if (StringUtils.hasLength(propertyName)) {
                Map classProperties = properties.get(key(path, klazz));
                ContentProperty property = classProperties.get(propertyName);
                if (property == null) {
                    property = new ContentProperty();
                    classProperties.put(propertyName, property);
                }
                updateContentProperty(property::setOriginalFileNamePropertyPath, fullyQualify(path, f.getName(), this.getContentPropertySeparator()));
            }
        }

        return true;
    }

    protected void updateContentProperty(Consumer propertyPathField, String propertyPath) {
        propertyPathField.accept(propertyPath);
    }

    protected String fullyQualify(String path, String name, CharSequence separator) {
        String fqName = name;
        if (StringUtils.hasLength(path) ) {
            String propertyPath = path.replaceAll("/", separator.toString());
            fqName = String.format("%s%s%s", propertyPath, separator, fqName);
        }
        return fqName;
    }

    protected String propertyName(String name) {
        if (!StringUtils.hasLength(name)) {
            return name;
        }

        String propertyName = calculateName(name);
        if (propertyName != null) {
            return propertyName;
        }

        String[] segments = split(name);
        if (segments.length == 1) {
            return segments[0];
        }
        else {
            StringBuilder b = new StringBuilder();
            for (int i=0; i < segments.length - 1; i++) {
                b.append(segments[i]);
            }
            return b.toString();
        }
    }

    protected boolean isNotRootContentProperty(String path) {
        return StringUtils.hasLength(path);
    }

    protected String calculateName(String name) {
        Pattern p = Pattern.compile("^(.+)(Id|Len|Length|MimeType|Mimetype|ContentType|(?




© 2015 - 2024 Weber Informatics LLC | Privacy Policy