
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