com.arondor.common.reflection.gwt.client.presenter.ClassTreeNodePresenter.java Source code

Java tutorial

Introduction

Here is the source code for com.arondor.common.reflection.gwt.client.presenter.ClassTreeNodePresenter.java

Source

/*
 *  Copyright 2013, Arondor
 *
 *  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.arondor.common.reflection.gwt.client.presenter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import com.arondor.common.reflection.gwt.client.event.TreeNodeClearEvent;
import com.arondor.common.reflection.gwt.client.service.GWTReflectionServiceAsync;
import com.arondor.common.reflection.model.config.ElementConfiguration;
import com.arondor.common.reflection.model.config.ObjectConfiguration;
import com.arondor.common.reflection.model.config.ObjectConfigurationFactory;
import com.arondor.common.reflection.model.config.ObjectConfigurationMap;
import com.arondor.common.reflection.model.config.ReferenceConfiguration;
import com.arondor.common.reflection.model.java.AccessibleClass;
import com.arondor.common.reflection.model.java.AccessibleField;
import com.arondor.common.reflection.util.PrimitiveTypeUtil;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class ClassTreeNodePresenter implements TreeNodePresenter {
    private static final Logger LOG = Logger.getLogger(ClassTreeNodePresenter.class.getName());

    public interface ClassDisplay extends TreeNodePresenter.ChildCreatorDisplay {
        ImplementingClassPresenter.Display getImplementingClassDisplay();

    }

    private final Map<String, TreeNodePresenter> classTreeNodePresenterMap = new HashMap<String, TreeNodePresenter>();

    private final ClassDisplay display;

    private final String fieldName;

    private final ImplementingClassPresenter implementingClassPresenter;

    private final GWTReflectionServiceAsync rpcService;

    private final ObjectConfigurationMap objectConfigurationMap;

    public ClassTreeNodePresenter(GWTReflectionServiceAsync rpcService,
            ObjectConfigurationMap objectConfigurationMap, String baseClassName, ClassDisplay view) {
        this(rpcService, objectConfigurationMap, null, baseClassName, view);
        display.setNodeName(baseClassName);
    }

    protected ClassTreeNodePresenter(GWTReflectionServiceAsync rpcService,
            ObjectConfigurationMap objectConfigurationMap, String fieldName, String baseClassName,
            ClassDisplay view) {
        this.fieldName = fieldName;
        this.rpcService = rpcService;
        this.display = view;
        this.objectConfigurationMap = objectConfigurationMap;

        LOG.finest("Create new TreeNodePresenter for fieldName=" + fieldName + ", baseClassName=" + baseClassName);

        implementingClassPresenter = new DefaultImplementingClassPresenter(rpcService, objectConfigurationMap,
                baseClassName, display.getImplementingClassDisplay());
        bind();
    }

    private void bind() {
        implementingClassPresenter.addValueChangeHandler(new ValueChangeHandler<ImplementingClass>() {
            public void onValueChange(ValueChangeEvent<ImplementingClass> event) {
                if (event.getValue().isReference()) {
                    classTreeNodePresenterMap.clear();
                } else {
                    updateAccessibleClass(event.getValue().getName(), null);
                }
            }
        });

        display.addTreeNodeClearHandler(new TreeNodeClearEvent.Handler() {
            public void onTreeNodeClearEvent(TreeNodeClearEvent treeNodeClearEvent) {
                implementingClassPresenter.setImplementingClass(ImplementingClass.NULL_CLASS);
                classTreeNodePresenterMap.clear();
            }
        });
    }

    private void updateAccessibleClass(String className, final ObjectConfiguration objectConfiguration) {
        rpcService.getAccessibleClass(className, new AsyncCallback<AccessibleClass>() {
            public void onSuccess(AccessibleClass result) {
                updateAccessibleClass(result, objectConfiguration);
            }

            public void onFailure(Throwable caught) {
            }
        });
    }

    private void updateAccessibleClass(AccessibleClass accessibleClass, ObjectConfiguration objectConfiguration) {
        LOG.finest("field=" + fieldName + ", updateAccessibleClass(class="
                + (accessibleClass != null ? accessibleClass.getName() : null) + ", objectConfiguration="
                + objectConfiguration + ")");

        classTreeNodePresenterMap.clear();
        display.clear();

        if (accessibleClass != null) {
            display.setActive(true);
            buildTree(accessibleClass);

            if (objectConfiguration != null) {
                implementingClassPresenter
                        .setImplementingClass(new ImplementingClass(false, objectConfiguration.getClassName()));

                if (PrimitiveTypeUtil.isPrimitiveType(objectConfiguration.getClassName())
                        && objectConfiguration.getConstructorArguments().size() == 1) {
                    TreeNodePresenter valuePresenter = classTreeNodePresenterMap.get("value");
                    if (valuePresenter != null) {
                        valuePresenter
                                .setElementConfiguration(objectConfiguration.getConstructorArguments().get(0));
                    }
                } else if (objectConfiguration.getFields() != null) {
                    for (Map.Entry<String, ElementConfiguration> fieldEntry : objectConfiguration.getFields()
                            .entrySet()) {
                        TreeNodePresenter nodePresenter = classTreeNodePresenterMap.get(fieldEntry.getKey());
                        if (nodePresenter != null) {
                            nodePresenter.setElementConfiguration(fieldEntry.getValue());
                        }
                    }
                }
            }
        } else {
            display.setActive(false);
        }
    }

    private void buildTree(AccessibleClass accessibleClass) {
        List<AccessibleField> sortedAccessibleFields = new ArrayList<AccessibleField>();
        sortedAccessibleFields.addAll(accessibleClass.getAccessibleFields().values());
        Collections.sort(sortedAccessibleFields, new AccessibleFieldComparator());

        LOG.finest("Build tree for accessibleClass=" + accessibleClass.getName());

        for (AccessibleField accessibleField : sortedAccessibleFields) {
            TreeNodePresenter childPresenter = TreeNodePresenterFactory.getInstance()
                    .createChildNodePresenter(rpcService, objectConfigurationMap, display, accessibleField);
            LOG.finest("At field=" + accessibleField.getName() + ", created childPresenter=" + childPresenter);
            classTreeNodePresenterMap.put(accessibleField.getName(), childPresenter);
        }
    }

    public String getFieldName() {
        return fieldName;
    }

    public String getBaseClassName() {
        return implementingClassPresenter.getBaseClassName();
    }

    public ClassDisplay getDisplay() {
        return display;
    }

    public ElementConfiguration getElementConfiguration(ObjectConfigurationFactory objectConfigurationFactory) {
        if (implementingClassPresenter.getImplementingClass() == null
                || implementingClassPresenter.getImplementingClass().getName() == null) {
            return null;
        }
        if (PrimitiveTypeUtil.isPrimitiveType(implementingClassPresenter.getImplementingClass().getName())) {
            String implementingClass = implementingClassPresenter.getImplementingClass().getName();
            if (implementingClass.equals("java.lang.String")) {
                /**
                 * This is rather hacky
                 */
                TreeNodePresenter valuePresenter = classTreeNodePresenterMap.get("value");
                if (valuePresenter != null) {
                    ElementConfiguration valueConfiguration = valuePresenter
                            .getElementConfiguration(objectConfigurationFactory);
                    ObjectConfiguration objectConfiguration = objectConfigurationFactory
                            .createObjectConfiguration();
                    objectConfiguration.setClassName(implementingClass);
                    objectConfiguration.setFields(new LinkedHashMap<String, ElementConfiguration>());
                    objectConfiguration.setConstructorArguments(new ArrayList<ElementConfiguration>());
                    objectConfiguration.getConstructorArguments().add(valueConfiguration);
                    return objectConfiguration;
                }
            }
            throw new RuntimeException("NOT IMPLEMENTED YET");
        } else if (implementingClassPresenter.getImplementingClass().isReference()) {
            ReferenceConfiguration referenceConfiguration = objectConfigurationFactory
                    .createReferenceConfiguration();
            referenceConfiguration.setReferenceName(implementingClassPresenter.getImplementingClass().getName());
            return referenceConfiguration;
        } else {
            return getObjectConfiguration(objectConfigurationFactory);
        }

    }

    private ElementConfiguration getObjectConfiguration(ObjectConfigurationFactory objectConfigurationFactory) {
        ObjectConfiguration objectConfiguration = objectConfigurationFactory.createObjectConfiguration();
        objectConfiguration.setFields(new LinkedHashMap<String, ElementConfiguration>());
        objectConfiguration.setClassName(implementingClassPresenter.getImplementingClass().getName());

        updateChildObjectConfigurations(objectConfigurationFactory, objectConfiguration);
        return objectConfiguration;
    }

    private void updateChildObjectConfigurations(ObjectConfigurationFactory objectConfigurationFactory,
            ObjectConfiguration objectConfiguration) {
        for (Map.Entry<String, TreeNodePresenter> presentersEntry : classTreeNodePresenterMap.entrySet()) {
            ElementConfiguration childConfiguration = presentersEntry.getValue()
                    .getElementConfiguration(objectConfigurationFactory);
            if (childConfiguration != null) {
                objectConfiguration.getFields().put(presentersEntry.getKey(), childConfiguration);
            }
        }
    }

    public void setElementConfiguration(ElementConfiguration elementConfiguration) {
        LOG.finest("setElementConfiguration :" + elementConfiguration);
        if (elementConfiguration instanceof ObjectConfiguration) {
            ObjectConfiguration objectConfiguration = (ObjectConfiguration) elementConfiguration;
            updateAccessibleClass(objectConfiguration.getClassName(), objectConfiguration);
        } else if (elementConfiguration instanceof ReferenceConfiguration) {
            ReferenceConfiguration referenceConfiguration = (ReferenceConfiguration) elementConfiguration;
            implementingClassPresenter
                    .setImplementingClass(new ImplementingClass(true, referenceConfiguration.getReferenceName()));
        }
    }

    public ImplementingClass getImplementingClass() {
        return implementingClassPresenter.getImplementingClass();
    }

}