You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2016/02/03 22:23:40 UTC
[1/3] isis git commit: ISIS-993: normalizing the BS3 grid,
factoring out commonalities into superclass.
Repository: isis
Updated Branches:
refs/heads/ISIS-993 63d03d29b -> 8fcac9648
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
index 820f8c0..cf18f80 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
@@ -16,7 +16,6 @@
*/
package org.apache.isis.core.metamodel.services.grid.fixedcols;
-import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -30,7 +29,6 @@ import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.ActionLayoutData;
import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
import org.apache.isis.applib.layout.common.CollectionLayoutData;
@@ -69,63 +67,25 @@ import org.apache.isis.core.metamodel.facets.properties.propertylayout.MultiLine
import org.apache.isis.core.metamodel.facets.properties.propertylayout.NamedFacetForPropertyXml;
import org.apache.isis.core.metamodel.facets.properties.propertylayout.RenderedAdjustedFacetForPropertyXml;
import org.apache.isis.core.metamodel.facets.properties.propertylayout.TypicalLengthFacetForPropertyXml;
-import org.apache.isis.core.metamodel.services.grid.GridNormalizerService;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.services.grid.GridNormalizerServiceAbstract;
import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
@DomainService(
nature = NatureOfService.DOMAIN
)
-public class GridNormalizerServiceFC implements GridNormalizerService {
+public class GridNormalizerServiceFC extends GridNormalizerServiceAbstract {
public static final String TNS = "http://isis.apache.org/schema/applib/layout/fixedcols";
public static final String SCHEMA_LOCATION = "http://isis.apache.org/schema/applib/layout/fixedcols/fixedcols.xsd";
-
- @Programmatic
- @Override
- public Class<? extends Grid> gridImplementation() {
- return FCGrid.class;
- }
-
- @Programmatic
- @Override
- public String tns() {
- return TNS;
- }
-
- @Programmatic
- @Override
- public String schemaLocation() {
- return SCHEMA_LOCATION;
+ public GridNormalizerServiceFC() {
+ super(FCGrid.class, TNS, SCHEMA_LOCATION);
}
- @Programmatic
- @Override
- public void normalize(final Grid grid, final Class<?> domainClass) {
-
- final FCGrid fcGrid = (FCGrid) grid;
-
- final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
-
- final Map<String, OneToOneAssociation> oneToOneAssociationById =
- ObjectMember.Util.mapById(getOneToOneAssociations(objectSpec));
- final Map<String, OneToManyAssociation> oneToManyAssociationById =
- ObjectMember.Util.mapById(getOneToManyAssociations(objectSpec));
- final Map<String, ObjectAction> objectActionById =
- ObjectMember.Util.mapById(objectSpec.getObjectActions(Contributed.INCLUDED));
-
- derive(fcGrid, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
- overwrite(fcGrid, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
- }
-
/**
* Ensures that all object members (properties, collections and actions) are in the metadata.
*
@@ -133,23 +93,26 @@ public class GridNormalizerServiceFC implements GridNormalizerService {
* If they are missing then they will be added to default tabs (created on the fly if need be).
* </p>
*/
- private static void derive(
- final FCGrid metadata,
- final Map<String, OneToOneAssociation> oneToOneAssociationById,
- final Map<String, OneToManyAssociation> oneToManyAssociationById,
- final Map<String, ObjectAction> objectActionById) {
+ @Override
+ protected boolean validateAndDerive(
+ final Grid grid,
+ final Map oneToOneAssociationById,
+ final Map oneToManyAssociationById,
+ final Map objectActionById) {
+
+ final FCGrid fcGrid = (FCGrid) grid;
- final LinkedHashMap<String, PropertyLayoutData> propertyIds = metadata.getAllPropertiesById();
- final LinkedHashMap<String, CollectionLayoutData> collectionIds = metadata.getAllCollectionsById();
- final LinkedHashMap<String, ActionLayoutData> actionIds = metadata.getAllActionsById();
+ final LinkedHashMap<String, PropertyLayoutData> propertyIds = fcGrid.getAllPropertiesById();
+ final LinkedHashMap<String, CollectionLayoutData> collectionIds = fcGrid.getAllCollectionsById();
+ final LinkedHashMap<String, ActionLayoutData> actionIds = fcGrid.getAllActionsById();
- final AtomicReference<FieldSet> defaultPropertyGroupRef = new AtomicReference<>();
+ final AtomicReference<FieldSet> defaultFieldSetRef = new AtomicReference<>();
final AtomicReference<FCColumn> firstColumnRef = new AtomicReference<>();
final AtomicReference<FCTabGroup> lastTabGroupRef = new AtomicReference<>();
// capture the first column, and also
// capture the first property group (if any) with the default name ('General')
- metadata.visit(new FCGrid.VisitorAdapter() {
+ fcGrid.visit(new FCGrid.VisitorAdapter() {
@Override
public void visit(final FCColumn fcColumn) {
firstColumnRef.compareAndSet(null, fcColumn);
@@ -157,7 +120,7 @@ public class GridNormalizerServiceFC implements GridNormalizerService {
@Override
public void visit(final FieldSet fieldSet) {
if(MemberGroupLayoutFacet.DEFAULT_GROUP.equals(fieldSet.getName())) {
- defaultPropertyGroupRef.compareAndSet(null, fieldSet);
+ defaultFieldSetRef.compareAndSet(null, fieldSet);
}
}
@Override
@@ -179,8 +142,8 @@ public class GridNormalizerServiceFC implements GridNormalizerService {
if(!missingPropertyIds.isEmpty()) {
// ensure that there is a property group to use
- boolean wasSet = defaultPropertyGroupRef.compareAndSet(null, new FieldSet(MemberGroupLayoutFacet.DEFAULT_GROUP));
- final FieldSet defaultFieldSet = defaultPropertyGroupRef.get();
+ boolean wasSet = defaultFieldSetRef.compareAndSet(null, new FieldSet(MemberGroupLayoutFacet.DEFAULT_GROUP));
+ final FieldSet defaultFieldSet = defaultFieldSetRef.get();
if(wasSet) {
firstColumnRef.get().getFieldSets().add(defaultFieldSet);
}
@@ -201,9 +164,9 @@ public class GridNormalizerServiceFC implements GridNormalizerService {
}
if(!missingCollectionIds.isEmpty()) {
- while(metadata.getTabGroups().size() < 2) {
+ while(fcGrid.getTabGroups().size() < 2) {
final FCTabGroup tabGroup = new FCTabGroup();
- metadata.getTabGroups().add(tabGroup);
+ fcGrid.getTabGroups().add(tabGroup);
lastTabGroupRef.set(tabGroup);
}
final FCTabGroup lastTabGroup = lastTabGroupRef.get();
@@ -229,203 +192,16 @@ public class GridNormalizerServiceFC implements GridNormalizerService {
if(!missingActionIds.isEmpty()) {
for (String actionId : missingActionIds) {
- List<ActionLayoutData> actions = metadata.getActions();
+ List<ActionLayoutData> actions = fcGrid.getActions();
if(actions == null) {
actions = Lists.newArrayList();
- metadata.setActions(actions);
+ fcGrid.setActions(actions);
}
actions.add(new ActionLayoutData(actionId));
}
}
+ return true;
}
- static class Tuple<T> {
- final T first;
- final T second;
- private Tuple(final T first, final T second) {
- this.first = first;
- this.second = second;
- }
- public static <T> Tuple<T> of(final T first, final T second) {
- return new Tuple<>(first, second);
- }
- }
- /**
- * Returns a 2-element tuple of [first-second, second-first]
- */
- static <T> Tuple<List<T>> surplusAndMissing(final Collection<T> first, final Collection<T> second){
- final List<T> firstNotSecond = Lists.newArrayList(first);
- firstNotSecond.removeAll(second);
- final List<T> secondNotFirst = Lists.newArrayList(second);
- secondNotFirst.removeAll(first);
- return Tuple.of(firstNotSecond, secondNotFirst);
- }
-
- private void overwrite(
- final FCGrid page,
- final Map<String, OneToOneAssociation> oneToOneAssociationById,
- final Map<String, OneToManyAssociation> oneToManyAssociationById,
- final Map<String, ObjectAction> objectActionById) {
-
- final Map<String, int[]> propertySequenceByGroup = Maps.newHashMap();
-
- page.visit(new FCGrid.VisitorAdapter() {
- private int collectionSequence = 1;
- private int actionDomainObjectSequence = 1;
- private int actionPropertyGroupSequence = 1;
- private int actionPropertySequence = 1;
- private int actionCollectionSequence = 1;
-
- @Override
- public void visit(final ActionLayoutData actionLayoutData) {
- final ActionLayoutDataOwner actionLayoutDataOwner = actionLayoutData.getOwner();
- final ObjectAction objectAction = objectActionById.get(actionLayoutData.getId());
- if(objectAction == null) {
- return;
- }
-
- final String memberOrderName;
- final int memberOrderSequence;
- if(actionLayoutDataOwner instanceof FieldSet) {
- final FieldSet fieldSet = (FieldSet) actionLayoutDataOwner;
- final List<PropertyLayoutData> properties = fieldSet.getProperties();
- final PropertyLayoutData propertyLayoutData = properties.get(0); // any will do
- memberOrderName = propertyLayoutData.getId();
- memberOrderSequence = actionPropertyGroupSequence++;
- } else if(actionLayoutDataOwner instanceof PropertyLayoutData) {
- final PropertyLayoutData propertyLayoutData = (PropertyLayoutData) actionLayoutDataOwner;
- memberOrderName = propertyLayoutData.getId();
- memberOrderSequence = actionPropertySequence++;
- } else if(actionLayoutDataOwner instanceof CollectionLayoutData) {
- final CollectionLayoutData collectionLayoutData = (CollectionLayoutData) actionLayoutDataOwner;
- memberOrderName = collectionLayoutData.getId();
- memberOrderSequence = actionCollectionSequence++;
- } else {
- // DomainObject
- memberOrderName = null;
- memberOrderSequence = actionDomainObjectSequence++;
- }
- FacetUtil.addFacet(
- new MemberOrderFacetXml(memberOrderName, ""+memberOrderSequence, translationService, objectAction));
-
-
- if(actionLayoutDataOwner instanceof FieldSet) {
- if(actionLayoutData.getPosition() == null ||
- actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
- actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.RIGHT) {
- actionLayoutData.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.PANEL);
- }
- } else if(actionLayoutDataOwner instanceof PropertyLayoutData) {
- if(actionLayoutData.getPosition() == null ||
- actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL_DROPDOWN ||
- actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL) {
- actionLayoutData.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.BELOW);
- }
- } else {
- // doesn't do anything for DomainObject or Collection
- actionLayoutData.setPosition(null);
- }
-
- FacetUtil.addFacet(ActionPositionFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(BookmarkPolicyFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(CssClassFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(CssClassFaFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(DescribedAsFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(HiddenFacetForActionLayoutXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(NamedFacetForActionXml.create(actionLayoutData, objectAction));
- }
-
- @Override
- public void visit(final PropertyLayoutData propertyLayoutData) {
- final OneToOneAssociation oneToOneAssociation = oneToOneAssociationById.get(propertyLayoutData.getId());
- if(oneToOneAssociation == null) {
- return;
- }
-
- FacetUtil.addFacet(CssClassFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(DescribedAsFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(HiddenFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(LabelAtFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(MultiLineFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(NamedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(
- RenderedAdjustedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(TypicalLengthFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
-
- // @MemberOrder#name based on owning property group, @MemberOrder#sequence monotonically increasing
- final FieldSet fieldSet = propertyLayoutData.getOwner();
- final String groupName = fieldSet.getName();
- final String sequence = nextInSequenceFor(groupName, propertySequenceByGroup);
- FacetUtil.addFacet(
- new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
- }
-
- @Override
- public void visit(final CollectionLayoutData collectionLayoutData) {
- final OneToManyAssociation oneToManyAssociation = oneToManyAssociationById.get(collectionLayoutData.getId());
- if(oneToManyAssociation == null) {
- return;
- }
-
- FacetUtil.addFacet(CssClassFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(
- DefaultViewFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(
- DescribedAsFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(HiddenFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(NamedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(PagedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(SortedByFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
-
- // @MemberOrder#name based on the collection's id (so that each has a single "member group")
- final String groupName = collectionLayoutData.getId();
- final String sequence = "" + collectionSequence++;
- FacetUtil.addFacet(
- new MemberOrderFacetXml(groupName, sequence, translationService, oneToManyAssociation));
-
- // if there is only a single column and no other contents, then copy the collection Id onto the tab'
- final MemberRegionOwner memberRegionOwner = collectionLayoutData.getOwner();
- if(memberRegionOwner instanceof FCColumn) {
- final FCColumn FCColumn = (FCColumn) memberRegionOwner;
- final FCColumnOwner holder = FCColumn.getOwner();
- if(holder instanceof FCTab) {
- final FCTab FCTab = (FCTab) holder;
- if(FCTab.getContents().size() == 1 && Strings.isNullOrEmpty(FCTab.getName()) ) {
- final String collectionName = oneToManyAssociation.getName();
- FCTab.setName(collectionName);
- }
- }
- }
- }
- });
- }
-
- private String nextInSequenceFor(
- final String key, final Map<String, int[]> seqByKey) {
- synchronized (seqByKey) {
- int[] holder = seqByKey.get(key);
- if(holder == null) {
- holder = new int[]{0};
- seqByKey.put(key, holder);
- }
- holder[0]++;
- return ""+holder[0];
- }
- }
-
- private static List<OneToOneAssociation> getOneToOneAssociations(final ObjectSpecification objectSpec) {
- List associations = objectSpec.getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.PROPERTIES);
- return associations;
- }
- private static List<OneToManyAssociation> getOneToManyAssociations(final ObjectSpecification objectSpec) {
- List associations = objectSpec.getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.COLLECTIONS);
- return associations;
- }
-
- @Inject
- SpecificationLoader specificationLookup;
- @Inject
- TranslationService translationService;
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
index 1be3c4b..1fe5b48 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
@@ -22,7 +22,7 @@ package org.apache.isis.viewer.wicket.ui.components.layout.bs3;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.repeater.RepeatingView;
-import org.apache.isis.applib.layout.bootstrap3.BS3ElementAbstract;
+import org.apache.isis.applib.layout.bootstrap3.BS3Element;
import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
import org.apache.isis.applib.layout.bootstrap3.BS3Row;
import org.apache.isis.viewer.wicket.model.models.EntityModel;
@@ -49,8 +49,7 @@ public class BS3GridPanel extends PanelAbstract<EntityModel> {
final RepeatingView rv = new RepeatingView(ID_ROWS);
- final BS3ElementAbstract element = this.bs3Page;
-
+ final BS3Element element = this.bs3Page;
for(final BS3Row bs3Row: this.bs3Page.getRows()) {
final String id = rv.newChildId();
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Util.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Util.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Util.java
index 0b189e3..06d8877 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Util.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Util.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.wicket.ui.components.layout.bs3;
import org.apache.wicket.MarkupContainer;
+import org.apache.isis.applib.layout.bootstrap3.BS3Element;
import org.apache.isis.applib.layout.bootstrap3.BS3ElementAbstract;
import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
@@ -28,7 +29,7 @@ public class Util {
private Util(){}
- public static void appendCssClassIfRequired(final MarkupContainer markupContainer, final BS3ElementAbstract element) {
+ public static void appendCssClassIfRequired(final MarkupContainer markupContainer, final BS3Element element) {
final String cssClass = element.getCssClass();
if(cssClass != null) {
CssClassAppender.appendCssClassTo(markupContainer, cssClass);
[3/3] isis git commit: ISIS-993: unreferenced
properties/actions/collectoins handling
Posted by da...@apache.org.
ISIS-993: unreferenced properties/actions/collectoins handling
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/8fcac964
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/8fcac964
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/8fcac964
Branch: refs/heads/ISIS-993
Commit: 8fcac96481cb21a47d8db0a64a76fa4693d5582d
Parents: fe46a78
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Feb 3 21:22:30 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Feb 3 21:22:30 2016 +0000
----------------------------------------------------------------------
.../applib/layout/bootstrap3/bootstrap3.xsd | 29 ++-
.../schema/applib/layout/common/common.xsd | 6 +-
.../isis/applib/layout/bootstrap3/BS3Col.java | 41 +---
.../isis/applib/layout/bootstrap3/BS3Grid.java | 31 ++-
.../isis/applib/layout/bootstrap3/BS3Row.java | 15 +-
.../isis/applib/layout/bootstrap3/BS3Tab.java | 7 +-
.../applib/layout/bootstrap3/BS3TabGroup.java | 54 ++++-
.../isis/applib/layout/common/FieldSet.java | 81 +++++++-
.../isis/applib/layout/common/GridAbstract.java | 2 +-
.../applib/layout/fixedcols/FCTabGroup.java | 9 +-
.../isis/core/metamodel/facetapi/FacetUtil.java | 21 +-
.../facets/object/grid/GridFacetDefault.java | 3 +
.../grid/GridNormalizerServiceAbstract.java | 110 ++++++----
.../bootstrap3/GridNormalizerServiceBS3.java | 201 +++++++++++++------
.../grid/fixedcols/GridNormalizerServiceFC.java | 39 +---
.../metamodel/services/grid/BS3GridTest.java | 24 ++-
.../java/domainapp/dom/simple/SimpleObject.java | 2 +
.../dom/simple/SimpleObject.layout.xml | 70 +++----
18 files changed, 473 insertions(+), 272 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/adocs/documentation/src/main/asciidoc/schema/applib/layout/bootstrap3/bootstrap3.xsd
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/schema/applib/layout/bootstrap3/bootstrap3.xsd b/adocs/documentation/src/main/asciidoc/schema/applib/layout/bootstrap3/bootstrap3.xsd
index 7259fcc..12c9de7 100644
--- a/adocs/documentation/src/main/asciidoc/schema/applib/layout/bootstrap3/bootstrap3.xsd
+++ b/adocs/documentation/src/main/asciidoc/schema/applib/layout/bootstrap3/bootstrap3.xsd
@@ -12,18 +12,10 @@
<xs:element name="grid" type="tns:grid"/>
<xs:complexType name="grid">
- <xs:complexContent>
- <xs:extension base="tns:bs3ElementAbstract">
- <xs:sequence>
- <xs:element name="row" type="tns:row" maxOccurs="unbounded"/>
- <xs:element name="metadataErrors" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:complexType name="bs3ElementAbstract" abstract="true">
- <xs:sequence/>
+ <xs:sequence>
+ <xs:element name="row" type="tns:row" maxOccurs="unbounded"/>
+ <xs:element name="metadataError" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
<xs:attribute name="cssClass" type="xs:string"/>
</xs:complexType>
@@ -36,12 +28,18 @@
<xs:element ref="tns:clearFixVisible"/>
<xs:element ref="tns:clearFixHidden"/>
</xs:choice>
+ <xs:element name="metadataError" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
+ <xs:complexType name="bs3ElementAbstract" abstract="true">
+ <xs:sequence/>
+ <xs:attribute name="cssClass" type="xs:string"/>
+ </xs:complexType>
+
<xs:complexType name="col">
<xs:complexContent>
<xs:extension base="tns:bs3RowContent">
@@ -52,12 +50,11 @@
<xs:element name="tabGroup" type="tns:tabGroup" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="ns1:fieldSet" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="ns1:collection" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="metadataError" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="span" type="xs:int" use="required"/>
<xs:attribute name="unreferencedActions" type="xs:boolean"/>
- <xs:attribute name="unreferencedCollections" type="xs:boolean"/>
- <xs:attribute name="unreferencedProperties" type="xs:boolean"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -75,8 +72,10 @@
<xs:complexContent>
<xs:extension base="tns:bs3ElementAbstract">
<xs:sequence>
- <xs:element name="tab" type="tns:tab" maxOccurs="unbounded"/>
+ <xs:element name="tab" type="tns:tab" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="metadataError" type="xs:string" minOccurs="0"/>
</xs:sequence>
+ <xs:attribute name="unreferencedCollections" type="xs:boolean"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/adocs/documentation/src/main/asciidoc/schema/applib/layout/common/common.xsd
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/schema/applib/layout/common/common.xsd b/adocs/documentation/src/main/asciidoc/schema/applib/layout/common/common.xsd
index 992a378..5b614a9 100644
--- a/adocs/documentation/src/main/asciidoc/schema/applib/layout/common/common.xsd
+++ b/adocs/documentation/src/main/asciidoc/schema/applib/layout/common/common.xsd
@@ -43,9 +43,13 @@
<xs:complexType name="fieldSet">
<xs:sequence>
<xs:element ref="tns:action" minOccurs="0" maxOccurs="unbounded"/>
- <xs:element ref="tns:property" maxOccurs="unbounded"/>
+ <xs:element ref="tns:property" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="metadataError" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="id" type="xs:string"/>
+ <xs:attribute name="unreferencedActions" type="xs:boolean"/>
+ <xs:attribute name="unreferencedProperties" type="xs:boolean"/>
</xs:complexType>
<xs:complexType name="property">
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
index 752c7e4..f51fcba 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
@@ -118,43 +118,6 @@ public class BS3Col extends BS3RowContent
}
- private Boolean unreferencedProperties;
- /**
- * Whether the first fieldset in this column should be used to hold any unreferenced properties (contributed or "native").
- *
- * <p>
- * Any layout must have precisely one column that has this attribute set, and that column must have at least one {@link FieldSet}.
- * </p>
- */
- @XmlAttribute(required = false)
- public Boolean isUnreferencedProperties() {
- return unreferencedProperties;
- }
-
- public void setUnreferencedProperties(final Boolean unreferencedProperties) {
- this.unreferencedProperties = unreferencedProperties;
- }
-
-
- private Boolean unreferencedCollections;
- /**
- * Whether this column should be used to hold any unreferenced collections (contributed or "native").
- *
- * <p>
- * Any layout must have precisely one column that has this attribute set.
- * </p>
- */
- @XmlAttribute(required = false)
- public Boolean isUnreferencedCollections() {
- return unreferencedCollections;
- }
-
- public void setUnreferencedCollections(final Boolean unreferencedCollections) {
- this.unreferencedCollections = unreferencedCollections;
- }
-
-
-
private DomainObjectLayoutData domainObject;
@@ -241,6 +204,10 @@ public class BS3Col extends BS3RowContent
}
+ @Override
+ public String getPath() {
+ return getId() != null? getId(): super.getPath();
+ }
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
index 6360480..f5e9d5d 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.applib.layout.bootstrap3;
-import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@@ -28,6 +27,7 @@ import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.Programmatic;
@@ -54,8 +54,8 @@ import org.apache.isis.applib.services.dto.Dto;
@XmlType(
name = "grid"
, propOrder = {
- "rows"
- , "metadataErrors"
+ "rows",
+ "metadataErrors"
}
)
public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwner {
@@ -91,9 +91,7 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
- private List<BS3Row> rows = new ArrayList<BS3Row>(){{
- add(new BS3Row());
- }};
+ private List<BS3Row> rows = Lists.newArrayList();
// no wrapper
@XmlElement(name = "row", required = true)
@@ -107,6 +105,27 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
+ private List<String> metadataErrors = Lists.newArrayList();
+
+ /**
+ * For diagnostics; populated by the framework if and only if a metadata error.
+ */
+ @XmlElement(name = "metadataError", required = false)
+ public List<String> getMetadataErrors() {
+ return metadataErrors;
+ }
+
+ public void setMetadataErrors(final List<String> metadataErrors) {
+ this.metadataErrors = metadataErrors;
+ }
+
+
+
+
+ private BS3RowOwner owner;
+
+
+
interface Visitor extends Grid.Visitor {
void visit(final BS3Grid bs3Page);
void visit(final BS3Row bs3Row);
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
index d05dbf8..097c883 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.applib.layout.bootstrap3;
-import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
@@ -28,6 +27,8 @@ import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import com.google.common.collect.Lists;
+
/**
* Contains a row of content, either on the top-level {@link BS3Grid page} or at any other lower-level element that can
* contain rows, eg {@link BS3Tab tabs}.
@@ -64,9 +65,7 @@ public class BS3Row extends BS3ElementAbstract implements HasCssId, BS3RowConten
- private List<BS3RowContent> cols = new ArrayList<BS3RowContent>(){{
- add(new BS3Col());
- }};
+ private List<BS3RowContent> cols = Lists.newArrayList();
// no wrapper
@XmlElementRefs({
@@ -84,6 +83,13 @@ public class BS3Row extends BS3ElementAbstract implements HasCssId, BS3RowConten
+ @Override
+ public String getPath() {
+ return getId() != null? getId(): super.getPath();
+ }
+
+
+
private String metadataError;
/**
@@ -101,6 +107,7 @@ public class BS3Row extends BS3ElementAbstract implements HasCssId, BS3RowConten
private BS3RowOwner owner;
+
/**
* Owner.
*
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Tab.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Tab.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Tab.java
index 57e7ca5..f1d4256 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Tab.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Tab.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.applib.layout.bootstrap3;
-import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
@@ -27,6 +26,7 @@ import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
/**
* Represents a tab within a {@link BS3TabGroup tab group}.
@@ -57,10 +57,7 @@ public class BS3Tab extends BS3ElementAbstract implements BS3RowOwner {
}
- // at least one row
- private List<BS3Row> rows = new ArrayList<BS3Row>(){{
- add(new BS3Row());
- }};
+ private List<BS3Row> rows = Lists.newArrayList();
// no wrapper
@XmlElement(name = "row", required = true)
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3TabGroup.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3TabGroup.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3TabGroup.java
index c96634a..6f65bf7 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3TabGroup.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3TabGroup.java
@@ -18,20 +18,23 @@
*/
package org.apache.isis.applib.layout.bootstrap3;
-import java.util.ArrayList;
import java.util.List;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import com.google.common.collect.Lists;
+
/**
* Represents a tab group containing one or more {@link BS3Tab tab}s.
*/
@XmlType(
name = "tabGroup"
, propOrder = {
- "tabs"
+ "tabs",
+ "metadataError"
}
)
public class BS3TabGroup extends BS3ElementAbstract implements BS3TabOwner {
@@ -39,12 +42,31 @@ public class BS3TabGroup extends BS3ElementAbstract implements BS3TabOwner {
private static final long serialVersionUID = 1L;
- private List<BS3Tab> tabs = new ArrayList<BS3Tab>(){{
- add(new BS3Tab());
- }};
- // no wrapper
- @XmlElement(name = "tab", required = true)
+ private Boolean unreferencedCollections;
+ /**
+ * Whether this column should be used to hold any unreferenced collections (contributed or "native").
+ *
+ * <p>
+ * Any layout must have precisely one column that has this attribute set.
+ * </p>
+ */
+ @XmlAttribute(required = false)
+ public Boolean isUnreferencedCollections() {
+ return unreferencedCollections;
+ }
+
+ public void setUnreferencedCollections(final Boolean unreferencedCollections) {
+ this.unreferencedCollections = unreferencedCollections;
+ }
+
+
+
+
+ private List<BS3Tab> tabs = Lists.newArrayList();
+
+ // no wrapper; required=false because may be auto-generated
+ @XmlElement(name = "tab", required = false)
public List<BS3Tab> getTabs() {
return tabs;
}
@@ -72,5 +94,23 @@ public class BS3TabGroup extends BS3ElementAbstract implements BS3TabOwner {
this.owner = owner;
}
+
+
+ private String metadataError;
+
+ /**
+ * For diagnostics; populated by the framework if and only if a metadata error.
+ */
+ @XmlElement(required = false)
+ public String getMetadataError() {
+ return metadataError;
+ }
+
+ public void setMetadataError(final String metadataError) {
+ this.metadataError = metadataError;
+ }
+
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
index fe0a3fb..40769eb 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
@@ -19,7 +19,6 @@
package org.apache.isis.applib.layout.common;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@@ -49,6 +48,7 @@ import org.apache.isis.applib.annotation.Programmatic;
"name"
, "actions"
, "properties"
+ , "metadataError"
}
)
public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializable {
@@ -62,6 +62,63 @@ public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializab
setName(name);
}
+
+
+ private String id;
+
+ /**
+ * As per <div id="...">...</div> : must be unique across entire page.
+ */
+ @XmlAttribute(required = false)
+ public String getId() {
+ return id;
+ }
+
+ public void setId(final String id) {
+ this.id = id;
+ }
+
+
+
+ private Boolean unreferencedActions;
+
+ /**
+ * Whether this fieldset should be used to hold any unreferenced actions (contributed or "native").
+ *
+ * <p>
+ * Any layout must have precisely one fieldset that has this attribute set.
+ * </p>
+ */
+ @XmlAttribute(required = false)
+ public Boolean isUnreferencedActions() {
+ return unreferencedActions;
+ }
+
+ public void setUnreferencedActions(final Boolean unreferencedActions) {
+ this.unreferencedActions = unreferencedActions;
+ }
+
+
+ private Boolean unreferencedProperties;
+ /**
+ * Whether this fieldset should be used to hold any unreferenced properties (contributed or "native").
+ *
+ * <p>
+ * Any grid layout must have precisely one fieldset that has this attribute set.
+ * </p>
+ */
+ @XmlAttribute(required = false)
+ public Boolean isUnreferencedProperties() {
+ return unreferencedProperties;
+ }
+
+ public void setUnreferencedProperties(final Boolean unreferencedProperties) {
+ this.unreferencedProperties = unreferencedProperties;
+ }
+
+
+
+
private String name;
/**
@@ -92,11 +149,10 @@ public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializab
- private List<PropertyLayoutData> properties = new ArrayList<PropertyLayoutData>() {{
- add(new PropertyLayoutData());
- }};
+ private List<PropertyLayoutData> properties = Lists.newArrayList();
- @XmlElement(name = "property", required = true)
+ // no wrapper; required=false because may be auto-generated
+ @XmlElement(name = "property", required = false)
public List<PropertyLayoutData> getProperties() {
return properties;
}
@@ -141,6 +197,21 @@ public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializab
+ private String metadataError;
+
+ /**
+ * For diagnostics; populated by the framework if and only if a metadata error.
+ */
+ @XmlElement(required = false)
+ public String getMetadataError() {
+ return metadataError;
+ }
+
+ public void setMetadataError(final String metadataError) {
+ this.metadataError = metadataError;
+ }
+
+
public static class Util {
private Util(){}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
index 70cee11..2efb85c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
@@ -27,7 +27,6 @@ import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
import org.apache.isis.applib.services.layout.GridService;
/**
@@ -37,6 +36,7 @@ import org.apache.isis.applib.services.layout.GridService;
* It is used by the {@link GridService} as a common based type for any layouts read in from XML.
* </p>
*/
+@XmlTransient // ignore this class
public abstract class GridAbstract implements Grid {
private boolean normalized;
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
index 567f278..d4ad9dc 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
@@ -19,7 +19,6 @@
package org.apache.isis.applib.layout.fixedcols;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
@@ -28,6 +27,7 @@ import javax.xml.bind.annotation.XmlType;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.Owned;
@@ -42,13 +42,10 @@ public class FCTabGroup implements FCColumnOwner, Serializable, Owned<FCTabGroup
private static final long serialVersionUID = 1L;
- // must be at least one tab.
- private List<FCTab> tabs = new ArrayList<FCTab>(){{
- add(new FCTab());
- }};
+ private List<FCTab> tabs = Lists.newArrayList();
// no wrapper
- @XmlElement(name = "tab", required = true)
+ @XmlElement(name = "tab", required = false)
public List<FCTab> getTabs() {
return tabs;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
index b5e67f7..8d9eb73 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
@@ -33,6 +33,26 @@ public final class FacetUtil {
private FacetUtil() {
}
+ public static void addOrReplaceFacet(final Facet facet) {
+ if (facet == null) {
+ return;
+ }
+ final FacetHolder facetHolder = facet.getFacetHolder();
+ final List<Facet> facets = facetHolder.getFacets(new Filter<Facet>() {
+ @Override
+ public boolean accept(final Facet each) {
+ return facet.facetType() == each.facetType() && facet.getClass() == each.getClass();
+ }
+ });
+ if(facets.size() == 1) {
+ final Facet existingFacet = facets.get(0);
+ final Facet underlyingFacet = existingFacet.getUnderlyingFacet();
+ facetHolder.removeFacet(existingFacet);
+ facet.setUnderlyingFacet(underlyingFacet);
+ }
+ facetHolder.addFacet(facet);
+ }
+
/**
* Attaches the {@link Facet} to its {@link Facet#getFacetHolder() facet
* holder}.
@@ -151,5 +171,4 @@ public final class FacetUtil {
}
}
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
index f2de0fc..596829d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
@@ -104,6 +104,9 @@ public class GridFacetDefault
final Class<?> domainClass = getSpecification().getCorrespondingClass();
gridNormalizerService.normalize(grid, domainClass);
+
+ grid.setNormalized(true);
+
return grid;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
index 1c0ab06..91d8aba 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
@@ -26,6 +26,10 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.ActionLayoutData;
import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
@@ -39,6 +43,8 @@ import org.apache.isis.applib.layout.fixedcols.FCColumnOwner;
import org.apache.isis.applib.layout.fixedcols.FCGrid;
import org.apache.isis.applib.layout.fixedcols.FCTab;
import org.apache.isis.applib.services.i18n.TranslationService;
+import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetUtil;
import org.apache.isis.core.metamodel.facets.actions.layout.ActionPositionFacetForActionXml;
import org.apache.isis.core.metamodel.facets.actions.layout.BookmarkPolicyFacetForActionXml;
@@ -65,6 +71,7 @@ import org.apache.isis.core.metamodel.facets.properties.propertylayout.RenderedA
import org.apache.isis.core.metamodel.facets.properties.propertylayout.TypicalLengthFacetForPropertyXml;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
@@ -72,7 +79,10 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-public abstract class GridNormalizerServiceAbstract<G extends Grid> implements GridNormalizerService<G> {
+public abstract class GridNormalizerServiceAbstract<G extends Grid>
+ implements GridNormalizerService<G>, SpecificationLoaderAware {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GridNormalizerServiceAbstract.class);
private final Class<G> gridImplementation;
private final String tns;
@@ -118,9 +128,17 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
final Map<String, ObjectAction> objectActionById =
ObjectMember.Util.mapById(objectSpec.getObjectActions(Contributed.INCLUDED));
- final boolean validation = validateAndDerive(grid, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
- if(validation) {
+ final boolean valid =
+ validateAndDerive(
+ grid, oneToOneAssociationById, oneToManyAssociationById, objectActionById, objectSpec);
+ if (valid) {
overwrite(grid, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("Grid:\n\n" + jaxbService.toXml(grid) + "\n\n");
+ }
+ } else {
+ container.warnUser("Grid metadata errors; check the error log");
+ LOG.error("Grid metadata errors:\n\n" + jaxbService.toXml(grid) + "\n\n");
}
}
@@ -131,11 +149,16 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
final Grid grid,
final Map<String, OneToOneAssociation> oneToOneAssociationById,
final Map<String, OneToManyAssociation> oneToManyAssociationById,
- final Map<String, ObjectAction> objectActionById);
-
-
-
+ final Map<String, ObjectAction> objectActionById,
+ final ObjectSpecification objectSpec);
+ /**
+ * Overwrites (replaces) any existing facets in the metamodel with info taken from the grid.
+ *
+ * <p>
+ * This code uses {@link FacetUtil#addOrReplaceFacet(Facet)} because the layout might be changed multiple times.
+ * </p>
+ */
protected void overwrite(
final G fcGrid,
final Map<String, OneToOneAssociation> oneToOneAssociationById,
@@ -143,9 +166,9 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
final Map<String, ObjectAction> objectActionById) {
final Map<String, int[]> propertySequenceByGroup = Maps.newHashMap();
-
fcGrid.visit(new FCGrid.VisitorAdapter() {
private int collectionSequence = 1;
+
private int actionDomainObjectSequence = 1;
private int actionPropertyGroupSequence = 1;
private int actionPropertySequence = 1;
@@ -176,14 +199,17 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
memberOrderName = collectionLayoutData.getId();
memberOrderSequence = actionCollectionSequence++;
} else {
- // DomainObject
+ // means' don't add: any existing metadata should be preserved
memberOrderName = null;
memberOrderSequence = actionDomainObjectSequence++;
}
- FacetUtil.addFacet(
- new MemberOrderFacetXml(memberOrderName, ""+memberOrderSequence, translationService, objectAction));
-
+ if(memberOrderName != null) {
+ FacetUtil.addOrReplaceFacet(
+ new MemberOrderFacetXml(memberOrderName, "" + memberOrderSequence, translationService,
+ objectAction));
+ }
+ // fix up the action position if required
if(actionLayoutDataOwner instanceof FieldSet) {
if(actionLayoutData.getPosition() == null ||
actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
@@ -201,13 +227,13 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
actionLayoutData.setPosition(null);
}
- FacetUtil.addFacet(ActionPositionFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(BookmarkPolicyFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(CssClassFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(CssClassFaFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(DescribedAsFacetForActionXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(HiddenFacetForActionLayoutXml.create(actionLayoutData, objectAction));
- FacetUtil.addFacet(NamedFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(ActionPositionFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(BookmarkPolicyFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(CssClassFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(CssClassFaFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(DescribedAsFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(HiddenFacetForActionLayoutXml.create(actionLayoutData, objectAction));
+ FacetUtil.addOrReplaceFacet(NamedFacetForActionXml.create(actionLayoutData, objectAction));
}
@Override
@@ -217,21 +243,21 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
return;
}
- FacetUtil.addFacet(CssClassFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(DescribedAsFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(HiddenFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(LabelAtFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(MultiLineFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(NamedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(
+ FacetUtil.addOrReplaceFacet(CssClassFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(DescribedAsFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(HiddenFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(LabelAtFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(MultiLineFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(NamedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(
RenderedAdjustedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
- FacetUtil.addFacet(TypicalLengthFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addOrReplaceFacet(TypicalLengthFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
// @MemberOrder#name based on owning property group, @MemberOrder#sequence monotonically increasing
final FieldSet fieldSet = propertyLayoutData.getOwner();
final String groupName = fieldSet.getName();
final String sequence = nextInSequenceFor(groupName, propertySequenceByGroup);
- FacetUtil.addFacet(
+ FacetUtil.addOrReplaceFacet(
new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
}
@@ -242,20 +268,20 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
return;
}
- FacetUtil.addFacet(CssClassFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(
+ FacetUtil.addOrReplaceFacet(CssClassFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addOrReplaceFacet(
DefaultViewFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(
+ FacetUtil.addOrReplaceFacet(
DescribedAsFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(HiddenFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(NamedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(PagedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
- FacetUtil.addFacet(SortedByFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addOrReplaceFacet(HiddenFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addOrReplaceFacet(NamedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addOrReplaceFacet(PagedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addOrReplaceFacet(SortedByFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
// @MemberOrder#name based on the collection's id (so that each has a single "member group")
final String groupName = collectionLayoutData.getId();
final String sequence = "" + collectionSequence++;
- FacetUtil.addFacet(
+ FacetUtil.addOrReplaceFacet(
new MemberOrderFacetXml(groupName, sequence, translationService, oneToManyAssociation));
// if there is only a single column and no other contents, then copy the collection Id onto the tab'
@@ -326,10 +352,20 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid> implements G
}
- @Inject
SpecificationLoader specificationLookup;
+
+ public void setSpecificationLoader(final SpecificationLoader specificationLookup) {
+ this.specificationLookup = specificationLookup;
+ }
+
@Inject
TranslationService translationService;
+ @Inject
+ JaxbService jaxbService;
+
+ @Inject
+ DomainObjectContainer container;
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
index a4f845a..5761965 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
@@ -21,6 +21,10 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
+import javax.annotation.Nullable;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -29,6 +33,7 @@ import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.layout.bootstrap3.BS3Col;
import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
import org.apache.isis.applib.layout.bootstrap3.BS3Row;
+import org.apache.isis.applib.layout.bootstrap3.BS3RowContent;
import org.apache.isis.applib.layout.bootstrap3.BS3Tab;
import org.apache.isis.applib.layout.bootstrap3.BS3TabGroup;
import org.apache.isis.applib.layout.common.ActionLayoutData;
@@ -36,9 +41,9 @@ import org.apache.isis.applib.layout.common.CollectionLayoutData;
import org.apache.isis.applib.layout.common.FieldSet;
import org.apache.isis.applib.layout.common.Grid;
import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
+import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
import org.apache.isis.core.metamodel.services.grid.GridNormalizerServiceAbstract;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
@@ -61,7 +66,7 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
final Grid grid,
final Map<String, OneToOneAssociation> oneToOneAssociationById,
final Map<String, OneToManyAssociation> oneToManyAssociationById,
- final Map<String, ObjectAction> objectActionById) {
+ final Map<String, ObjectAction> objectActionById, final ObjectSpecification objectSpec) {
final BS3Grid bs3Grid = (BS3Grid) grid;
@@ -117,53 +122,75 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
// unreferencedActions, unreferencedProperties and unreferencedCollections attribute set.
final AtomicReference<BS3Col> colForUnreferencedActionsRef = new AtomicReference<>();
- final AtomicReference<BS3Col> colForUnreferencedPropertiesRef = new AtomicReference<>();
- final AtomicReference<FieldSet> fieldSetForUnreferencedPropsRef = new AtomicReference<>();
- final AtomicReference<BS3Col> colForUnreferencedCollectionsRef = new AtomicReference<>();
+ final AtomicReference<FieldSet> fieldSetForUnreferencedActionsRef = new AtomicReference<>();
+ final AtomicReference<FieldSet> fieldSetForUnreferencedPropertiesRef = new AtomicReference<>();
+ final AtomicReference<BS3TabGroup> tabGroupForUnreferencedCollectionsRef = new AtomicReference<>();
bs3Grid.visit(new BS3Grid.VisitorAdapter(){
@Override
public void visit(final BS3Col bs3Col) {
- if(bs3Col.isUnreferencedActions()) {
+ if(isSet(bs3Col.isUnreferencedActions())) {
if(colForUnreferencedActionsRef.get() != null) {
bs3Col.setMetadataError("More than one col with 'unreferencedActions' attribute set");
+ } else if(fieldSetForUnreferencedActionsRef.get() != null) {
+ bs3Col.setMetadataError("Already found a fieldset with 'unreferencedActions' attribute set");
} else {
colForUnreferencedActionsRef.set(bs3Col);
}
}
- if(bs3Col.isUnreferencedProperties()) {
- if(colForUnreferencedPropertiesRef.get() != null) {
- bs3Col.setMetadataError("More than one col with 'unreferencedProperties' attribute set");
+ }
+
+ @Override
+ public void visit(final FieldSet fieldSet) {
+ if(isSet(fieldSet.isUnreferencedActions())) {
+ if(fieldSetForUnreferencedActionsRef.get() != null) {
+ fieldSet.setMetadataError("More than one fieldset with 'unreferencedActions' attribute set");
+ } else if(colForUnreferencedActionsRef.get() != null) {
+ fieldSet.setMetadataError("Already found a column with 'unreferencedActions' attribute set");
} else {
- final List<FieldSet> fieldSets = bs3Col.getFieldSets();
- for (FieldSet fieldSet : fieldSets) {
- if(fieldSet.getName().equals(MemberGroupLayoutFacet.DEFAULT_GROUP)) {
- fieldSetForUnreferencedPropsRef.set(fieldSet);
- }
- }
- colForUnreferencedPropertiesRef.set(bs3Col);
+ fieldSetForUnreferencedActionsRef.set(fieldSet);
}
}
- if(bs3Col.isUnreferencedCollections()) {
- if(colForUnreferencedCollectionsRef.get() != null) {
- bs3Col.setMetadataError("More than one col with 'unreferencedCollections' attribute set");
+ if(isSet(fieldSet.isUnreferencedProperties())) {
+ if(fieldSetForUnreferencedPropertiesRef.get() != null) {
+ fieldSet.setMetadataError("More than one col with 'unreferencedProperties' attribute set");
+ } else {
+ fieldSetForUnreferencedPropertiesRef.set(fieldSet);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final BS3TabGroup bs3TabGroup) {
+ if(isSet(bs3TabGroup.isUnreferencedCollections())) {
+ if(tabGroupForUnreferencedCollectionsRef.get() != null) {
+ bs3TabGroup.setMetadataError("More than one tabgroup with 'unreferencedCollections' attribute set");
} else {
- colForUnreferencedCollectionsRef.set(bs3Col);
+ tabGroupForUnreferencedCollectionsRef.set(bs3TabGroup);
}
}
}
});
- if( colForUnreferencedActionsRef.get() == null ||
- colForUnreferencedPropertiesRef.get() == null ||
- colForUnreferencedCollectionsRef.get() == null) {
- return false;
+ if(colForUnreferencedActionsRef.get() == null && fieldSetForUnreferencedActionsRef.get() == null) {
+ bs3Grid.getMetadataErrors().add("No column and no fieldset has the 'unreferencedActions' attribute set");
+ }
+ if(fieldSetForUnreferencedPropertiesRef.get() == null) {
+ bs3Grid.getMetadataErrors().add("No fieldset has the 'unreferencedProperties' attribute set");
+ }
+ if(tabGroupForUnreferencedCollectionsRef.get() == null) {
+ bs3Grid.getMetadataErrors().add("No tabgroup has the 'unreferencedCollections' attribute set");
}
+ if( colForUnreferencedActionsRef.get() == null && fieldSetForUnreferencedActionsRef.get() == null ||
+ fieldSetForUnreferencedPropertiesRef.get() == null ||
+ tabGroupForUnreferencedCollectionsRef.get() == null) {
+ return false;
+ }
// add missing properties will be added to the first fieldset of the specified column
final Tuple<List<String>> propertyIdTuple =
- surplusAndMissing(propertyIds.keySet(), oneToOneAssociationById.keySet());
+ surplusAndMissing(propertyIds.keySet(), oneToOneAssociationById.keySet());
final List<String> surplusPropertyIds = propertyIdTuple.first;
final List<String> missingPropertyIds = propertyIdTuple.second;
@@ -172,18 +199,9 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
}
if(!missingPropertyIds.isEmpty()) {
- final BS3Col bs3Col = colForUnreferencedPropertiesRef.get();
- if(bs3Col != null) {
- // ensure that there is a field set to use, else create
- boolean wasSet = fieldSetForUnreferencedPropsRef.compareAndSet(null, new FieldSet(MemberGroupLayoutFacet.DEFAULT_GROUP));
- final FieldSet fieldSetForUnref = fieldSetForUnreferencedPropsRef.get();
- if(wasSet) {
- fieldSetForUnref.setOwner(bs3Col);
- bs3Col.getFieldSets().add(fieldSetForUnref);
- }
- for (final String propertyId : missingPropertyIds) {
- bs3Col.getFieldSets().get(0).getProperties().add(new PropertyLayoutData(propertyId));
- }
+ final FieldSet fieldSet = fieldSetForUnreferencedPropertiesRef.get();
+ if(fieldSet != null) {
+ addMissingPropertiesTo(fieldSet, missingPropertyIds);
}
}
@@ -198,20 +216,9 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
}
if(!missingCollectionIds.isEmpty()) {
- final BS3Col bs3Col = colForUnreferencedCollectionsRef.get();
- if(bs3Col != null) {
- final BS3TabGroup tabGroup = new BS3TabGroup();
- tabGroup.setOwner(bs3Col);
- bs3Col.getTabGroups().add(tabGroup);
- for (final String collectionId : missingCollectionIds) {
- final BS3Tab bs3Tab = new BS3Tab();
- tabGroup.getTabs().add(bs3Tab);
- FCColumn left = new FCColumn(12);
- bs3Tab.setOwner(tabGroup);
- final CollectionLayoutData layoutMetadata = new CollectionLayoutData(collectionId);
- layoutMetadata.setDefaultView("table");
- left.getCollections().add(layoutMetadata);
- }
+ final BS3TabGroup bs3TabGroup = tabGroupForUnreferencedCollectionsRef.get();
+ if(bs3TabGroup != null) {
+ addMissingCollectionsTo(bs3TabGroup, missingCollectionIds, objectSpec);
}
}
@@ -219,7 +226,27 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
final Tuple<List<String>> actionIdTuple =
surplusAndMissing(actionIds.keySet(), objectActionById.keySet());
final List<String> surplusActionIds = actionIdTuple.first;
- final List<String> missingActionIds = actionIdTuple.second;
+
+ // ... the missing actions are those in the second tuple, excluding those bound via @MemberOrder#name
+ // to a property or collection.
+ final List<String> missingActionIds =
+ FluentIterable.from(actionIdTuple.second)
+ .filter(new Predicate<String>() {
+ @Override public boolean apply(@Nullable final String actionId) {
+ final ObjectAction oa = objectActionById.get(actionId);
+ final MemberOrderFacet memberOrderFacet = oa.getFacet(MemberOrderFacet.class);
+ if(memberOrderFacet == null) {
+ return true;
+ }
+ final String memberOrderName = memberOrderFacet.name();
+ if (memberOrderName == null) {
+ return true;
+ }
+ return !oneToOneAssociationById.containsKey(memberOrderName) &&
+ !oneToManyAssociationById.containsKey(memberOrderName);
+ }
+ })
+ .toList();
for (String surplusActionId : surplusActionIds) {
actionIds.get(surplusActionId).setMetadataError("No such action");
@@ -228,13 +255,11 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
if(!missingActionIds.isEmpty()) {
final BS3Col bs3Col = colForUnreferencedActionsRef.get();
if(bs3Col != null) {
- for (String actionId : missingActionIds) {
- List<ActionLayoutData> actions = bs3Col.getActions();
- if(actions == null) {
- actions = Lists.newArrayList();
- bs3Col.setActions(actions);
- }
- actions.add(new ActionLayoutData(actionId));
+ addMissingActionsTo(bs3Col, missingActionIds);
+ } else {
+ final FieldSet fieldSet = fieldSetForUnreferencedActionsRef.get();
+ if(fieldSet != null) {
+ addMissingActionsTo(fieldSet, missingActionIds);
}
}
}
@@ -242,4 +267,60 @@ public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3G
return true;
}
+ protected void addMissingPropertiesTo(
+ final FieldSet fieldSet,
+ final List<String> missingPropertyIds) {
+ for (final String propertyId : missingPropertyIds) {
+ fieldSet.getProperties().add(new PropertyLayoutData(propertyId));
+ }
+ }
+
+ protected void addMissingActionsTo(final BS3Col bs3Col, final List<String> missingActionIds) {
+ for (String actionId : missingActionIds) {
+ List<ActionLayoutData> actions = bs3Col.getActions();
+ if(actions == null) {
+ actions = Lists.newArrayList();
+ bs3Col.setActions(actions);
+ }
+ actions.add(new ActionLayoutData(actionId));
+ }
+ }
+
+ protected void addMissingActionsTo(final FieldSet fieldSet, final List<String> missingActionIds) {
+ List<ActionLayoutData> actions = fieldSet.getActions();
+ for (String actionId : missingActionIds) {
+ actions.add(new ActionLayoutData(actionId));
+ }
+ }
+
+ protected void addMissingCollectionsTo(
+ final BS3TabGroup tabGroup,
+ final List<String> missingCollectionIds,
+ final ObjectSpecification objectSpec) {
+ for (final String collectionId : missingCollectionIds) {
+ final BS3Tab bs3Tab = new BS3Tab();
+ bs3Tab.setName(objectSpec.getAssociation(collectionId).getName());
+ tabGroup.getTabs().add(bs3Tab);
+ bs3Tab.setOwner(tabGroup);
+
+ final BS3Row tabRow = new BS3Row();
+ tabRow.setOwner(bs3Tab);
+ bs3Tab.getRows().add(tabRow);
+
+ final BS3Col tabRowCol = new BS3Col();
+ tabRowCol.setSpan(12);
+ tabRowCol.setSize(BS3RowContent.Size.MD);
+ tabRowCol.setOwner(tabRow);
+ tabRow.getCols().add(tabRowCol);
+
+ final CollectionLayoutData layoutMetadata = new CollectionLayoutData(collectionId);
+ layoutMetadata.setDefaultView("table");
+ tabRowCol.getCollections().add(layoutMetadata);
+ }
+ }
+
+ private static Boolean isSet(final Boolean flag) {
+ return flag != null && flag;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
index cf18f80..c617c73 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
@@ -21,57 +21,22 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
-import javax.inject.Inject;
-
-import com.google.common.base.Strings;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.layout.common.ActionLayoutData;
-import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
import org.apache.isis.applib.layout.common.CollectionLayoutData;
import org.apache.isis.applib.layout.common.FieldSet;
import org.apache.isis.applib.layout.common.Grid;
-import org.apache.isis.applib.layout.common.MemberRegionOwner;
import org.apache.isis.applib.layout.common.PropertyLayoutData;
import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.applib.layout.fixedcols.FCColumnOwner;
import org.apache.isis.applib.layout.fixedcols.FCGrid;
import org.apache.isis.applib.layout.fixedcols.FCTab;
import org.apache.isis.applib.layout.fixedcols.FCTabGroup;
-import org.apache.isis.applib.services.i18n.TranslationService;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.actions.layout.ActionPositionFacetForActionXml;
-import org.apache.isis.core.metamodel.facets.actions.layout.BookmarkPolicyFacetForActionXml;
-import org.apache.isis.core.metamodel.facets.actions.layout.CssClassFaFacetForActionXml;
-import org.apache.isis.core.metamodel.facets.actions.layout.CssClassFacetForActionXml;
-import org.apache.isis.core.metamodel.facets.actions.layout.DescribedAsFacetForActionXml;
-import org.apache.isis.core.metamodel.facets.actions.layout.HiddenFacetForActionLayoutXml;
-import org.apache.isis.core.metamodel.facets.actions.layout.NamedFacetForActionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.CssClassFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.DefaultViewFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.DescribedAsFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.HiddenFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.NamedFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.PagedFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.collections.layout.SortedByFacetForCollectionXml;
-import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetXml;
import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.CssClassFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.DescribedAsFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.HiddenFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.LabelAtFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.MultiLineFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.NamedFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.RenderedAdjustedFacetForPropertyXml;
-import org.apache.isis.core.metamodel.facets.properties.propertylayout.TypicalLengthFacetForPropertyXml;
import org.apache.isis.core.metamodel.services.grid.GridNormalizerServiceAbstract;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@DomainService(
nature = NatureOfService.DOMAIN
@@ -98,7 +63,7 @@ public class GridNormalizerServiceFC extends GridNormalizerServiceAbstract {
final Grid grid,
final Map oneToOneAssociationById,
final Map oneToManyAssociationById,
- final Map objectActionById) {
+ final Map objectActionById, final ObjectSpecification objectSpec) {
final FCGrid fcGrid = (FCGrid) grid;
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
index 3d9d6b2..706db56 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
@@ -72,8 +72,10 @@ public class BS3GridTest {
final BS3Grid bs3Grid = new BS3Grid();
// header
- final BS3Row headerRow = bs3Grid.getRows().get(0);
- final BS3Col headerCol = (BS3Col) headerRow.getCols().get(0);
+ final BS3Row headerRow = new BS3Row();
+ bs3Grid.getRows().add(headerRow);
+ final BS3Col headerCol = new BS3Col();
+ headerRow.getCols().add(headerCol);
headerCol.setSpan(12);
final DomainObjectLayoutData objectLayoutData = new DomainObjectLayoutData();
@@ -88,18 +90,22 @@ public class BS3GridTest {
final BS3Row contentRow = new BS3Row();
bs3Grid.getRows().add(contentRow);
- final BS3Col contentCol = (BS3Col) contentRow.getCols().get(0);
+ final BS3Col contentCol = new BS3Col();
+ contentRow.getCols().add(contentCol);
contentCol.setSpan(12);
// a tabgroup containing a 'Common' tab
final BS3TabGroup tabGroup = new BS3TabGroup();
contentCol.getTabGroups().add(tabGroup);
- BS3Tab bs3Tab = tabGroup.getTabs().get(0);
+ BS3Tab bs3Tab = new BS3Tab();
+ tabGroup.getTabs().add(bs3Tab);
bs3Tab.setName("Common");
// with a left col...
- final BS3Row tabRow = bs3Tab.getRows().get(0);
- final BS3Col tabLeftCol = (BS3Col) tabRow.getCols().get(0);
+ final BS3Row tabRow = new BS3Row();
+ bs3Tab.getRows().add(tabRow);
+ final BS3Col tabLeftCol = new BS3Col();
+ tabRow.getCols().add(tabLeftCol);
tabLeftCol.setSpan(6);
// containing a fieldset
@@ -109,7 +115,8 @@ public class BS3GridTest {
leftPropGroup.setName("General");
// with a single property
- final PropertyLayoutData namePropertyLayoutData = leftPropGroup.getProperties().get(0);
+ final PropertyLayoutData namePropertyLayoutData = new PropertyLayoutData();
+ leftPropGroup.getProperties().add(namePropertyLayoutData);
namePropertyLayoutData.setNamed("name");
// and its associated action
@@ -119,7 +126,8 @@ public class BS3GridTest {
namePropertyLayoutData.getActions().add(updateNameActionLayoutData);
// and the tab also has a right col...
- final BS3Col tabRightCol = (BS3Col) tabRow.getCols().get(0);
+ final BS3Col tabRightCol = new BS3Col();
+ tabRow.getCols().add(tabRightCol);
tabRightCol.setSpan(6);
// containing a collection
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
index dad55cf..7f2702e 100644
--- a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
+++ b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
@@ -31,6 +31,7 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
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.MemberOrder;
import org.apache.isis.applib.annotation.Parameter;
import org.apache.isis.applib.annotation.ParameterLayout;
import org.apache.isis.applib.annotation.Property;
@@ -104,6 +105,7 @@ public class SimpleObject implements Comparable<SimpleObject> {
domainEvent = UpdateNameDomainEvent.class,
semantics = SemanticsOf.IDEMPOTENT
)
+ @MemberOrder(name = "name", sequence = "1")
public SimpleObject updateName(
@Parameter(maxLength = NAME_LENGTH)
@ParameterLayout(named = "New name")
http://git-wip-us.apache.org/repos/asf/isis/blob/8fcac964/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
index b1b3ed9..34bbb54 100644
--- a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
+++ b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
@@ -1,64 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bs3:grid xsi:schemaLocation="http://isis.apache.org/schema/applib/layout/common http://isis.apache.org/schema/applib/layout/common/common.xsd http://isis.apache.org/schema/applib/layout/bootstrap3 http://isis.apache.org/schema/applib/layout/bootstrap3/bootstrap3.xsd" xmlns:c="http://isis.apache.org/schema/applib/layout/common" xmlns:bs3="http://isis.apache.org/schema/applib/layout/bootstrap3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <bs3:row cssClass="bishbosh">
- <bs3:col span="8">
+<!--
+ <bs3:row>
+ <bs3:col span="8" unreferencedActions="false">
<c:domainObject/>
</bs3:col>
- <bs3:col span="4" cssClass="foobar" unreferencedActions="true">
- <c:action id="delete" cssClassFa="fa-trash"/>
- </bs3:col>
</bs3:row>
<bs3:row>
<bs3:col span="12">
<bs3:tabGroup>
- <bs3:tab name="Metadata">
+ <bs3:tab name="Properties">
<bs3:row>
- <bs3:col span="12">
- <c:fieldSet name="Metadata">
- <c:action id="downloadJdMetadata"/>
- <c:action id="downloadLayoutXml" position="PANEL_DROPDOWN"/>
- <c:property id="versionSequence"/>
- </c:fieldSet>
- </bs3:col>
<bs3:col span="6">
- <c:fieldSet name="Xxx">
- <c:property id="name" labelPosition="TOP">
- <c:action id="updateName">
- <c:describedAs>This allows the name to be updated</c:describedAs>
- </c:action>
- </c:property>
- </c:fieldSet>
+ <c:fieldSet name="General" unreferencedProperties="true" unreferencedActions="true"/>
</bs3:col>
<bs3:col span="6">
- <c:fieldSet name="Xxx">
- <c:property id="name" labelPosition="TOP">
- <c:action id="updateName">
- <c:describedAs>This allows the name to be updated</c:describedAs>
- </c:action>
- </c:property>
+ <c:fieldSet name="Metadata">
+ <c:action id="downloadJdoMetadata"/>
+ <c:action id="downloadLayoutXml" position="PANEL_DROPDOWN"/>
+ <c:property id="versionSequence"/>
</c:fieldSet>
</bs3:col>
</bs3:row>
</bs3:tab>
</bs3:tabGroup>
- <bs3:tabGroup>
- <bs3:tab name="SimilarTo">
- <bs3:row>
- <bs3:col span="12">
- <c:collection id="similarTo" defaultView="table"/>
- </bs3:col>
- </bs3:row>
- </bs3:tab>
- <bs3:tab name="Others">
- <bs3:row>
- <bs3:col span="12">
- <c:collection id="others" defaultView="hide"/>
- </bs3:col>
- </bs3:row>
- </bs3:tab>
- </bs3:tabGroup>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="12">
+ <bs3:tabGroup unreferencedCollections="true"/>
+ </bs3:col>
+ </bs3:row>
+-->
+ <bs3:row>
+ <bs3:col span="12" unreferencedActions="true">
+ <c:domainObject/>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="6">
+ <c:fieldSet name="Properties" unreferencedProperties="true"/>
+ </bs3:col>
+ <bs3:col span="6">
+ <bs3:tabGroup unreferencedCollections="true"/>
</bs3:col>
</bs3:row>
</bs3:grid>
[2/3] isis git commit: ISIS-993: normalizing the BS3 grid,
factoring out commonalities into superclass.
Posted by da...@apache.org.
ISIS-993: normalizing the BS3 grid, factoring out commonalities into superclass.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/fe46a781
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/fe46a781
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/fe46a781
Branch: refs/heads/ISIS-993
Commit: fe46a781eb7472694e705cfd396e630964c3add3
Parents: 63d03d2
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Feb 2 21:29:22 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Feb 2 21:29:22 2016 +0000
----------------------------------------------------------------------
.../isis/applib/layout/bootstrap3/BS3Col.java | 26 +-
.../applib/layout/bootstrap3/BS3Element.java | 38 +++
.../layout/bootstrap3/BS3ElementAbstract.java | 5 +-
.../isis/applib/layout/bootstrap3/BS3Grid.java | 248 +++++---------
.../isis/applib/layout/bootstrap3/BS3Row.java | 17 +
.../common/CollectionLayoutDataOwner.java | 25 ++
.../applib/layout/common/FieldSetOwner.java | 25 ++
.../apache/isis/applib/layout/common/Grid.java | 39 ++-
.../isis/applib/layout/common/GridAbstract.java | 164 +++++++++
.../isis/applib/layout/fixedcols/FCColumn.java | 7 +-
.../isis/applib/layout/fixedcols/FCGrid.java | 159 ++-------
.../services/grid/GridNormalizerService.java | 6 +-
.../grid/GridNormalizerServiceAbstract.java | 335 +++++++++++++++++++
.../services/grid/GridNormalizerUtil.java | 38 +++
.../bootstrap3/GridNormalizerServiceBS3.java | 232 +++++++++++--
.../grid/fixedcols/GridNormalizerServiceFC.java | 274 ++-------------
.../ui/components/layout/bs3/BS3GridPanel.java | 5 +-
.../wicket/ui/components/layout/bs3/Util.java | 3 +-
18 files changed, 1049 insertions(+), 597 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
index cef0f80..752c7e4 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
@@ -31,9 +31,10 @@ import com.google.common.collect.Lists;
import org.apache.isis.applib.layout.common.ActionLayoutData;
import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.CollectionLayoutDataOwner;
import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
import org.apache.isis.applib.layout.common.FieldSet;
-import org.apache.isis.applib.layout.common.MemberRegionOwner;
+import org.apache.isis.applib.layout.common.FieldSetOwner;
/**
* A column within a row which, depending on its {@link #getSpan()}, could be as narrow as 1/12th of the page's width, all the way up to spanning the entire page.
@@ -60,9 +61,12 @@ import org.apache.isis.applib.layout.common.MemberRegionOwner;
"tabGroups",
"fieldSets",
"collections",
+ "metadataError"
}
)
-public class BS3Col extends BS3RowContent implements ActionLayoutDataOwner, BS3TabGroupOwner, BS3RowOwner, MemberRegionOwner, HasCssId {
+public class BS3Col extends BS3RowContent
+ implements ActionLayoutDataOwner, BS3TabGroupOwner, BS3RowOwner, FieldSetOwner, HasCssId,
+ CollectionLayoutDataOwner {
private static final long serialVersionUID = 1L;
@@ -239,8 +243,26 @@ public class BS3Col extends BS3RowContent implements ActionLayoutDataOwner, BS3T
+
+ private String metadataError;
+
+ /**
+ * For diagnostics; populated by the framework if and only if a metadata error.
+ */
+ @XmlElement(required = false)
+ public String getMetadataError() {
+ return metadataError;
+ }
+
+ public void setMetadataError(final String metadataError) {
+ this.metadataError = metadataError;
+ }
+
+
+
public String toCssClass() {
final Size size = getSize() != null? getSize(): Size.MD;
return "col-" + size.toCssClassFragment() + "-" + getSpan();
}
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Element.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Element.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Element.java
new file mode 100644
index 0000000..669fcbb
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Element.java
@@ -0,0 +1,38 @@
+/*
+ * 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.layout.bootstrap3;
+
+import java.io.Serializable;
+
+public interface BS3Element extends Serializable {
+
+ /**
+ * Any additional CSS classes to render on the page element corresponding to this object,
+ * eg as per the <a href="http://getbootstrap.com/css/#grid-less">Bootstrap mixins</a> or just for
+ * custom styling.
+ */
+ String getCssClass();
+
+ void setCssClass(final String cssClass);
+
+
+ String getPath();
+ void setPath(final String path);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3ElementAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3ElementAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3ElementAbstract.java
index 6bcd45a..95aa611 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3ElementAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3ElementAbstract.java
@@ -18,8 +18,6 @@
*/
package org.apache.isis.applib.layout.bootstrap3;
-import java.io.Serializable;
-
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;
@@ -28,7 +26,7 @@ import org.apache.isis.applib.annotation.Programmatic;
/**
* Superclass for all layout classes, factoring out the common {@link #getCssClass()} attribute.
*/
-public abstract class BS3ElementAbstract implements Serializable {
+public abstract class BS3ElementAbstract implements BS3Element {
private String cssClass;
@@ -63,5 +61,4 @@ public abstract class BS3ElementAbstract implements Serializable {
}
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
index e3904c4..6360480 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
@@ -22,21 +22,21 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.ActionLayoutData;
-import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
import org.apache.isis.applib.layout.common.CollectionLayoutData;
import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
import org.apache.isis.applib.layout.common.FieldSet;
import org.apache.isis.applib.layout.common.Grid;
+import org.apache.isis.applib.layout.common.GridAbstract;
import org.apache.isis.applib.layout.common.PropertyLayoutData;
import org.apache.isis.applib.services.dto.Dto;
@@ -58,77 +58,67 @@ import org.apache.isis.applib.services.dto.Dto;
, "metadataErrors"
}
)
-public class BS3Grid extends BS3ElementAbstract implements Grid, Dto, BS3RowOwner {
+public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwner {
private static final long serialVersionUID = 1L;
- private List<BS3Row> rows = new ArrayList<BS3Row>(){{
- add(new BS3Row());
- }};
- // no wrapper
- @XmlElement(name = "row", required = true)
- public List<BS3Row> getRows() {
- return rows;
+ private String cssClass;
+
+ @XmlAttribute(required = false)
+ public String getCssClass() {
+ return cssClass;
}
- public void setRows(final List<BS3Row> rows) {
- this.rows = rows;
+ public void setCssClass(final String cssClass) {
+ this.cssClass = cssClass;
}
- private boolean normalized;
+ private String path;
@Programmatic
@XmlTransient
- public boolean isNormalized() {
- return normalized;
+ public String getPath() {
+ return path;
}
@Programmatic
- public void setNormalized(final boolean normalized) {
- this.normalized = normalized;
+ public void setPath(final String path) {
+ this.path = path;
}
- private List<String> metadataErrors = Lists.newArrayList();
-
- /**
- * For diagnostics; populated by the framework if and only if a metadata error.
- *
- * <p>
- * For example, if there is not exactly one {@link BS3Col} with the
- * {@link BS3Col#isUnreferencedActions()} attribute set, then this is an error. Ditto for
- * {@link BS3Col#isUnreferencedCollections() collections}
- * and {@link BS3Col#isUnreferencedProperties() properties}.
- * </p>
- */
- @XmlElement(required = false)
- public List<String> getMetadataErrors() {
- return metadataErrors;
+
+
+ private List<BS3Row> rows = new ArrayList<BS3Row>(){{
+ add(new BS3Row());
+ }};
+
+ // no wrapper
+ @XmlElement(name = "row", required = true)
+ public List<BS3Row> getRows() {
+ return rows;
}
- public void setMetadataErrors(final List<String> metadataErrors) {
- this.metadataErrors = metadataErrors;
+ public void setRows(final List<BS3Row> rows) {
+ this.rows = rows;
}
- interface Visitor {
+
+
+ interface Visitor extends Grid.Visitor {
void visit(final BS3Grid bs3Page);
void visit(final BS3Row bs3Row);
void visit(final BS3Col bs3Col);
void visit(final BS3ClearFix bs3ClearFix);
void visit(final BS3TabGroup bs3TabGroup);
void visit(final BS3Tab bs3Tab);
- void visit(final FieldSet fieldSet);
- void visit(final DomainObjectLayoutData domainObjectLayout);
- void visit(final PropertyLayoutData propertyLayoutData);
- void visit(final CollectionLayoutData collectionLayoutData);
- void visit(final ActionLayoutData actionLayoutData);
}
- public static class VisitorAdapter implements Visitor {
+ public static class VisitorAdapter extends Grid.VisitorAdapter implements Visitor {
@Override
- public void visit(final BS3Grid bs3Page) { }
+ public void visit(final BS3Grid bs3Grid) { }
@Override
public void visit(final BS3Row bs3Row) { }
@Override
@@ -139,51 +129,48 @@ public class BS3Grid extends BS3ElementAbstract implements Grid, Dto, BS3RowOwne
public void visit(final BS3TabGroup bs3TabGroup) { }
@Override
public void visit(final BS3Tab bs3Tab) { }
- @Override
- public void visit(final DomainObjectLayoutData domainObjectLayout) { }
- @Override
- public void visit(final FieldSet fieldSet) {}
- @Override
- public void visit(final PropertyLayoutData propertyLayoutData) {}
- @Override
- public void visit(final CollectionLayoutData collectionLayoutData) {}
- @Override
- public void visit(final ActionLayoutData actionLayoutData) { }
}
- public void visit(final BS3Grid.Visitor visitor) {
- visitor.visit(this);
+ public void visit(final Grid.Visitor visitor) {
+ final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
+ bs3Visitor.visit(this);
traverseRows(this, visitor);
}
- protected void traverseRows(final BS3RowOwner rowOwner, final Visitor visitor) {
+ protected void traverseRows(final BS3RowOwner rowOwner, final Grid.Visitor visitor) {
+ final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
for (BS3Row bs3Row : rowOwner.getRows()) {
bs3Row.setOwner(this);
- visitor.visit(bs3Row);
- final List<BS3RowContent> cols = bs3Row.getCols();
- for (BS3RowContent rowContent : cols) {
- rowContent.setOwner(bs3Row);
- if(rowContent instanceof BS3Col) {
- final BS3Col bs3Col = (BS3Col) rowContent;
- visitor.visit(bs3Col);
- traverseDomainObject(bs3Col, visitor);
- traverseTabGroups(bs3Col, visitor);
- traverseActions(bs3Col, visitor);
- traverseFieldSets(bs3Col, visitor);
- traverseCollections(bs3Col, visitor);
- traverseRows(bs3Col, visitor);
- } else if (rowContent instanceof BS3ClearFix) {
- final BS3ClearFix bs3ClearFix = (BS3ClearFix) rowContent;
- visitor.visit(bs3ClearFix);
- } else {
- throw new IllegalStateException(
- "Unrecognized implementation of BS3RowContent, " + rowContent);
- }
+ bs3Visitor.visit(bs3Row);
+ traverseCols(visitor, bs3Row);
+ }
+ }
+
+ private void traverseCols(final Grid.Visitor visitor, final BS3Row bs3Row) {
+ final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
+ final List<BS3RowContent> cols = bs3Row.getCols();
+ for (BS3RowContent rowContent : cols) {
+ rowContent.setOwner(bs3Row);
+ if(rowContent instanceof BS3Col) {
+ final BS3Col bs3Col = (BS3Col) rowContent;
+ bs3Visitor.visit(bs3Col);
+ traverseDomainObject(bs3Col, visitor);
+ traverseTabGroups(bs3Col, visitor);
+ traverseActions(bs3Col, visitor);
+ traverseFieldSets(bs3Col, visitor);
+ traverseCollections(bs3Col, visitor);
+ traverseRows(bs3Col, visitor);
+ } else if (rowContent instanceof BS3ClearFix) {
+ final BS3ClearFix bs3ClearFix = (BS3ClearFix) rowContent;
+ bs3Visitor.visit(bs3ClearFix);
+ } else {
+ throw new IllegalStateException(
+ "Unrecognized implementation of BS3RowContent, " + rowContent);
}
}
}
- private void traverseDomainObject(final BS3Col bs3Col, final Visitor visitor) {
+ private void traverseDomainObject(final BS3Col bs3Col, final Grid.Visitor visitor) {
final DomainObjectLayoutData domainObject = bs3Col.getDomainObject();
if(domainObject == null) {
return;
@@ -194,120 +181,50 @@ public class BS3Grid extends BS3ElementAbstract implements Grid, Dto, BS3RowOwne
private void traverseTabGroups(
final BS3TabGroupOwner bs3TabGroupOwner,
- final Visitor visitor) {
+ final Grid.Visitor visitor) {
+ final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
final List<BS3TabGroup> tabGroups = bs3TabGroupOwner.getTabGroups();
for (BS3TabGroup bs3TabGroup : tabGroups) {
bs3TabGroup.setOwner(bs3TabGroupOwner);
- visitor.visit(bs3TabGroup);
+ bs3Visitor.visit(bs3TabGroup);
traverseTabs(bs3TabGroup, visitor);
}
}
private void traverseTabs(
final BS3TabOwner bs3TabOwner,
- final Visitor visitor) {
+ final Grid.Visitor visitor) {
+ final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
final List<BS3Tab> tabs = bs3TabOwner.getTabs();
for (BS3Tab tab : tabs) {
tab.setOwner(bs3TabOwner);
- visitor.visit(tab);
+ bs3Visitor.visit(tab);
traverseRows(tab, visitor);
}
}
- private void traverseActions(
- final ActionLayoutDataOwner actionLayoutDataOwner,
- final Visitor visitor) {
- final List<ActionLayoutData> actionLayoutDatas = actionLayoutDataOwner.getActions();
- if(actionLayoutDatas == null) {
- return;
- }
- for (final ActionLayoutData actionLayoutData : actionLayoutDatas) {
- actionLayoutData.setOwner(actionLayoutDataOwner);
- visitor.visit(actionLayoutData);
- }
- }
-
- private void traverseFieldSets(final BS3Col bs3Col, final Visitor visitor) {
- final List<FieldSet> fieldSets = bs3Col.getFieldSets();
- for (FieldSet fieldSet : fieldSets) {
- fieldSet.setOwner(bs3Col);
- visitor.visit(fieldSet);
- traverseActions(fieldSet, visitor);
- final List<PropertyLayoutData> properties = fieldSet.getProperties();
- for (final PropertyLayoutData property : properties) {
- property.setOwner(fieldSet);
- visitor.visit(property);
- traverseActions(property, visitor);
+ private static Visitor asBs3Visitor(final Grid.Visitor visitor) {
+ return visitor instanceof Visitor? (Visitor) visitor : new BS3Grid.VisitorAdapter() {
+ @Override public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
+ visitor.visit(domainObjectLayoutData);
}
- }
- }
- private void traverseCollections(final BS3Col bs3Col, final Visitor visitor) {
- final List<CollectionLayoutData> collections = bs3Col.getCollections();
- for (CollectionLayoutData collection : collections) {
- collection.setOwner(bs3Col);
- visitor.visit(collection);
- traverseActions(collection, visitor);
- }
- }
-
-
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById() {
- final LinkedHashMap<String, PropertyLayoutData> propertiesById = Maps.newLinkedHashMap();
- visit(new BS3Grid.VisitorAdapter() {
- public void visit(final PropertyLayoutData propertyLayoutData) {
- propertiesById.put(propertyLayoutData.getId(), propertyLayoutData);
+ @Override public void visit(final ActionLayoutData actionLayoutData) {
+ visitor.visit(actionLayoutData);
}
- });
- return propertiesById;
- }
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById() {
- final LinkedHashMap<String, CollectionLayoutData> collectionsById = Maps.newLinkedHashMap();
-
- visit(new BS3Grid.VisitorAdapter() {
- @Override
- public void visit(final CollectionLayoutData collectionLayoutData) {
- collectionsById.put(collectionLayoutData.getId(), collectionLayoutData);
+ @Override public void visit(final PropertyLayoutData propertyLayoutData) {
+ visitor.visit(propertyLayoutData);
}
- });
- return collectionsById;
- }
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, ActionLayoutData> getAllActionsById() {
- final LinkedHashMap<String, ActionLayoutData> actionsById = Maps.newLinkedHashMap();
-
- visit(new BS3Grid.VisitorAdapter() {
- @Override
- public void visit(final ActionLayoutData actionLayoutData) {
- actionsById.put(actionLayoutData.getId(), actionLayoutData);
+ @Override public void visit(final CollectionLayoutData collectionLayoutData) {
+ visitor.visit(collectionLayoutData);
}
- });
- return actionsById;
- }
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, FieldSet> getAllFieldSetsByName() {
- final LinkedHashMap<String, FieldSet> fieldSetsByName = Maps.newLinkedHashMap();
-
- visit(new BS3Grid.VisitorAdapter() {
- @Override
- public void visit(final FieldSet fieldSet) {
- fieldSetsByName.put(fieldSet.getName(), fieldSet);
+ @Override public void visit(final FieldSet fieldSet) {
+ visitor.visit(fieldSet);
}
- });
- return fieldSetsByName;
+ };
}
@@ -326,7 +243,6 @@ public class BS3Grid extends BS3ElementAbstract implements Grid, Dto, BS3RowOwne
}
- // TODO: need to figure out where the checking that can't have multiple divs with the same CSS id should go...
@Programmatic
@XmlTransient
public LinkedHashMap<String, HasCssId> getAllCssId() {
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
index ff75f46..d05dbf8 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Row.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlTransient;
@@ -39,6 +40,7 @@ import javax.xml.bind.annotation.XmlType;
name = "row"
, propOrder = {
"cols"
+ , "metadataError"
}
)
public class BS3Row extends BS3ElementAbstract implements HasCssId, BS3RowContentOwner {
@@ -82,6 +84,21 @@ public class BS3Row extends BS3ElementAbstract implements HasCssId, BS3RowConten
+ private String metadataError;
+
+ /**
+ * For diagnostics; populated by the framework if and only if a metadata error.
+ */
+ @XmlElement(required = false)
+ public String getMetadataError() {
+ return metadataError;
+ }
+
+ public void setMetadataError(final String metadataError) {
+ this.metadataError = metadataError;
+ }
+
+
private BS3RowOwner owner;
/**
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
new file mode 100644
index 0000000..438ae56
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
@@ -0,0 +1,25 @@
+/*
+ * 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.layout.common;
+
+import java.util.List;
+
+public interface CollectionLayoutDataOwner extends MemberRegionOwner {
+ List<CollectionLayoutData> getCollections();
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSetOwner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSetOwner.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSetOwner.java
new file mode 100644
index 0000000..f3e5fd0
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSetOwner.java
@@ -0,0 +1,25 @@
+/*
+ * 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.layout.common;
+
+import java.util.List;
+
+public interface FieldSetOwner extends MemberRegionOwner {
+ List<FieldSet> getFieldSets();
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
index 92e5a1d..7380a3a 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
@@ -19,8 +19,10 @@
package org.apache.isis.applib.layout.common;
import java.util.LinkedHashMap;
+import java.util.List;
import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.layout.bootstrap3.BS3Col;
import org.apache.isis.applib.services.layout.GridService;
/**
@@ -36,16 +38,37 @@ public interface Grid {
void setNormalized(final boolean normalized);
- @Programmatic
- LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById();
+ @Programmatic LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById();
- @Programmatic
- LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById();
+ @Programmatic LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById();
- @Programmatic
- LinkedHashMap<String, ActionLayoutData> getAllActionsById();
+ @Programmatic LinkedHashMap<String, ActionLayoutData> getAllActionsById();
- @Programmatic
- LinkedHashMap<String, FieldSet> getAllFieldSetsByName();
+ interface Visitor {
+ void visit(final DomainObjectLayoutData domainObjectLayoutData);
+
+ void visit(final ActionLayoutData actionLayoutData);
+
+ void visit(final PropertyLayoutData propertyLayoutData);
+
+ void visit(final CollectionLayoutData collectionLayoutData);
+
+ void visit(final FieldSet fieldSet);
+ }
+
+ class VisitorAdapter implements Visitor {
+ @Override public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
+ }
+ @Override public void visit(final ActionLayoutData actionLayoutData) {
+ }
+ @Override public void visit(final PropertyLayoutData propertyLayoutData) {
+ }
+ @Override public void visit(final CollectionLayoutData collectionLayoutData) {
+ }
+ @Override public void visit(final FieldSet fieldSet) {
+ }
+ }
+
+ void visit(final Grid.Visitor visitor);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
new file mode 100644
index 0000000..70cee11
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
@@ -0,0 +1,164 @@
+/*
+ * 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.layout.common;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.google.common.collect.Maps;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
+import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.applib.services.layout.GridService;
+
+/**
+ * All top-level page layout classes should implement this interface.
+ *
+ * <p>
+ * It is used by the {@link GridService} as a common based type for any layouts read in from XML.
+ * </p>
+ */
+public abstract class GridAbstract implements Grid {
+
+ private boolean normalized;
+
+ @Programmatic
+ @XmlTransient
+ public boolean isNormalized() {
+ return normalized;
+ }
+
+ @Programmatic
+ public void setNormalized(final boolean normalized) {
+ this.normalized = normalized;
+ }
+
+
+ /**
+ * Convenience for subclasses.
+ */
+ protected void traverseActions(
+ final ActionLayoutDataOwner actionLayoutDataOwner,
+ final GridAbstract.Visitor visitor) {
+ final List<ActionLayoutData> actionLayoutDatas = actionLayoutDataOwner.getActions();
+ if(actionLayoutDatas == null) {
+ return;
+ }
+ for (final ActionLayoutData actionLayoutData : actionLayoutDatas) {
+ actionLayoutData.setOwner(actionLayoutDataOwner);
+ visitor.visit(actionLayoutData);
+ }
+ }
+
+
+ /**
+ * Convenience for subclasses.
+ */
+ protected void traverseFieldSets(final FieldSetOwner fieldSetOwner, final GridAbstract.Visitor visitor) {
+ final List<FieldSet> fieldSets = fieldSetOwner.getFieldSets();
+ for (FieldSet fieldSet : fieldSets) {
+ fieldSet.setOwner(fieldSetOwner);
+ visitor.visit(fieldSet);
+ traverseActions(fieldSet, visitor);
+ final List<PropertyLayoutData> properties = fieldSet.getProperties();
+ for (final PropertyLayoutData property : properties) {
+ property.setOwner(fieldSet);
+ visitor.visit(property);
+ traverseActions(property, visitor);
+ }
+ }
+ }
+
+
+ /**
+ * Convenience for subclasses.
+ */
+ protected void traverseCollections(
+ final CollectionLayoutDataOwner owner, final GridAbstract.Visitor visitor) {
+ final List<CollectionLayoutData> collections = owner.getCollections();
+ for (CollectionLayoutData collection : collections) {
+ collection.setOwner(owner);
+ visitor.visit(collection);
+ traverseActions(collection, visitor);
+ }
+ }
+
+
+ @Programmatic
+ @XmlTransient
+ public LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById() {
+ final LinkedHashMap<String, PropertyLayoutData> propertiesById = Maps.newLinkedHashMap();
+ visit(new BS3Grid.VisitorAdapter() {
+ public void visit(final PropertyLayoutData propertyLayoutData) {
+ propertiesById.put(propertyLayoutData.getId(), propertyLayoutData);
+ }
+ });
+ return propertiesById;
+ }
+
+
+ @Programmatic
+ @XmlTransient
+ public LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById() {
+ final LinkedHashMap<String, CollectionLayoutData> collectionsById = Maps.newLinkedHashMap();
+
+ visit(new BS3Grid.VisitorAdapter() {
+ @Override
+ public void visit(final CollectionLayoutData collectionLayoutData) {
+ collectionsById.put(collectionLayoutData.getId(), collectionLayoutData);
+ }
+ });
+ return collectionsById;
+ }
+
+
+ @Programmatic
+ @XmlTransient
+ public LinkedHashMap<String, ActionLayoutData> getAllActionsById() {
+ final LinkedHashMap<String, ActionLayoutData> actionsById = Maps.newLinkedHashMap();
+
+ visit(new BS3Grid.VisitorAdapter() {
+ @Override
+ public void visit(final ActionLayoutData actionLayoutData) {
+ actionsById.put(actionLayoutData.getId(), actionLayoutData);
+ }
+ });
+ return actionsById;
+ }
+
+
+ @Programmatic
+ @XmlTransient
+ public LinkedHashMap<String, FieldSet> getAllFieldSetsByName() {
+ final LinkedHashMap<String, FieldSet> fieldSetsByName = Maps.newLinkedHashMap();
+
+ visit(new BS3Grid.VisitorAdapter() {
+ @Override
+ public void visit(final FieldSet fieldSet) {
+ fieldSetsByName.put(fieldSet.getName(), fieldSet);
+ }
+ });
+ return fieldSetsByName;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
index 25436ea..4c29f26 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
@@ -31,10 +31,11 @@ import com.google.common.collect.Lists;
import org.apache.isis.applib.annotation.MemberGroupLayout;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.CollectionLayoutDataOwner;
import org.apache.isis.applib.layout.common.FieldSet;
-import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.layout.common.MemberRegionOwner;
+import org.apache.isis.applib.layout.common.FieldSetOwner;
import org.apache.isis.applib.layout.common.Owned;
+import org.apache.isis.applib.layout.common.PropertyLayoutData;
/**
* The column contains a mixture of {@link FieldSet}s (of {@link PropertyLayoutData properties}) and also
@@ -52,7 +53,7 @@ import org.apache.isis.applib.layout.common.Owned;
, "collections"
}
)
-public class FCColumn implements Serializable, MemberRegionOwner, Owned<FCColumnOwner> {
+public class FCColumn implements Serializable, FieldSetOwner, CollectionLayoutDataOwner, Owned<FCColumnOwner> {
private static final long serialVersionUID = 1L;
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
index ed32e64..01626dd 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
@@ -19,23 +19,20 @@
package org.apache.isis.applib.layout.fixedcols;
import java.io.Serializable;
-import java.util.LinkedHashMap;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
-import com.google.common.collect.Maps;
-
-import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.ActionLayoutData;
import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
import org.apache.isis.applib.layout.common.FieldSet;
import org.apache.isis.applib.layout.common.Grid;
+import org.apache.isis.applib.layout.common.GridAbstract;
import org.apache.isis.applib.layout.common.PropertyLayoutData;
import org.apache.isis.applib.services.dto.Dto;
@@ -55,7 +52,7 @@ import org.apache.isis.applib.services.dto.Dto;
, "right"
}
)
-public class FCGrid implements Grid, Dto, ActionLayoutDataOwner, Serializable, FCColumnOwner, FCTabGroupOwner {
+public class FCGrid extends GridAbstract implements Dto, ActionLayoutDataOwner, Serializable, FCColumnOwner, FCTabGroupOwner {
private static final long serialVersionUID = 1L;
@@ -114,18 +111,15 @@ public class FCGrid implements Grid, Dto, ActionLayoutDataOwner, Serializable, F
}
- interface Visitor {
+
+ interface Visitor extends Grid.Visitor {
void visit(final FCGrid fcPage);
void visit(final FCTabGroup fcTabGroup);
void visit(final FCTab fcTab);
void visit(final FCColumn fcColumn);
- void visit(final FieldSet fieldSet);
- void visit(final PropertyLayoutData propertyLayoutData);
- void visit(final CollectionLayoutData collectionLayoutData);
- void visit(final ActionLayoutData actionLayoutData);
}
- public static class VisitorAdapter implements Visitor {
+ public static class VisitorAdapter extends Grid.VisitorAdapter implements Visitor {
@Override
public void visit(final FCGrid fcPage) { }
@Override
@@ -135,8 +129,6 @@ public class FCGrid implements Grid, Dto, ActionLayoutDataOwner, Serializable, F
@Override
public void visit(final FCColumn fcColumn) { }
@Override
- public void visit(final FieldSet fieldSet) {}
- @Override
public void visit(final PropertyLayoutData propertyLayoutData) {}
@Override
public void visit(final CollectionLayoutData collectionLayoutData) {}
@@ -149,18 +141,19 @@ public class FCGrid implements Grid, Dto, ActionLayoutDataOwner, Serializable, F
* Visits all elements of the graph. The {@link Visitor} implementation
* can assume that all "owner" references are populated.
*/
- public void visit(final FCGrid.Visitor visitor) {
- visitor.visit(this);
+ public void visit(final Grid.Visitor visitor) {
+ FCGrid.Visitor fcVisitor = asFcVisitor(visitor);
+ fcVisitor.visit(this);
traverseActions(this, visitor);
traverseColumn(getLeft(), this, visitor);
final List<FCTabGroup> tabGroups = getTabGroups();
for (final FCTabGroup fcTabGroup : tabGroups) {
fcTabGroup.setOwner(this);
- visitor.visit(fcTabGroup);
+ fcVisitor.visit(fcTabGroup);
final List<FCTab> tabs = fcTabGroup.getTabs();
for (final FCTab fcTab : tabs) {
fcTab.setOwner(fcTabGroup);
- visitor.visit(fcTab);
+ fcVisitor.visit(fcTab);
traverseColumn(fcTab.getLeft(), fcTab, visitor);
traverseColumn(fcTab.getMiddle(), fcTab, visitor);
traverseColumn(fcTab.getRight(), fcTab, visitor);
@@ -170,135 +163,41 @@ public class FCGrid implements Grid, Dto, ActionLayoutDataOwner, Serializable, F
}
private void traverseColumn(
- final FCColumn fcColumn, final FCColumnOwner fcColumnOwner, final Visitor visitor) {
+ final FCColumn fcColumn,
+ final FCColumnOwner fcColumnOwner,
+ final Grid.Visitor visitor) {
if(fcColumn == null) {
return;
}
+ FCGrid.Visitor fcVisitor = asFcVisitor(visitor);
fcColumn.setOwner(fcColumnOwner);
- visitor.visit(fcColumn);
+ fcVisitor.visit(fcColumn);
traverseFieldSets(fcColumn, visitor);
traverseCollections(fcColumn, visitor);
}
- private void traverseFieldSets(final FCColumn fcColumn, final Visitor visitor) {
- for (final FieldSet fieldSet : fcColumn.getFieldSets()) {
- fieldSet.setOwner(fcColumn);
- visitor.visit(fieldSet);
- traverseActions(fieldSet, visitor);
- final List<PropertyLayoutData> properties = fieldSet.getProperties();
- for (final PropertyLayoutData propertyLayoutData : properties) {
- propertyLayoutData.setOwner(fieldSet);
- visitor.visit(propertyLayoutData);
- traverseActions(propertyLayoutData, visitor);
+ private static Visitor asFcVisitor(final Grid.Visitor visitor) {
+ return visitor instanceof Visitor? (Visitor) visitor : new VisitorAdapter() {
+ @Override public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
+ visitor.visit(domainObjectLayoutData);
}
- }
- }
- private void traverseCollections(final FCColumn fcColumn, final Visitor visitor) {
- for (final CollectionLayoutData collectionLayoutData : fcColumn.getCollections()) {
- collectionLayoutData.setOwner(fcColumn);
- visitor.visit(collectionLayoutData);
- traverseActions(collectionLayoutData, visitor);
- }
- }
-
- private void traverseActions(final ActionLayoutDataOwner actionLayoutDataOwner, final Visitor visitor) {
- final List<ActionLayoutData> actionLayoutDatas = actionLayoutDataOwner.getActions();
- if(actionLayoutDatas == null) {
- return;
- }
- for (final ActionLayoutData actionLayoutData : actionLayoutDatas) {
- actionLayoutData.setOwner(actionLayoutDataOwner);
- visitor.visit(actionLayoutData);
- }
- }
-
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById() {
- final LinkedHashMap<String, PropertyLayoutData> propertiesById = Maps.newLinkedHashMap();
- visit(new FCGrid.VisitorAdapter() {
- public void visit(final PropertyLayoutData propertyLayoutData) {
- propertiesById.put(propertyLayoutData.getId(), propertyLayoutData);
+ @Override public void visit(final ActionLayoutData actionLayoutData) {
+ visitor.visit(actionLayoutData);
}
- });
- return propertiesById;
- }
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById() {
- final LinkedHashMap<String, CollectionLayoutData> collectionsById = Maps.newLinkedHashMap();
-
- visit(new FCGrid.VisitorAdapter() {
- @Override
- public void visit(final CollectionLayoutData collectionLayoutData) {
- collectionsById.put(collectionLayoutData.getId(), collectionLayoutData);
- }
- });
- return collectionsById;
- }
-
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, ActionLayoutData> getAllActionsById() {
- final LinkedHashMap<String, ActionLayoutData> actionsById = Maps.newLinkedHashMap();
-
- visit(new FCGrid.VisitorAdapter() {
- @Override
- public void visit(final ActionLayoutData actionLayoutData) {
- actionsById.put(actionLayoutData.getId(), actionLayoutData);
+ @Override public void visit(final PropertyLayoutData propertyLayoutData) {
+ visitor.visit(propertyLayoutData);
}
- });
- return actionsById;
- }
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, FieldSet> getAllFieldSetsByName() {
- final LinkedHashMap<String, FieldSet> fieldSetsByName = Maps.newLinkedHashMap();
-
- visit(new FCGrid.VisitorAdapter() {
- @Override
- public void visit(final FieldSet fieldSet) {
- fieldSetsByName.put(fieldSet.getName(), fieldSet);
+ @Override public void visit(final CollectionLayoutData collectionLayoutData) {
+ visitor.visit(collectionLayoutData);
}
- });
- return fieldSetsByName;
- }
-
- @Programmatic
- @XmlTransient
- public LinkedHashMap<String, FCTab> getAllTabsByName() {
- final LinkedHashMap<String, FCTab> tabsByName = Maps.newLinkedHashMap();
-
- visit(new FCGrid.VisitorAdapter() {
- @Override
- public void visit(final FCTab fcTab) {
- tabsByName.put(fcTab.getName(), fcTab);
+ @Override public void visit(final FieldSet fieldSet) {
+ visitor.visit(fieldSet);
}
- });
- return tabsByName;
- }
-
-
-
- private boolean normalized;
-
- @Programmatic
- @XmlTransient
- public boolean isNormalized() {
- return normalized;
- }
-
- @Programmatic
- public void setNormalized(final boolean normalized) {
- this.normalized = normalized;
+ };
}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
index d2436db..844168b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
@@ -19,7 +19,7 @@ package org.apache.isis.core.metamodel.services.grid;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.layout.common.Grid;
-public interface GridNormalizerService {
+public interface GridNormalizerService<G extends Grid> {
@Programmatic
Class<? extends Grid> gridImplementation();
@@ -31,6 +31,8 @@ public interface GridNormalizerService {
String schemaLocation();
@Programmatic
- void normalize(Grid grid, Class<?> domainClass);
+ void normalize(G grid, Class<?> domainClass);
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
new file mode 100644
index 0000000..1c0ab06
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
@@ -0,0 +1,335 @@
+/**
+ * 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.core.metamodel.services.grid;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.layout.common.ActionLayoutData;
+import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
+import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.FieldSet;
+import org.apache.isis.applib.layout.common.Grid;
+import org.apache.isis.applib.layout.common.MemberRegionOwner;
+import org.apache.isis.applib.layout.common.PropertyLayoutData;
+import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.applib.layout.fixedcols.FCColumnOwner;
+import org.apache.isis.applib.layout.fixedcols.FCGrid;
+import org.apache.isis.applib.layout.fixedcols.FCTab;
+import org.apache.isis.applib.services.i18n.TranslationService;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facets.actions.layout.ActionPositionFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.actions.layout.BookmarkPolicyFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.actions.layout.CssClassFaFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.actions.layout.CssClassFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.actions.layout.DescribedAsFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.actions.layout.HiddenFacetForActionLayoutXml;
+import org.apache.isis.core.metamodel.facets.actions.layout.NamedFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.CssClassFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.DefaultViewFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.DescribedAsFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.HiddenFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.NamedFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.PagedFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.layout.SortedByFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.CssClassFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.DescribedAsFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.HiddenFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.LabelAtFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.MultiLineFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.NamedFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.RenderedAdjustedFacetForPropertyXml;
+import org.apache.isis.core.metamodel.facets.properties.propertylayout.TypicalLengthFacetForPropertyXml;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+public abstract class GridNormalizerServiceAbstract<G extends Grid> implements GridNormalizerService<G> {
+
+ private final Class<G> gridImplementation;
+ private final String tns;
+ private final String schemaLocation;
+
+ public GridNormalizerServiceAbstract(
+ final Class<G> gridImplementation,
+ final String tns,
+ final String schemaLocation) {
+ this.gridImplementation = gridImplementation;
+ this.tns = tns;
+ this.schemaLocation = schemaLocation;
+ }
+
+ @Programmatic
+ @Override
+ public Class<G> gridImplementation() {
+ return gridImplementation;
+ }
+
+ @Programmatic
+ @Override
+ public String tns() {
+ return tns;
+ }
+
+ @Programmatic
+ @Override
+ public String schemaLocation() {
+ return schemaLocation;
+ }
+
+ @Programmatic
+ @Override
+ public void normalize(final G grid, final Class<?> domainClass) {
+
+ final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
+
+ final Map<String, OneToOneAssociation> oneToOneAssociationById =
+ ObjectMember.Util.mapById(getOneToOneAssociations(objectSpec));
+ final Map<String, OneToManyAssociation> oneToManyAssociationById =
+ ObjectMember.Util.mapById(getOneToManyAssociations(objectSpec));
+ final Map<String, ObjectAction> objectActionById =
+ ObjectMember.Util.mapById(objectSpec.getObjectActions(Contributed.INCLUDED));
+
+ final boolean validation = validateAndDerive(grid, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
+ if(validation) {
+ overwrite(grid, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
+ }
+ }
+
+ /**
+ * Ensures that all object members (properties, collections and actions) are in the metadata.
+ */
+ protected abstract boolean validateAndDerive(
+ final Grid grid,
+ final Map<String, OneToOneAssociation> oneToOneAssociationById,
+ final Map<String, OneToManyAssociation> oneToManyAssociationById,
+ final Map<String, ObjectAction> objectActionById);
+
+
+
+
+ protected void overwrite(
+ final G fcGrid,
+ final Map<String, OneToOneAssociation> oneToOneAssociationById,
+ final Map<String, OneToManyAssociation> oneToManyAssociationById,
+ final Map<String, ObjectAction> objectActionById) {
+
+ final Map<String, int[]> propertySequenceByGroup = Maps.newHashMap();
+
+ fcGrid.visit(new FCGrid.VisitorAdapter() {
+ private int collectionSequence = 1;
+ private int actionDomainObjectSequence = 1;
+ private int actionPropertyGroupSequence = 1;
+ private int actionPropertySequence = 1;
+ private int actionCollectionSequence = 1;
+
+ @Override
+ public void visit(final ActionLayoutData actionLayoutData) {
+ final ActionLayoutDataOwner actionLayoutDataOwner = actionLayoutData.getOwner();
+ final ObjectAction objectAction = objectActionById.get(actionLayoutData.getId());
+ if(objectAction == null) {
+ return;
+ }
+
+ final String memberOrderName;
+ final int memberOrderSequence;
+ if(actionLayoutDataOwner instanceof FieldSet) {
+ final FieldSet fieldSet = (FieldSet) actionLayoutDataOwner;
+ final List<PropertyLayoutData> properties = fieldSet.getProperties();
+ final PropertyLayoutData propertyLayoutData = properties.get(0); // any will do
+ memberOrderName = propertyLayoutData.getId();
+ memberOrderSequence = actionPropertyGroupSequence++;
+ } else if(actionLayoutDataOwner instanceof PropertyLayoutData) {
+ final PropertyLayoutData propertyLayoutData = (PropertyLayoutData) actionLayoutDataOwner;
+ memberOrderName = propertyLayoutData.getId();
+ memberOrderSequence = actionPropertySequence++;
+ } else if(actionLayoutDataOwner instanceof CollectionLayoutData) {
+ final CollectionLayoutData collectionLayoutData = (CollectionLayoutData) actionLayoutDataOwner;
+ memberOrderName = collectionLayoutData.getId();
+ memberOrderSequence = actionCollectionSequence++;
+ } else {
+ // DomainObject
+ memberOrderName = null;
+ memberOrderSequence = actionDomainObjectSequence++;
+ }
+ FacetUtil.addFacet(
+ new MemberOrderFacetXml(memberOrderName, ""+memberOrderSequence, translationService, objectAction));
+
+
+ if(actionLayoutDataOwner instanceof FieldSet) {
+ if(actionLayoutData.getPosition() == null ||
+ actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
+ actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.RIGHT) {
+ actionLayoutData.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.PANEL);
+ }
+ } else if(actionLayoutDataOwner instanceof PropertyLayoutData) {
+ if(actionLayoutData.getPosition() == null ||
+ actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL_DROPDOWN ||
+ actionLayoutData.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL) {
+ actionLayoutData.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.BELOW);
+ }
+ } else {
+ // doesn't do anything for DomainObject or Collection
+ actionLayoutData.setPosition(null);
+ }
+
+ FacetUtil.addFacet(ActionPositionFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addFacet(BookmarkPolicyFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addFacet(CssClassFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addFacet(CssClassFaFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addFacet(DescribedAsFacetForActionXml.create(actionLayoutData, objectAction));
+ FacetUtil.addFacet(HiddenFacetForActionLayoutXml.create(actionLayoutData, objectAction));
+ FacetUtil.addFacet(NamedFacetForActionXml.create(actionLayoutData, objectAction));
+ }
+
+ @Override
+ public void visit(final PropertyLayoutData propertyLayoutData) {
+ final OneToOneAssociation oneToOneAssociation = oneToOneAssociationById.get(propertyLayoutData.getId());
+ if(oneToOneAssociation == null) {
+ return;
+ }
+
+ FacetUtil.addFacet(CssClassFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(DescribedAsFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(HiddenFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(LabelAtFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(MultiLineFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(NamedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(
+ RenderedAdjustedFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+ FacetUtil.addFacet(TypicalLengthFacetForPropertyXml.create(propertyLayoutData, oneToOneAssociation));
+
+ // @MemberOrder#name based on owning property group, @MemberOrder#sequence monotonically increasing
+ final FieldSet fieldSet = propertyLayoutData.getOwner();
+ final String groupName = fieldSet.getName();
+ final String sequence = nextInSequenceFor(groupName, propertySequenceByGroup);
+ FacetUtil.addFacet(
+ new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
+ }
+
+ @Override
+ public void visit(final CollectionLayoutData collectionLayoutData) {
+ final OneToManyAssociation oneToManyAssociation = oneToManyAssociationById.get(collectionLayoutData.getId());
+ if(oneToManyAssociation == null) {
+ return;
+ }
+
+ FacetUtil.addFacet(CssClassFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addFacet(
+ DefaultViewFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addFacet(
+ DescribedAsFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addFacet(HiddenFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addFacet(NamedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addFacet(PagedFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+ FacetUtil.addFacet(SortedByFacetForCollectionXml.create(collectionLayoutData, oneToManyAssociation));
+
+ // @MemberOrder#name based on the collection's id (so that each has a single "member group")
+ final String groupName = collectionLayoutData.getId();
+ final String sequence = "" + collectionSequence++;
+ FacetUtil.addFacet(
+ new MemberOrderFacetXml(groupName, sequence, translationService, oneToManyAssociation));
+
+ // if there is only a single column and no other contents, then copy the collection Id onto the tab'
+ final MemberRegionOwner memberRegionOwner = collectionLayoutData.getOwner();
+ if(memberRegionOwner instanceof FCColumn) {
+ final FCColumn FCColumn = (FCColumn) memberRegionOwner;
+ final FCColumnOwner holder = FCColumn.getOwner();
+ if(holder instanceof FCTab) {
+ final FCTab FCTab = (FCTab) holder;
+ if(FCTab.getContents().size() == 1 && Strings.isNullOrEmpty(FCTab.getName()) ) {
+ final String collectionName = oneToManyAssociation.getName();
+ FCTab.setName(collectionName);
+ }
+ }
+ }
+ }
+ });
+ }
+
+
+ protected static List<OneToOneAssociation> getOneToOneAssociations(final ObjectSpecification objectSpec) {
+ List associations = objectSpec.getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.PROPERTIES);
+ return associations;
+ }
+ protected static List<OneToManyAssociation> getOneToManyAssociations(final ObjectSpecification objectSpec) {
+ List associations = objectSpec.getAssociations(Contributed.INCLUDED, ObjectAssociation.Filters.COLLECTIONS);
+ return associations;
+ }
+
+
+
+ protected static class Tuple<T> {
+ public final T first;
+ public final T second;
+ private Tuple(final T first, final T second) {
+ this.first = first;
+ this.second = second;
+ }
+ public static <T> Tuple<T> of(final T first, final T second) {
+ return new Tuple<>(first, second);
+ }
+ }
+
+
+ /**
+ * Returns a 2-element tuple of [first-second, second-first]
+ */
+ protected static <T> Tuple<List<T>> surplusAndMissing(final Collection<T> first, final Collection<T> second){
+ final List<T> firstNotSecond = Lists.newArrayList(first);
+ firstNotSecond.removeAll(second);
+ final List<T> secondNotFirst = Lists.newArrayList(second);
+ secondNotFirst.removeAll(first);
+ return Tuple.of(firstNotSecond, secondNotFirst);
+ }
+
+
+ protected static String nextInSequenceFor(
+ final String key, final Map<String, int[]> seqByKey) {
+ synchronized (seqByKey) {
+ int[] holder = seqByKey.get(key);
+ if(holder == null) {
+ holder = new int[]{0};
+ seqByKey.put(key, holder);
+ }
+ holder[0]++;
+ return ""+holder[0];
+ }
+ }
+
+
+ @Inject
+ SpecificationLoader specificationLookup;
+ @Inject
+ TranslationService translationService;
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerUtil.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerUtil.java
new file mode 100644
index 0000000..7f09ee9
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerUtil.java
@@ -0,0 +1,38 @@
+/**
+ * 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.core.metamodel.services.grid;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+public class GridNormalizerUtil {
+
+ private GridNormalizerUtil(){}
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/fe46a781/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
index 0b69210..a4f845a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridNormalizerServiceBS3.java
@@ -16,56 +16,230 @@
*/
package org.apache.isis.core.metamodel.services.grid.bootstrap3;
-import javax.inject.Inject;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.layout.bootstrap3.BS3Col;
import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
+import org.apache.isis.applib.layout.bootstrap3.BS3Row;
+import org.apache.isis.applib.layout.bootstrap3.BS3Tab;
+import org.apache.isis.applib.layout.bootstrap3.BS3TabGroup;
+import org.apache.isis.applib.layout.common.ActionLayoutData;
+import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.FieldSet;
import org.apache.isis.applib.layout.common.Grid;
-import org.apache.isis.applib.services.i18n.TranslationService;
-import org.apache.isis.core.metamodel.services.grid.GridNormalizerService;
-import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.applib.layout.common.PropertyLayoutData;
+import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
+import org.apache.isis.core.metamodel.services.grid.GridNormalizerServiceAbstract;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
@DomainService(
nature = NatureOfService.DOMAIN
)
-public class GridNormalizerServiceBS3 implements GridNormalizerService {
+public class GridNormalizerServiceBS3 extends GridNormalizerServiceAbstract<BS3Grid> {
public static final String TNS = "http://isis.apache.org/schema/applib/layout/bootstrap3";
public static final String SCHEMA_LOCATION = "http://isis.apache.org/schema/applib/layout/bootstrap3/bootstrap3.xsd";
+ public GridNormalizerServiceBS3() {
+ super(BS3Grid.class, TNS, SCHEMA_LOCATION);
+ }
- @Programmatic
@Override
- public Class<? extends Grid> gridImplementation() {
- return BS3Grid.class;
- }
+ protected boolean validateAndDerive(
+ final Grid grid,
+ final Map<String, OneToOneAssociation> oneToOneAssociationById,
+ final Map<String, OneToManyAssociation> oneToManyAssociationById,
+ final Map<String, ObjectAction> objectActionById) {
- @Programmatic
- @Override
- public String tns() {
- return TNS;
- }
+ final BS3Grid bs3Grid = (BS3Grid) grid;
- @Programmatic
- @Override
- public String schemaLocation() {
- return SCHEMA_LOCATION;
- }
+ final LinkedHashMap<String, PropertyLayoutData> propertyIds = bs3Grid.getAllPropertiesById();
+ final LinkedHashMap<String, CollectionLayoutData> collectionIds = bs3Grid.getAllCollectionsById();
+ final LinkedHashMap<String, ActionLayoutData> actionIds = bs3Grid.getAllActionsById();
- @Override
- public void normalize(final Grid grid, final Class<?> domainClass) {
- BS3Grid bs3Grid = (BS3Grid) grid;
- // TODO
- }
+ // find all row and col ids
+ // ensure that all Ids are different
+
+ final LinkedHashMap<String, BS3Row> rowIds = Maps.newLinkedHashMap();
+ final LinkedHashMap<String, BS3Col> colIds = Maps.newLinkedHashMap();
+
+ final AtomicReference<Boolean> duplicateIdDetected = new AtomicReference<>(false);
+
+ bs3Grid.visit(new BS3Grid.VisitorAdapter(){
+ @Override
+ public void visit(final BS3Row bs3Row) {
+ final String id = bs3Row.getId();
+ if(id == null) {
+ return;
+ }
+ if(rowIds.containsKey(id) || colIds.containsKey(id)) {
+ bs3Row.setMetadataError("There is another col with this id");
+ duplicateIdDetected.set(true);
+ return;
+ }
+ rowIds.put(id, bs3Row);
+ }
+
+ @Override
+ public void visit(final BS3Col bs3Col) {
+ final String id = bs3Col.getId();
+ if(id == null) {
+ return;
+ }
+ if(rowIds.containsKey(id) || colIds.containsKey(id)) {
+ bs3Col.setMetadataError("There is another col with this id");
+ duplicateIdDetected.set(true);
+ return;
+ }
+ colIds.put(id, bs3Col);
+ }
+ });
+
+ if(duplicateIdDetected.get()) {
+ return false;
+ }
+
+ // ensure that there is exactly one col with the
+ // unreferencedActions, unreferencedProperties and unreferencedCollections attribute set.
- @Inject
- SpecificationLoader specificationLookup;
- @Inject
- TranslationService translationService;
+ final AtomicReference<BS3Col> colForUnreferencedActionsRef = new AtomicReference<>();
+ final AtomicReference<BS3Col> colForUnreferencedPropertiesRef = new AtomicReference<>();
+ final AtomicReference<FieldSet> fieldSetForUnreferencedPropsRef = new AtomicReference<>();
+ final AtomicReference<BS3Col> colForUnreferencedCollectionsRef = new AtomicReference<>();
+
+ bs3Grid.visit(new BS3Grid.VisitorAdapter(){
+ @Override
+ public void visit(final BS3Col bs3Col) {
+ if(bs3Col.isUnreferencedActions()) {
+ if(colForUnreferencedActionsRef.get() != null) {
+ bs3Col.setMetadataError("More than one col with 'unreferencedActions' attribute set");
+ } else {
+ colForUnreferencedActionsRef.set(bs3Col);
+ }
+ }
+ if(bs3Col.isUnreferencedProperties()) {
+ if(colForUnreferencedPropertiesRef.get() != null) {
+ bs3Col.setMetadataError("More than one col with 'unreferencedProperties' attribute set");
+ } else {
+ final List<FieldSet> fieldSets = bs3Col.getFieldSets();
+ for (FieldSet fieldSet : fieldSets) {
+ if(fieldSet.getName().equals(MemberGroupLayoutFacet.DEFAULT_GROUP)) {
+ fieldSetForUnreferencedPropsRef.set(fieldSet);
+ }
+ }
+ colForUnreferencedPropertiesRef.set(bs3Col);
+ }
+ }
+ if(bs3Col.isUnreferencedCollections()) {
+ if(colForUnreferencedCollectionsRef.get() != null) {
+ bs3Col.setMetadataError("More than one col with 'unreferencedCollections' attribute set");
+ } else {
+ colForUnreferencedCollectionsRef.set(bs3Col);
+ }
+ }
+ }
+ });
+
+ if( colForUnreferencedActionsRef.get() == null ||
+ colForUnreferencedPropertiesRef.get() == null ||
+ colForUnreferencedCollectionsRef.get() == null) {
+ return false;
+ }
+
+
+ // add missing properties will be added to the first fieldset of the specified column
+ final Tuple<List<String>> propertyIdTuple =
+ surplusAndMissing(propertyIds.keySet(), oneToOneAssociationById.keySet());
+ final List<String> surplusPropertyIds = propertyIdTuple.first;
+ final List<String> missingPropertyIds = propertyIdTuple.second;
+
+ for (String surplusPropertyId : surplusPropertyIds) {
+ propertyIds.get(surplusPropertyId).setMetadataError("No such property");
+ }
+
+ if(!missingPropertyIds.isEmpty()) {
+ final BS3Col bs3Col = colForUnreferencedPropertiesRef.get();
+ if(bs3Col != null) {
+ // ensure that there is a field set to use, else create
+ boolean wasSet = fieldSetForUnreferencedPropsRef.compareAndSet(null, new FieldSet(MemberGroupLayoutFacet.DEFAULT_GROUP));
+ final FieldSet fieldSetForUnref = fieldSetForUnreferencedPropsRef.get();
+ if(wasSet) {
+ fieldSetForUnref.setOwner(bs3Col);
+ bs3Col.getFieldSets().add(fieldSetForUnref);
+ }
+ for (final String propertyId : missingPropertyIds) {
+ bs3Col.getFieldSets().get(0).getProperties().add(new PropertyLayoutData(propertyId));
+ }
+ }
+ }
+
+ // any missing collections will be added as tabs to a new TabGroup in the specified column
+ final Tuple<List<String>> collectionIdTuple =
+ surplusAndMissing(collectionIds.keySet(), oneToManyAssociationById.keySet());
+ final List<String> surplusCollectionIds = collectionIdTuple.first;
+ final List<String> missingCollectionIds = collectionIdTuple.second;
+
+ for (String surplusCollectionId : surplusCollectionIds) {
+ collectionIds.get(surplusCollectionId).setMetadataError("No such collection");
+ }
+
+ if(!missingCollectionIds.isEmpty()) {
+ final BS3Col bs3Col = colForUnreferencedCollectionsRef.get();
+ if(bs3Col != null) {
+ final BS3TabGroup tabGroup = new BS3TabGroup();
+ tabGroup.setOwner(bs3Col);
+ bs3Col.getTabGroups().add(tabGroup);
+ for (final String collectionId : missingCollectionIds) {
+ final BS3Tab bs3Tab = new BS3Tab();
+ tabGroup.getTabs().add(bs3Tab);
+ FCColumn left = new FCColumn(12);
+ bs3Tab.setOwner(tabGroup);
+ final CollectionLayoutData layoutMetadata = new CollectionLayoutData(collectionId);
+ layoutMetadata.setDefaultView("table");
+ left.getCollections().add(layoutMetadata);
+ }
+ }
+ }
+
+ // any missing actions will be added as actions in the specified column
+ final Tuple<List<String>> actionIdTuple =
+ surplusAndMissing(actionIds.keySet(), objectActionById.keySet());
+ final List<String> surplusActionIds = actionIdTuple.first;
+ final List<String> missingActionIds = actionIdTuple.second;
+
+ for (String surplusActionId : surplusActionIds) {
+ actionIds.get(surplusActionId).setMetadataError("No such action");
+ }
+
+ if(!missingActionIds.isEmpty()) {
+ final BS3Col bs3Col = colForUnreferencedActionsRef.get();
+ if(bs3Col != null) {
+ for (String actionId : missingActionIds) {
+ List<ActionLayoutData> actions = bs3Col.getActions();
+ if(actions == null) {
+ actions = Lists.newArrayList();
+ bs3Col.setActions(actions);
+ }
+ actions.add(new ActionLayoutData(actionId));
+ }
+ }
+ }
+
+ return true;
+ }
}