/** Default constructor. */
 public DeliveryItemLayoutStrategy() {
   NodeDescriptor node =
       DescriptorHelper.getNode(
           SupplierArchetypes.DELIVERY_ITEM,
           SUPPLIER_INVOICE_LINE_ID,
           ServiceHelper.getArchetypeService());
   ArchetypeNodes nodes = new ArchetypeNodes().excludeIfEmpty("order");
   if (node != null && node.isReadOnly()) {
     nodes.excludeIfEmpty(SUPPLIER_INVOICE_LINE_ID);
   }
   setArchetypeNodes(nodes);
 }
    /**
     * Lay out out the object in the specified container.
     *
     * @param object the object to lay out
     * @param properties the object's properties
     * @param parent the parent object. May be {@code null}
     * @param container the container to use
     * @param context the layout context
     */
    @Override
    protected void doLayout(
        IMObject object,
        PropertySet properties,
        IMObject parent,
        Component container,
        LayoutContext context) {
      ArchetypeDescriptor archetype = context.getArchetypeDescriptor(object);
      ArchetypeNodes nodes = getArchetypeNodes();
      NodeFilter filter = getNodeFilter(object, context);

      List<Property> simple = nodes.getSimpleNodes(properties, archetype, object, filter);
      List<Property> complex = nodes.getComplexNodes(properties, archetype, object, filter);

      if (simple.size() == 1 && complex.isEmpty()) {
        ComponentSet set = createComponentSet(object, simple, context);
        ComponentState state = set.getComponents().get(0);
        setFocusTraversal(state);
        container.add(state.getComponent());
      } else {
        doSimpleLayout(object, parent, simple, container, context);
        doComplexLayout(object, parent, complex, container, context);
      }
    }
  /**
   * Constructs an {@code AbstractRelationshipEditor}.
   *
   * @param relationship the relationship
   * @param parent the parent object
   * @param layoutContext the layout context
   */
  public AbstractRelationshipEditor(
      IMObject relationship, IMObject parent, LayoutContext layoutContext) {
    super(relationship, parent, layoutContext);
    IMObjectCache cache = layoutContext.getCache();
    Property sourceProp = getSource();
    Property targetProp = getTarget();

    IMObjectReference sourceRef = (IMObjectReference) sourceProp.getValue();
    IMObjectReference targetRef = (IMObjectReference) targetProp.getValue();

    IMObject source = getObject(sourceRef, parent, sourceProp.getArchetypeRange(), cache);
    IMObject target = getObject(targetRef, parent, targetProp.getArchetypeRange(), cache);

    // initialise the properties if null
    if (sourceRef == null && source != null) {
      sourceProp.setValue(source.getObjectReference());
    }
    if (targetRef == null && target != null && !ObjectUtils.equals(source, target)) {
      // only add the target if it is different to the source (e.g. see
      // entityRelationship.productLink where the
      // source and target archetypes are the same)
      targetProp.setValue(target.getObjectReference());
    }

    nodes = new ArchetypeNodes();

    if (source == null || !source.equals(parent)) {
      sourceEditor = createSourceEditor(sourceProp, layoutContext);
      nodes.simple(SOURCE);
      nodes.first(SOURCE);
      nodes.exclude(TARGET);
    }

    if (target == null || !target.equals(parent) || target.equals(source)) {
      targetEditor = createTargetEditor(targetProp, layoutContext);
      nodes.simple(TARGET);
      nodes.first(TARGET);
      nodes.exclude(SOURCE);
    }
  }