com.haulmont.cuba.gui.data.impl.EntityCopyUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.haulmont.cuba.gui.data.impl.EntityCopyUtils.java

Source

/*
 * Copyright (c) 2008-2016 Haulmont.
 *
 * 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 com.haulmont.cuba.gui.data.impl;

import com.haulmont.bali.util.Preconditions;
import com.haulmont.chile.core.model.MetaProperty;
import com.haulmont.chile.core.model.impl.AbstractInstance;
import com.haulmont.cuba.core.entity.BaseDbGeneratedIdEntity;
import com.haulmont.cuba.core.entity.BaseEntityInternalAccess;
import com.haulmont.cuba.core.entity.BaseGenericIdEntity;
import com.haulmont.cuba.core.entity.Entity;
import org.apache.commons.lang.exception.ExceptionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;

public class EntityCopyUtils {

    public static Entity copyCompositions(Entity source) {
        Preconditions.checkNotNullArgument(source, "source is null");

        Entity dest;
        try {
            dest = source.getClass().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        copyCompositions(source, dest);

        return dest;
    }

    public static void copyCompositions(Entity source, Entity dest) {
        Preconditions.checkNotNullArgument(source, "source is null");
        Preconditions.checkNotNullArgument(dest, "dest is null");

        if (source instanceof BaseDbGeneratedIdEntity && dest instanceof BaseDbGeneratedIdEntity) {
            ((BaseDbGeneratedIdEntity) dest).setId(((BaseDbGeneratedIdEntity) source).getId());
        }

        for (MetaProperty srcProperty : source.getMetaClass().getProperties()) {
            String name = srcProperty.getName();
            MetaProperty dstProperty = dest.getMetaClass().getProperty(name);
            if (dstProperty != null && !dstProperty.isReadOnly()) {
                try {
                    Object value = source.getValue(name);

                    if (value != null && srcProperty.getRange().getCardinality().isMany()
                            && srcProperty.getType() == MetaProperty.Type.COMPOSITION) {
                        //noinspection unchecked
                        Collection<Entity> srcCollection = (Collection) value;

                        // Copy first to a Set to remove duplicates that could be created on repeated editing newly
                        // added items
                        Collection<Entity> tmpCollection = new LinkedHashSet<>();
                        for (Entity item : srcCollection) {
                            Entity copy = copyCompositions(item);
                            tmpCollection.add(copy);
                        }

                        Collection<Entity> dstCollection;
                        if (value instanceof List)
                            dstCollection = new ArrayList<>(tmpCollection);
                        else
                            dstCollection = tmpCollection;
                        dest.setValue(name, dstCollection);

                    } else {
                        dest.setValue(name, source.getValue(name));
                    }
                } catch (RuntimeException e) {
                    Throwable cause = ExceptionUtils.getRootCause(e);
                    if (cause == null)
                        cause = e;
                    // ignore exception on copy for not loaded fields
                    if (!isNotLoadedAttributeException(cause))
                        throw e;
                }
            }
        }
        if (source instanceof BaseGenericIdEntity && dest instanceof BaseGenericIdEntity) {
            BaseGenericIdEntity destGenericEntity = (BaseGenericIdEntity) dest;
            BaseGenericIdEntity<?> sourceGenericEntity = (BaseGenericIdEntity<?>) source;

            BaseEntityInternalAccess.setDetached(destGenericEntity,
                    BaseEntityInternalAccess.isDetached(sourceGenericEntity));
            BaseEntityInternalAccess.setNew(destGenericEntity, BaseEntityInternalAccess.isNew(sourceGenericEntity));
            destGenericEntity.setDynamicAttributes(sourceGenericEntity.getDynamicAttributes());
        }
    }

    public static void copyCompositionsBack(Entity source, Entity dest) {
        Preconditions.checkNotNullArgument(source, "source is null");
        Preconditions.checkNotNullArgument(dest, "dest is null");

        for (MetaProperty srcProperty : source.getMetaClass().getProperties()) {
            String name = srcProperty.getName();
            MetaProperty dstProperty = dest.getMetaClass().getProperty(name);
            if (dstProperty != null && !dstProperty.isReadOnly()) {
                try {
                    Object value = source.getValue(name);

                    if (value != null && srcProperty.getRange().getCardinality().isMany()
                            && srcProperty.getType() == MetaProperty.Type.COMPOSITION) {
                        ((AbstractInstance) dest).setValue(name, source.getValue(name), false);
                    } else {
                        dest.setValue(name, source.getValue(name));
                    }
                } catch (RuntimeException e) {
                    Throwable cause = ExceptionUtils.getRootCause(e);
                    if (cause == null)
                        cause = e;
                    // ignore exception on copy for not loaded fields
                    if (!isNotLoadedAttributeException(cause))
                        throw e;
                }
            }
        }
    }

    private static boolean isNotLoadedAttributeException(Throwable e) {
        return e instanceof IllegalStateException
                || e instanceof org.eclipse.persistence.exceptions.ValidationException && e.getMessage() != null
                        && e.getMessage().contains(
                                "An attempt was made to traverse a relationship using indirection that had a null Session");
    }
}