com.haulmont.cuba.gui.model.impl.ScreenDataImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.haulmont.cuba.gui.model.impl.ScreenDataImpl.java

Source

/*
 * Copyright (c) 2008-2018 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.model.impl;

import com.google.common.base.Strings;
import com.haulmont.bali.util.ReflectionHelper;
import com.haulmont.chile.core.model.MetaProperty;
import com.haulmont.cuba.core.entity.Entity;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.core.global.MetadataTools;
import com.haulmont.cuba.core.global.ViewRepository;
import com.haulmont.cuba.gui.model.*;
import org.dom4j.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

@Component(ScreenData.NAME)
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ScreenDataImpl implements ScreenData {

    @Inject
    protected DataContextFactory factory;

    @Inject
    protected ViewRepository viewRepository;

    @Inject
    protected Metadata metadata;

    @Inject
    protected MetadataTools metadataTools;

    protected DataContext dataContext;

    protected Map<String, InstanceContainer> containers = new HashMap<>();

    protected Map<String, DataLoader> loaders = new HashMap<>();

    @PostConstruct
    protected void init() {
        dataContext = factory.createDataContext();
    }

    @Override
    public DataContext getDataContext() {
        return dataContext;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends InstanceContainer> T getContainer(String id) {
        return (T) containers.get(id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends DataLoader> T getLoader(String id) {
        return (T) loaders.get(id);
    }

    @Override
    public void load(Element element) {
        for (Element el : element.elements()) {
            if (el.getName().equals("collection")) {
                loadCollectionContainer(el);
            } else if (el.getName().equals("instance")) {
                loadInstanceContainer(el);
            }
        }
    }

    protected void loadInstanceContainer(Element element) {
        String containerId = getRequiredAttr(element, "id");

        InstanceContainer<Entity> container = factory.createInstanceContainer(getEntityClass(element));
        loadView(element, getEntityClass(element), container);

        Element loaderEl = element.element("loader");
        if (loaderEl != null) {
            loadInstanceLoader(loaderEl, container);
        }

        registerContainer(containerId, container);

        for (Element collectionEl : element.elements("collection")) {
            loadNestedCollectionContainer(collectionEl, container);
        }
    }

    protected void loadCollectionContainer(Element element) {
        String containerId = getRequiredAttr(element, "id");

        CollectionContainer<Entity> container = factory.createCollectionContainer(getEntityClass(element));
        loadView(element, getEntityClass(element), container);

        Element loaderEl = element.element("loader");
        if (loaderEl != null) {
            loadCollectionLoader(loaderEl, container);
        }

        registerContainer(containerId, container);

        for (Element collectionEl : element.elements("collection")) {
            loadNestedCollectionContainer(collectionEl, container);
        }
    }

    private void loadNestedCollectionContainer(Element element, InstanceContainer<Entity> parentContainer) {
        String containerId = getRequiredAttr(element, "id");

        String property = getRequiredAttr(element, "property");
        MetaProperty metaProperty = parentContainer.getEntityMetaClass().getPropertyNN(property);
        if (!metaProperty.getRange().isClass() || !metaProperty.getRange().getCardinality().isMany()) {
            throw new IllegalStateException(String.format("Property '%s' is not a to-many reference", property));
        }
        @SuppressWarnings("unchecked")
        CollectionContainer<Entity> container = factory
                .createCollectionContainer(metaProperty.getRange().asClass().getJavaClass());

        parentContainer.addItemChangeListener(e -> {
            container.setItems(parentContainer.getItem().getValue(property));
        });

        registerContainer(containerId, container);
    }

    protected void loadInstanceLoader(Element element, InstanceContainer<Entity> container) {
        InstanceLoader<Entity> loader = factory.createInstanceLoader();
        loader.setDataContext(dataContext);
        loader.setContainer(container);

        Element queryEl = element.element("query");
        if (queryEl != null) {
            loader.setQuery(loadQuery(queryEl));
        }

        loadSoftDeletion(element, loader);
        loadEntityId(element, loader);

        String loaderId = element.attributeValue("id");
        if (loaderId != null) {
            registerLoader(loaderId, loader);
        }
    }

    protected void loadCollectionLoader(Element element, CollectionContainer<Entity> container) {
        CollectionLoader<Entity> loader = factory.createCollectionLoader();
        loader.setDataContext(dataContext);
        loader.setContainer(container);

        Element queryEl = element.element("query");
        if (queryEl != null) {
            loader.setQuery(loadQuery(queryEl));
        }

        loadSoftDeletion(element, loader);
        loadFirstResult(element, loader);
        loadMaxResults(element, loader);
        loadCacheable(element, loader);

        String loaderId = element.attributeValue("id");
        if (loaderId != null) {
            registerLoader(loaderId, loader);
        }
    }

    protected Class<Entity> getEntityClass(Element element) {
        String entityClassName = getRequiredAttr(element, "class");
        return ReflectionHelper.getClass(entityClassName);
    }

    protected void loadView(Element element, Class<Entity> entityClass, InstanceContainer<Entity> container) {
        String viewName = element.attributeValue("view");
        if (viewName != null) {
            container.setView(viewRepository.getView(entityClass, viewName));
        }
    }

    protected String loadQuery(Element queryEl) {
        return queryEl.getText().trim();
    }

    protected void loadSoftDeletion(Element element, DataLoader loader) {
        String softDeletionVal = element.attributeValue("softDeletion");
        if (!Strings.isNullOrEmpty(softDeletionVal))
            loader.setSoftDeletion(Boolean.valueOf(softDeletionVal));
    }

    protected void loadEntityId(Element element, InstanceLoader<Entity> loader) {
        String entityIdStr = element.attributeValue("entityId");
        if (Strings.isNullOrEmpty(entityIdStr)) {
            return;
        }
        MetaProperty property = metadataTools.getPrimaryKeyProperty(loader.getContainer().getEntityMetaClass());
        if (property == null) {
            throw new IllegalStateException(
                    "Cannot determine id property for " + loader.getContainer().getEntityMetaClass());
        }
        if (property.getRange().isDatatype()) {
            try {
                Object value = property.getRange().asDatatype().parse(entityIdStr);
                loader.setEntityId(value);
            } catch (ParseException e) {
                throw new RuntimeException("Error parsing entityId for " + loader, e);
            }
        } else {
            throw new IllegalStateException(
                    "Cannot assign id to " + loader + " because the entity has a composite PK");
        }
    }

    protected void loadFirstResult(Element element, CollectionLoader<Entity> loader) {
        String firstResultStr = element.attributeValue("firstResult");
        if (Strings.isNullOrEmpty(firstResultStr))
            return;

        loader.setFirstResult(Integer.valueOf(firstResultStr));
    }

    protected void loadMaxResults(Element element, CollectionLoader<Entity> loader) {
        String maxResultsStr = element.attributeValue("maxResults");
        if (Strings.isNullOrEmpty(maxResultsStr))
            return;

        loader.setMaxResults(Integer.valueOf(maxResultsStr));
    }

    protected void loadCacheable(Element element, CollectionLoader<Entity> loader) {
        String cacheableVal = element.attributeValue("cacheable");
        if (!Strings.isNullOrEmpty(cacheableVal))
            loader.setCacheable(Boolean.valueOf(cacheableVal));
    }

    protected String getRequiredAttr(Element element, String attributeName) {
        String id = element.attributeValue(attributeName);
        if (id == null)
            throw new IllegalStateException("Required attribute '" + attributeName + "' not found in " + element);
        return id.trim();
    }

    protected void registerContainer(String id, InstanceContainer container) {
        containers.put(id, container);
    }

    protected void registerLoader(String id, DataLoader loader) {
        loaders.put(id, loader);
    }
}