All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nakedobjects.nos.client.dnd.builder.ObjectFieldBuilder Maven / Gradle / Ivy

package org.nakedobjects.nos.client.dnd.builder;

import org.apache.log4j.Logger;
import org.nakedobjects.noa.adapter.Naked;
import org.nakedobjects.noa.adapter.NakedObject;
import org.nakedobjects.noa.reflect.NakedObjectField;
import org.nakedobjects.noa.spec.NakedObjectSpecification;
import org.nakedobjects.nof.core.context.NakedObjectsContext;
import org.nakedobjects.nof.core.util.Assert;
import org.nakedobjects.nof.core.util.UnknownTypeException;
import org.nakedobjects.nos.client.dnd.CompositeViewSpecification;
import org.nakedobjects.nos.client.dnd.Content;
import org.nakedobjects.nos.client.dnd.FieldContent;
import org.nakedobjects.nos.client.dnd.ObjectContent;
import org.nakedobjects.nos.client.dnd.SubviewSpec;
import org.nakedobjects.nos.client.dnd.Toolkit;
import org.nakedobjects.nos.client.dnd.View;
import org.nakedobjects.nos.client.dnd.ViewAxis;
import org.nakedobjects.nos.client.dnd.view.simple.CompositeView;
import org.nakedobjects.nos.client.dnd.view.simple.FieldErrorView;


public class ObjectFieldBuilder extends AbstractViewBuilder {
    private static final Logger LOG = Logger.getLogger(ObjectFieldBuilder.class);
    private SubviewSpec subviewDesign;
    // TODO remove this:
    private final boolean useFieldType;

    public ObjectFieldBuilder(final SubviewSpec subviewDesign) {
        this(subviewDesign, false);
    }

    public ObjectFieldBuilder(final SubviewSpec subviewDesign, final boolean useFieldType) {
        this.subviewDesign = subviewDesign;
        this.useFieldType = useFieldType;
    }

    public void build(final View view) {
        Assert.assertEquals("ensure the view is the complete decorated view", view.getView(), view);

        Content content = view.getContent();
        NakedObject object = ((ObjectContent) content).getObject();

        LOG.debug("build view " + view + " for " + object);

        NakedObjectSpecification spec = null;
        if (useFieldType) {
            spec = content.getSpecification();
        }
        if (spec == null) {
            spec = object.getSpecification();
        }

        NakedObjectField[] flds = spec.getDynamicallyVisibleFields(object);

        if (view.getSubviews().length == 0) {
            newBuild(view, object, flds);
        } else {
            updateBuild(view, object, flds);
        }
    }

    public View createCompositeView(final Content content, final CompositeViewSpecification specification, final ViewAxis axis) {
        return new CompositeView(content, specification, axis);
    }

    public View decorateSubview(final View subview) {
        return subviewDesign.decorateSubview(subview);
    }

    private void newBuild(final View view, final NakedObject object, final NakedObjectField[] flds) {
        LOG.debug("  as new build");
        for (int f = 0; f < flds.length; f++) {
            NakedObjectField field = flds[f];
            addField(view, object, field);
        }
    }

    private void addField(final View view, final NakedObject object, final NakedObjectField field) {
        Naked value = field.get(object);
        View fieldView = createFieldView(view, object, field, value);
        if (fieldView != null) {
            view.addView(decorateSubview(fieldView));
        }
    }

    private void updateBuild(final View view, final NakedObject object, final NakedObjectField[] flds) {
        LOG.debug("  as update build");
        /*
         * 1/ To remove fields: look through views and remove any that don't exists in visible fields
         * 
         * 2/ From remaining views, check for changes as already being done, and replace if needed
         * 
         * 3/ Finally look through fields to see if there is no existing subview; and add one
         */

        View[] subviews = view.getSubviews();

        // remove views for fields that no longer exist
        outer: for (int i = 0; i < subviews.length; i++) {
            FieldContent fieldContent = ((FieldContent) subviews[i].getContent());

            for (int j = 0; j < flds.length; j++) {
                NakedObjectField field = flds[j];
                if (fieldContent.getField() == field) {
                    continue outer;
                }
            }
            view.removeView(subviews[i]);
        }

        // update existing fields if needed
        subviews = view.getSubviews();
        for (int i = 0; i < subviews.length; i++) {
            View subview = subviews[i];
            NakedObjectField field = ((FieldContent) subview.getContent()).getField();
            Naked value = field.get(object);
            if (field.isValue()) {
                Naked naked = subview.getContent().getNaked();

                if (value != null && value.getObject() != null && !value.getObject().equals(naked.getObject())) {
                    View fieldView = createFieldView(view, object, field, value);
                    view.replaceView(subview, decorateSubview(fieldView));
                }  else {
                    subview.refresh();
                }
            } else if (field.isCollection()) {
                subview.update(value);
            } else if (field.isObject()) {
                NakedObject existing = ((ObjectContent) subviews[i].getContent()).getObject();
                boolean changedValue = value != existing;
                boolean isDestroyed = existing != null && existing.getResolveState().isDestroyed();
                if (changedValue || isDestroyed) {
                    View fieldView;
                    fieldView = createFieldView(view, object, field, value);
                    if (fieldView != null) {
                        view.replaceView(subview, decorateSubview(fieldView));
                    } else {
                        view.addView(new FieldErrorView("No field for " + value));
                    }
                }
            } else {
                throw new UnknownTypeException(field.getName());
            }
        }

        // add new fields
        outer2: for (int j = 0; j < flds.length; j++) {
            NakedObjectField field = flds[j];
            for (int i = 0; i < subviews.length; i++) {
                FieldContent fieldContent = ((FieldContent) subviews[i].getContent());
                if (fieldContent.getField() == field) {
                    continue outer2;
                }
            }
            addField(view, object, field);
        }
    }

    private View createFieldView(final View view, final NakedObject object, final NakedObjectField field, final Naked value) {
        if (field == null) {
            throw new NullPointerException();
        }

        if (field.isObject()) {
            NakedObjectsContext.getObjectPersistor().resolveField(object, field);
        }

        Content content1 = Toolkit.getContentFactory().createFieldContent(field, object, value);
        View fieldView = subviewDesign.createSubview(content1, view.getViewAxis());
        return fieldView;
    }
}
// Copyright (c) Naked Objects Group Ltd.




© 2015 - 2025 Weber Informatics LLC | Privacy Policy