/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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 org.apache.isis.applib.domain;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.apache.isis.applib.IsisModuleApplib;
import org.apache.isis.applib.annotation.Collection;
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.DomainObjectLayout;
import org.apache.isis.applib.annotation.Editing;
import org.apache.isis.applib.annotation.Nature;
import org.apache.isis.applib.annotation.Optionality;
import org.apache.isis.applib.annotation.Property;
import org.apache.isis.applib.jaxb.PersistentEntitiesAdapter;

import lombok.Getter;

/**
 * The initial idea of {@link DomainObjectList} was to simplify restful clients.
 * <p>
 * In the original Restful Objects specification, invoking an action that returned
 * a list meant that the RO client needed to handle this collection, which didn't
 * have any identity. That made for special case logic in the client.
 * <p>
 * Instead, if the RO client invokes the action but uses the <i>Accept Header</i> to
 * request an object, then the RO viewer would automatically wrap the returned list
 * in this {@link DomainObjectList} view model.
 * <p>
 * Thus, the RO client then only ever needs to know how to render an object, in all cases.
 *
 * @since 1.x {@index}
 */
@XmlRootElement(name = "list")
@XmlType(
        propOrder = {
                "title",
                "actionOwningType",
                "actionId",
                "actionArguments",
                "elementObjectType",
                "objects"
        }
        )
@XmlAccessorType(XmlAccessType.FIELD)
@DomainObject(
        objectType = DomainObjectList.OBJECT_TYPE,
        editing = Editing.DISABLED,
        nature = Nature.VIEW_MODEL
        )
@DomainObjectLayout(
        titleUiEvent = DomainObjectList.TitleUiEvent.class,
        iconUiEvent = DomainObjectList.IconUiEvent.class,
        cssClassUiEvent = DomainObjectList.CssClassUiEvent.class,
        layoutUiEvent = DomainObjectList.LayoutUiEvent.class
        )
public class DomainObjectList {

    public static final String OBJECT_TYPE = "isis.applib.DomainObjectList";

    // -- ui event classes
    public static class TitleUiEvent extends IsisModuleApplib.TitleUiEvent<DomainObjectList>{  }
    public static class IconUiEvent extends IsisModuleApplib.IconUiEvent<DomainObjectList>{  }
    public static class CssClassUiEvent extends IsisModuleApplib.CssClassUiEvent<DomainObjectList>{  }
    public static class LayoutUiEvent extends IsisModuleApplib.LayoutUiEvent<DomainObjectList>{  }


    // -- domain event classes
    public static abstract class PropertyDomainEvent<T> extends IsisModuleApplib.PropertyDomainEvent<DomainObjectList, T> {  }
    public static abstract class CollectionDomainEvent<T> extends IsisModuleApplib.CollectionDomainEvent<DomainObjectList, T> {  }
    public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<DomainObjectList> {  }


    // -- constructors
    public DomainObjectList() {
    }
    public DomainObjectList(
            final String title,
            final String elementTypeFqcn,
            final String actionOwnerFqcn,
            final String actionId,
            final String actionArguments) {
        this.title = title;
        this.elementTypeFqcn = elementTypeFqcn;
        this.actionOwnerFqcn = actionOwnerFqcn;
        this.actionId = actionId;
        this.actionArguments = actionArguments;
    }


    // -- title
    private String title;
    public String title() {
        return title;
    }


    // -- property: elementObjectType
    public static class ElementObjectTypeDomainEvent extends PropertyDomainEvent<String> {  }

    @Property(
            domainEvent = ElementObjectTypeDomainEvent.class,
            editing = Editing.DISABLED
            )
    @Getter
    private String elementTypeFqcn;


    // -- property: actionOwningType
    public static class ActionOwningTypeDomainEvent extends PropertyDomainEvent<String> {  }



    @Property(
            domainEvent = ActionOwningTypeDomainEvent.class,
            optionality = Optionality.OPTIONAL,
            editing = Editing.DISABLED
            )
    @Getter
    private String actionOwnerFqcn;

    // -- property: actionId
    public static class ActionIdDomainEvent extends PropertyDomainEvent<String> {  }

    private String actionId;

    @Property(
            domainEvent = ActionIdDomainEvent.class,
            optionality = Optionality.OPTIONAL,
            editing = Editing.DISABLED
            )
    public String getActionId() {
        return actionId;
    }


    // -- property: actionArguments
    public static class ActionArgumentsDomainEvent extends PropertyDomainEvent<String> {  }

    private String actionArguments;

    @Property(
            domainEvent = ActionArgumentsDomainEvent.class,
            optionality = Optionality.OPTIONAL,
            editing = Editing.DISABLED
            )
    public String getActionArguments() {
        return actionArguments;
    }


    // -- collection: objects
    public static class ObjectsDomainEvent extends CollectionDomainEvent<Object> {  }

    @XmlJavaTypeAdapter(PersistentEntitiesAdapter.class)
    private List<Object> objects = new ArrayList<>();

    @Collection(
            domainEvent = ObjectsDomainEvent.class
            )
    public List<Object> getObjects() {
        return objects;
    }

    public void setObjects(final List<Object> objects) {
        this.objects = objects;
    }


}

@@ -2466,20 +2466,20 @@
 onOwning
-Type
+Fqcn
 %22,%0A     
@@ -2560,26 +2560,24 @@
 %22element
-Object
 Type
+Fqcn
 %22,%0A     
@@ -4214,26 +4214,27 @@
 ng actionOwn
-er
+ing
 Fqcn,%0A      
@@ -4400,26 +4400,27 @@
 is.actionOwn
-er
+ing
 Fqcn = actio
@@ -4419,26 +4419,27 @@
  = actionOwn
-er
+ing
 Fqcn;%0A      
@@ -5285,18 +5285,19 @@
 ctionOwn
-er
+ing
 Fqcn;%0A%0A 

align names in DomainObjectList