com.utest.webservice.builders.Builder.java Source code

Java tutorial

Introduction

Here is the source code for com.utest.webservice.builders.Builder.java

Source

/**
 *
 * Licensed under the GNU General Public License (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.gnu.org/licenses/gpl.txt
 *
 * 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.
 *
 * 
 * @author Vadim Kisen
 *
 * copyright 2010 by uTest 
 */
package com.utest.webservice.builders;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.ws.rs.core.UriBuilder;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.PropertyUtils;

import com.utest.domain.Entity;
import com.utest.domain.Locale;
import com.utest.domain.LocaleDescriptable;
import com.utest.domain.LocalizedEntity;
import com.utest.domain.Named;
import com.utest.domain.TimelineVersionable;
import com.utest.domain.search.UtestSearch;
import com.utest.domain.search.UtestSearchResult;
import com.utest.webservice.model.v2.BaseInfo;
import com.utest.webservice.model.v2.ResourceIdentity;
import com.utest.webservice.model.v2.ResourceLocator;
import com.utest.webservice.model.v2.SearchResultInfo;
import com.utest.webservice.model.v2.Timeline;
import com.utest.webservice.model.v2.UtestSearchRequest;
import com.utest.webservice.model.v2.UtestSearchResultInfo;

public class Builder<Ti, To> {

    protected final ObjectBuilderFactory factory;
    protected Class<Ti> infoClass;
    protected Class<? extends SearchResultInfo<Ti>> resultClass;

    Builder(final ObjectBuilderFactory factory, final Class<Ti> clazz,
            final Class<? extends SearchResultInfo<Ti>> resultClass) {
        this.factory = factory;
        infoClass = clazz;
        this.resultClass = resultClass;
    }

    public List<Ti> toInfo(final List<To> objects, final UriBuilder ub, final Object... uriBuilderArgs)
            throws Exception {
        final List<Ti> ret = new ArrayList<Ti>();
        if ((objects == null) || objects.isEmpty()) {
            return ret;
        }
        for (final To obj : objects) {
            final Object[] args = new Object[uriBuilderArgs.length + 1];
            int i = 0;
            for (; i < uriBuilderArgs.length; i++) {
                args[i] = uriBuilderArgs[i];
            }
            if (obj instanceof Entity) {
                args[i] = ((Entity) obj).getId();
            }
            ret.add(toInfo(obj, ub.clone(), args));
        }
        return ret;

    }

    public Ti toInfo(final To object, final UriBuilder ub, Object... uriBuilderArgs) throws Exception {
        Ti result;
        final Constructor<Ti> constr = infoClass.getConstructor(new Class[] {});
        if (constr == null) {
            throw new IllegalArgumentException("No default constructor found for " + infoClass.getName());
        }
        result = constr.newInstance(new Object[] {});
        ConvertUtilsBean cub = new ConvertUtilsBean();
        // do not throw exceptions on null values
        cub.register(false, true, 0);
        BeanUtilsBean bub = new BeanUtilsBean(cub);
        bub.copyProperties(result, object);
        // PropertyUtils.copyProperties(result, object);
        if (object instanceof LocalizedEntity) {
            LocalizedEntity localizedEntity = (LocalizedEntity) object;
            LocaleDescriptable localDescriptable = localizedEntity.getLocale(Locale.DEFAULT_LOCALE);
            // PropertyUtils.copyProperties(result, localDescriptable);
            bub.copyProperties(result, localDescriptable);
        }
        Map<?, ?> resultProperties = PropertyUtils.describe(result);
        // don't return password field
        if (resultProperties.containsKey("password")) {
            PropertyUtils.setProperty(result, "password", null);
        }
        //
        populateLocators(result, ub);
        //
        if (result instanceof BaseInfo) {
            populateIdentityAndTimeline((BaseInfo) result, object, ub, uriBuilderArgs);
        }

        // special handling for descendands of Builder
        populateExtendedProperties(result, object, ub, uriBuilderArgs);

        return result;
    }

    protected void populateExtendedProperties(Ti result, To object, UriBuilder ub, Object[] uriBuilderArgs)
            throws Exception {
        // do nothing.this method could be overitten by descendants
    }

    protected void populateLocators(Ti result, UriBuilder ub)
            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Map<?, ?> resultProperties = PropertyUtils.describe(result);
        for (Object property : resultProperties.keySet()) {
            if (((String) property).endsWith("Locator")) {
                String resourcePath = null;
                Integer resourceId = null;
                String resourceName = ((String) property).substring(0, ((String) property).indexOf("Locator"));
                if (resultProperties.containsKey(resourceName + "Id")) {
                    resourceId = (Integer) PropertyUtils.getProperty(result, resourceName + "Id");
                    if (resourceId != null) {
                        resourcePath = getResourcePath(resourceName.toLowerCase());
                    }
                }
                // represents a user who performed an operation
                else if (resourceName.endsWith("By")) {
                    resourceId = (Integer) PropertyUtils.getProperty(result, resourceName);
                    if (resourceId != null) {
                        resourcePath = getResourcePath("user");
                    }
                }
                if (resourcePath != null) {
                    String className = getResourceNamedClass(resourceName.toLowerCase());
                    String name = "";
                    if (className != null) {
                        try {
                            Class<?> clazz = Class.forName(className);
                            Object namedEntity = factory.getStaticDataService().getEntity(clazz, resourceId);
                            if (namedEntity != null && namedEntity instanceof Named) {
                                name = ((Named) namedEntity).getName();
                            }
                        } catch (ClassNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    ResourceLocator resourceLocator = new ResourceLocator(resourceId,
                            ub.clone().path(resourcePath).build(resourceId).toString(), name);
                    PropertyUtils.setProperty(result, (String) property, resourceLocator);
                }
            }
        }
    }

    protected void populateIdentityAndTimeline(BaseInfo result, final To object, final UriBuilder ub,
            Object... uriBuilderArgs)
            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        ResourceIdentity resourceIdentity = new ResourceIdentity();
        PropertyUtils.copyProperties(resourceIdentity, object);
        result.setResourceIdentity(resourceIdentity);
        // populate resource url if it's defined
        String resourcePath = null;
        String resourceName = object.getClass().getSimpleName().toLowerCase();
        resourcePath = getResourcePath(resourceName);
        if (resourcePath != null) {
            resourceIdentity.setUrl(ub.clone().path(resourcePath).build(resourceIdentity.getId()).toString());
        }

        if (object instanceof TimelineVersionable) {
            Timeline timeline = new Timeline();
            PropertyUtils.copyProperties(timeline, object);
            result.setTimeline(timeline);
        }
    }

    @SuppressWarnings("unchecked")
    public SearchResultInfo<Ti> createResult(final UtestSearchRequest request, final UtestSearchResult result,
            final UriBuilder ub) throws Exception {
        SearchResultInfo<Ti> info;
        if (resultClass != null) {
            info = resultClass.newInstance();
        } else {
            info = new UtestSearchResultInfo<Ti>();
        }
        final List<To> list = (List<To>) result.getResults();
        if (list.isEmpty()) {
            info.setRows((List<Ti>) Collections.emptyList());
        } else {
            info.setRows(toInfo(list, ub));
        }
        info.setTotalResults(result.getTotalRecords());
        return info;
    }

    public void updateSearch(final UtestSearchRequest request, final UtestSearch search) {
        search.setPage(request.getPageNumber());
        search.setMaxResults(request.getPageSize());
        return;
    }

    public To toObject(final Class<To> objectClass, final Ti info) throws Exception {
        To result;
        final Constructor<To> constr = objectClass.getConstructor(new Class[] {});
        if (constr == null) {
            throw new IllegalArgumentException("No default constructor found for " + infoClass.getName());
        }
        result = constr.newInstance(new Object[] {});
        PropertyUtils.copyProperties(result, info);
        return result;
    }

    public String toStringFromDescriptable(final Object object) {
        try {
            final Method getDescription = object.getClass().getMethod("getDescription", new Class[] {});
            return (String) getDescription.invoke(object, new Object[] {});
        } catch (final Exception e) {
            return null;
        }
    }

    public List<String> toStringListFromDescriptable(final List<?> objects) {
        if ((objects == null) || objects.isEmpty()) {
            return Collections.emptyList();
        }
        final List<String> results = new ArrayList<String>();
        for (final Object object : objects) {
            final String value = toStringFromDescriptable(object);
            if (value != null) {
                results.add(value);
            }
        }
        return results;
    }

    private String getResourcePath(String resourceKey_) {
        return ResourceManager.getResourcePath(resourceKey_);
    }

    private String getResourceNamedClass(String resourceKey_) {
        return ResourceManager.getResourceNamedClass(resourceKey_);
    }
}