org.onehippo.forge.feed.util.ConversionUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.onehippo.forge.feed.util.ConversionUtil.java

Source

/*
 * Copyright 2013-2017 Hippo B.V. (http://www.onehippo.com)
 *
 * 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 org.onehippo.forge.feed.util;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.onehippo.forge.feed.api.FeedDescriptor;
import org.onehippo.forge.feed.api.FeedType;
import org.onehippo.forge.feed.api.annot.ContextTransformable;
import org.onehippo.forge.feed.api.annot.SyndicationElement;
import org.onehippo.forge.feed.api.annot.SyndicationRefs;
import org.onehippo.forge.feed.api.annot.noop.NoopConverter;
import org.onehippo.forge.feed.api.annot.noop.NoopTransformer;
import org.onehippo.forge.feed.api.transform.Converter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @version "$Id$"
 */
public class ConversionUtil {

    private static Logger log = LoggerFactory.getLogger(ConversionUtil.class);

    public static <T> T covertToAppropriateSyndicationFeed(final FeedDescriptor<T, ?> descriptor,
            final Object source, Object... context) {
        final T syndication = descriptor.createSyndication();
        return convertObject(syndication, source, descriptor.type(), context);
    }

    public static <E> E covertToAppropriateSyndicationEntry(final FeedDescriptor<?, E> descriptor,
            final Object source, Object... context) {
        final E entry = descriptor.createEntry();
        return convertObject(entry, source, descriptor.type(), context);
    }

    /**
     * TODO refactor complexity and enable caching
     *
     * @param destination
     * @param source
     * @param type
     * @param context
     * @param <T>
     * @return
     */
    private static <T> T convertObject(final T destination, final Object source, FeedType type, Object... context) {
        final Method[] methods = source.getClass().getMethods();
        for (Method method : methods) {
            final boolean refPresent = method.isAnnotationPresent(SyndicationRefs.class);
            if (refPresent || (method.isAnnotationPresent(SyndicationElement.class)
                    && method.getAnnotation(SyndicationElement.class).type().equals(type))) {
                SyndicationElement annotation = null;
                if (refPresent) {
                    final SyndicationElement[] value = method.getAnnotation(SyndicationRefs.class).value();
                    for (SyndicationElement element : value) {
                        if (element.type().equals(type)) {
                            annotation = element;
                            break;
                        }
                    }
                    if (annotation == null) {
                        continue;
                    }
                } else {
                    annotation = method.getAnnotation(SyndicationElement.class);
                }
                final String name = annotation.name();
                try {
                    final Object initValue = method.invoke(source);
                    Object value = initValue;
                    if (!(annotation.converter().isAssignableFrom(NoopConverter.class))) {
                        final Converter converter = annotation.converter().newInstance();
                        value = converter.convert(initValue);
                    }
                    if (!(annotation.transformer().isAssignableFrom(NoopTransformer.class)) && initValue != null) {
                        Map<Class, Object> contentMap = new HashMap<>();
                        for (Object o : context) {
                            contentMap.put(o.getClass(), o);
                        }
                        contentMap.put(initValue.getClass(), initValue);
                        final Class<?> transformer = annotation.transformer();
                        final Method[] transformerMethods = transformer.getMethods();
                        for (Method transformerMethod : transformerMethods) {
                            if (transformerMethod.isAnnotationPresent(ContextTransformable.class)) {
                                final Class<?>[] parameterTypes = transformerMethod.getParameterTypes();
                                List<Object> parameters = new ArrayList<>();
                                for (Class clazz : parameterTypes) {
                                    if (contentMap.containsKey(clazz)) {
                                        parameters.add(contentMap.get(clazz));
                                    } else {
                                        boolean found = false;
                                        for (Object obj : contentMap.values()) {
                                            if (clazz.isInstance(obj)) {
                                                parameters.add(obj);
                                                found = true;
                                                break;
                                            }
                                        }
                                        if (!found) {
                                            parameters.add(null);
                                        }
                                    }
                                }
                                if (Modifier.isStatic(transformerMethod.getModifiers())) {
                                    value = transformerMethod.invoke(null, parameters.toArray());
                                } else {
                                    value = transformerMethod.invoke(transformer.newInstance(),
                                            parameters.toArray());
                                }
                                break;
                            }
                        }

                    }
                    if (value != null) {
                        BeanUtils.setProperty(destination, name, value);
                    }
                } catch (Exception e) {
                    log.error(String.format("exception happened while trying to revolve syndication %s", name), e);
                }

            }
        }
        return destination;
    }

}