org.openengsb.core.services.internal.security.EntryUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.openengsb.core.services.internal.security.EntryUtils.java

Source

/**
 * Licensed to the Austrian Association for Software Tool Integration (AASTI)
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. The AASTI 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.openengsb.core.services.internal.security;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ClassUtils;
import org.openengsb.core.api.OsgiUtilsService;
import org.openengsb.core.api.security.model.Permission;
import org.openengsb.core.services.internal.security.model.BeanData;
import org.openengsb.core.services.internal.security.model.EntryElement;
import org.openengsb.core.services.internal.security.model.EntryValue;
import org.openengsb.core.util.BeanUtilsExtended;
import org.openengsb.core.util.FilterUtils;
import org.openengsb.labs.delegation.service.ClassProvider;
import org.openengsb.labs.delegation.service.Constants;
import org.osgi.framework.Filter;
import org.springframework.util.ReflectionUtils;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ComputationException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Provides util-functions for handling multi-valued attributes, used to save {@link BeanData}.
 *
 * For more details on the conversion from a bean to {@link BeanData} and vice versa, see {@link BeanData}.
 */
public final class EntryUtils {

    private static OsgiUtilsService utilsService;

    /**
     * converts a list of {@link EntryElement} back to a list containing the original java objects.
     */
    public static List<Object> convertAllEntryElementsToObject(List<EntryElement> value) {
        return Lists.transform(value, new EntryElementParserFunction());
    }

    private static class EntryElementParserFunction implements Function<EntryElement, Object> {
        @Override
        public Object apply(EntryElement input) {
            Class<?> elementType;
            try {
                elementType = Class.forName(input.getType());
            } catch (ClassNotFoundException e) {
                throw new ComputationException(e);
            }
            try {
                Constructor<?> constructor = elementType.getConstructor(String.class);
                return constructor.newInstance(input.getValue());
            } catch (Exception e) {
                ReflectionUtils.handleReflectionException(e);
                throw new ComputationException(e);
            }
        }

    }

    /**
     * converts all Objects to {@link EntryElement}s to their Bean-data can be saved to the DB
     */
    public static List<EntryElement> makeEntryElementList(Object... value) {
        List<EntryElement> valueElements = new ArrayList<EntryElement>();
        for (Object o : value) {
            Class<?> type = ClassUtils.primitiveToWrapper(o.getClass());
            EntryElement entryElement = new EntryElement(type.getName(), o.toString());
            valueElements.add(entryElement);
        }
        return valueElements;
    }

    /**
     * Takes any bean Object and converts it to a Map of {@link EntryValue} so the beandata can be saved to the DB.
     */
    public static Map<String, EntryValue> convertBeanToEntryMap(Object bean) {
        Map<String, Object> buildAttributeValueMap = BeanUtilsExtended.buildObjectAttributeMap(bean);
        return Maps.transformEntries(buildAttributeValueMap, new ObjectToEntryValueTransformer());
    }

    private static final class ObjectToEntryValueTransformer
            implements Maps.EntryTransformer<String, Object, EntryValue> {
        @SuppressWarnings("unchecked")
        @Override
        public EntryValue transformEntry(String key, Object value) {
            if (value == null) {
                return null;
            }
            if (value instanceof Collection) {
                return new EntryValue(key, convertAllObjectsToEntryElements((Collection<Object>) value));
            }
            if (value.getClass().isArray()) {
                return new EntryValue(key, convertAllObjectsToEntryElements((Object[]) value));
            }
            return new EntryValue(key, Arrays.asList(transformObjectToEntryElement(value)));
        }
    }

    /**
     * works similar to {@link EntryUtils#makeEntryElementList(Object...)}, but takes a list as argument
     */
    private static List<EntryElement> convertAllObjectsToEntryElements(Collection<? extends Object> collection) {
        List<EntryElement> result = new ArrayList<EntryElement>();
        for (Object o : collection) {
            result.add(transformObjectToEntryElement(o));
        }
        return result;
    }

    private static List<EntryElement> convertAllObjectsToEntryElements(Object[] array) {
        List<EntryElement> result = new ArrayList<EntryElement>();
        for (Object o : array) {
            result.add(transformObjectToEntryElement(o));
        }
        return result;
    }

    private static EntryElement transformObjectToEntryElement(Object o) {
        return new EntryElement(o.getClass().getName(), o.toString());
    }

    /**
     * converts a Collection of {@link BeanData} to their original {@link Object} form.
     */
    public static <T> Collection<T> convertAllBeanDataToObjects(Collection<? extends BeanData> data) {
        return Collections2.transform(data, new BeanDataToObjectFunction<T>());
    }

    private static final class BeanDataToObjectFunction<T> implements Function<BeanData, T> {
        @Override
        public T apply(BeanData input) {
            return convertBeanDataToObject(input);
        }
    }

    @SuppressWarnings("unchecked")
    private static <T> T convertBeanDataToObject(BeanData input) {
        Class<?> permType;
        try {
            permType = findPermissionClass(input.getType());
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("permission-type could not be found " + input.getType(), e);
        }
        Map<String, Object> attributeValues = convertEntryMapToAttributeMap(input.getAttributes());
        return (T) BeanUtilsExtended.createBeanFromAttributeMap(permType, attributeValues);
    }

    @SuppressWarnings("unchecked")
    private static Class<? extends Permission> findPermissionClass(String name) throws ClassNotFoundException {
        Filter filter = FilterUtils.makeFilter(ClassProvider.class,
                String.format("(%s=%s)", Constants.PROVIDED_CLASSES_KEY, name));
        ClassProvider provider = utilsService.getOsgiServiceProxy(filter, ClassProvider.class);
        return (Class<? extends Permission>) provider.loadClass(name);
    }

    private static Map<String, Object> convertEntryMapToAttributeMap(Map<String, EntryValue> entryMap) {
        return Maps.transformEntries(entryMap, new EntryValueToObjectTransformer());
    }

    private static final class EntryValueToObjectTransformer
            implements Maps.EntryTransformer<String, EntryValue, Object> {
        @Override
        public Object transformEntry(String key, EntryValue value) {
            List<Object> objects = Lists.transform(value.getValue(), new EntryElementParserFunction());
            if (objects.isEmpty()) {
                return null;
            }
            if (objects.size() == 1) {
                return objects.get(0);
            }
            return objects;
        }
    }

    public static void setUtilsService(OsgiUtilsService utilsService) {
        EntryUtils.utilsService = utilsService;
    }

    private EntryUtils() {
    }

}