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/01/25 15:40:54 UTC
[30/50] [abbrv] isis git commit: ISIS-993: working towards getting
dynamic reloading working smoothly - not there yet.
ISIS-993: working towards getting dynamic reloading working smoothly - not there yet.
* moved responsibility for reading the XML to ObjectLayoutMetadataFacet (not certain if that was a good idea).
* Update to MedataMenu to switch on/off dynamic layouts. Don't invalidate entire spec, instead just reload the metadata.
* EntityModel cloning now shares the assocated ScalarModel map (a shallow clone), needed for edit form
* ObjectReflectorDefault only eagerly loads specs for contributed services and mixins, in an attempt to reduce startup time
* EntityTabGroupsPanelFactory now created ether the EntityTabGroupsPanel or the original EntityCombinedPanel, depending on whether there is layout.xml metadata
* added some further convenience methods to ObjectLayoutMetadata.
What I would like to do is to eagerly load up the layout.xml up front rather than lazily. However, attempting to do that caused a stackoverflow, and not sure why. As things stand I also have an issue with edit failing for the todoapp if no layout data at all, not sure why.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/47f4aea4
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/47f4aea4
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/47f4aea4
Branch: refs/heads/ISIS-993
Commit: 47f4aea4b39e688ab0f9b750c2419976b7958a30
Parents: aacec3b
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Jan 12 18:23:47 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon Jan 25 14:38:24 2016 +0000
----------------------------------------------------------------------
.../layout/v1_0/ObjectLayoutMetadata.java | 53 ++-
.../isis/applib/layout/v1_0/PropertyGroup.java | 9 +-
.../layout/ObjectLayoutMetadataService.java | 17 +-
.../layout/Object_downloadLayoutXml.java | 13 +-
.../facetdecorator/FacetDecoratorSet.java | 11 +-
.../ObjectLayoutMetadataFacet.java | 11 +-
.../ObjectLayoutMetadataFacetDefault.java | 423 ++++++++++++++++++-
.../ObjectLayoutMetadataFacetFactory.java | 12 +-
.../ObjectLayoutMetadataServiceDefault.java | 378 +----------------
.../services/metamodel/MetadataMenu.java | 45 +-
.../specloader/ObjectReflectorDefault.java | 10 +-
.../specimpl/FacetedMethodsBuilder.java | 6 +-
.../specimpl/ObjectActionContributee.java | 3 +
.../dflt/ObjectSpecificationDefault.java | 2 +
.../v1_0/ObjectLayoutMetadataTest.java | 5 +-
.../viewer/wicket/model/models/EntityModel.java | 36 +-
.../combined/EntityCombinedPanelFactory.java | 9 +-
.../entity/properties/EntityColumnMembers.java | 5 +-
.../entity/properties/EntityPropertiesForm.java | 4 +-
.../EntityTabGroupsPanel$EntityTabPanel.html | 5 +-
.../entity/tabgroups/EntityTabGroupsPanel.java | 15 +-
.../tabgroups/EntityTabGroupsPanelFactory.java | 14 +-
.../wicket/ui/pages/entity/EntityPage.java | 22 +-
23 files changed, 626 insertions(+), 482 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
index 2f056a8..4af327c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
@@ -33,7 +33,6 @@ import com.google.common.collect.Maps;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.services.dto.Dto;
-import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
@XmlRootElement(
name = "objectLayout"
@@ -182,62 +181,74 @@ public class ObjectLayoutMetadata implements Dto, ActionHolder, Serializable {
@Programmatic
@XmlTransient
public LinkedHashMap<String, PropertyLayoutMetadata> getAllPropertiesById() {
- final LinkedHashMap<String, PropertyLayoutMetadata> propertyIds = Maps.newLinkedHashMap();
+ final LinkedHashMap<String, PropertyLayoutMetadata> propertiesById = Maps.newLinkedHashMap();
visit(new ObjectLayoutMetadata.VisitorAdapter() {
public void visit(final PropertyLayoutMetadata propertyLayoutMetadata) {
- propertyIds.put(propertyLayoutMetadata.getId(), propertyLayoutMetadata);
+ propertiesById.put(propertyLayoutMetadata.getId(), propertyLayoutMetadata);
}
});
- return propertyIds;
+ return propertiesById;
}
@Programmatic
@XmlTransient
public LinkedHashMap<String, CollectionLayoutMetadata> getAllCollectionsById() {
- final LinkedHashMap<String, CollectionLayoutMetadata> collectionIds = Maps.newLinkedHashMap();
- final LinkedHashMap<String, ActionLayoutMetadata> actionIds = Maps.newLinkedHashMap();
+ final LinkedHashMap<String, CollectionLayoutMetadata> collectionsById = Maps.newLinkedHashMap();
visit(new ObjectLayoutMetadata.VisitorAdapter() {
@Override
public void visit(final CollectionLayoutMetadata collectionLayoutMetadata) {
- collectionIds.put(collectionLayoutMetadata.getId(), collectionLayoutMetadata);
+ collectionsById.put(collectionLayoutMetadata.getId(), collectionLayoutMetadata);
}
});
- return collectionIds;
+ return collectionsById;
}
@Programmatic
@XmlTransient
public LinkedHashMap<String, ActionLayoutMetadata> getAllActionsById() {
- final LinkedHashMap<String, ActionLayoutMetadata> actionIds = Maps.newLinkedHashMap();
+ final LinkedHashMap<String, ActionLayoutMetadata> actionsById = Maps.newLinkedHashMap();
visit(new ObjectLayoutMetadata.VisitorAdapter() {
@Override
public void visit(final ActionLayoutMetadata actionLayoutMetadata) {
- actionIds.put(actionLayoutMetadata.getId(), actionLayoutMetadata);
+ actionsById.put(actionLayoutMetadata.getId(), actionLayoutMetadata);
}
});
- return actionIds;
+ return actionsById;
}
+ @Programmatic
+ @XmlTransient
+ public LinkedHashMap<String, Tab> getAllTabsByName() {
+ final LinkedHashMap<String, Tab> tabsByName = Maps.newLinkedHashMap();
+
+ visit(new ObjectLayoutMetadata.VisitorAdapter() {
+ @Override
+ public void visit(final Tab tab) {
+ tabsByName.put(tab.getName(), tab);
+ }
+ });
+ return tabsByName;
+ }
- private boolean normalized;
- /**
- * Whether {@link ObjectLayoutMetadataService#normalize(ObjectLayoutMetadata, Class)}
- * has been called on this instance.
- */
@Programmatic
@XmlTransient
- public boolean isNormalized() {
- return normalized;
- }
+ public LinkedHashMap<String, PropertyGroup> getAllPropertyGroupsByName() {
+ final LinkedHashMap<String, PropertyGroup> propertyGroupsByName = Maps.newLinkedHashMap();
- public void setNormalized(final boolean normalized) {
- this.normalized = normalized;
+ visit(new ObjectLayoutMetadata.VisitorAdapter() {
+ @Override
+ public void visit(final PropertyGroup propertyGroup) {
+ propertyGroupsByName.put(propertyGroup.getName(), propertyGroup);
+ }
+ });
+ return propertyGroupsByName;
}
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
index fd7f3c7..2fb52e3 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/PropertyGroup.java
@@ -19,7 +19,6 @@
package org.apache.isis.applib.layout.v1_0;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@@ -30,6 +29,7 @@ import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.google.common.base.Function;
+import com.google.common.collect.Lists;
import org.apache.isis.applib.annotation.MemberOrder;
@@ -67,7 +67,7 @@ public class PropertyGroup implements ColumnContent, ActionHolder, Serializable
- private List<ActionLayoutMetadata> actions;
+ private List<ActionLayoutMetadata> actions = Lists.newArrayList();
@XmlElementWrapper(required = false)
@XmlElement(name = "action", required = false)
@@ -81,10 +81,7 @@ public class PropertyGroup implements ColumnContent, ActionHolder, Serializable
- // must be at least one property in the property group
- private List<PropertyLayoutMetadata> properties = new ArrayList<PropertyLayoutMetadata>() {{
- add(new PropertyLayoutMetadata());
- }};
+ private List<PropertyLayoutMetadata> properties = Lists.newArrayList();
@XmlElement(name = "property", required = true)
public List<PropertyLayoutMetadata> getProperties() {
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
index f0da669..e29ff47 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
@@ -28,22 +28,21 @@ public interface ObjectLayoutMetadataService {
ObjectLayoutMetadata fromXml(Class<?> domainClass);
/**
- * @param objectLayoutMetadata - the layout to be validated.
- * @param domainClass - as per domain class.
- */
- @Programmatic
- ObjectLayoutMetadata normalize(final ObjectLayoutMetadata objectLayoutMetadata, final Class<?> domainClass);
-
- /**
- * Obtains the layout metadata for the specified domain object. It will have been {@link #normalize(ObjectLayoutMetadata, Class) normalized} already.
+ * Obtains the layout metadata, if any, for the (domain class of the) specified domain object.
*/
@Programmatic
ObjectLayoutMetadata toMetadata(Object domainObject);
/**
- * Obtains the layout metadata for the specified domain class. It will have been {@link #normalize(ObjectLayoutMetadata, Class) normalized} already.
+ * Obtains the layout metadata, if any, for the specified domain class.
*/
@Programmatic
ObjectLayoutMetadata toMetadata(Class<?> domainClass);
+ @Programmatic
+ void toggleDynamicReloading();
+
+ @Programmatic
+ boolean isDynamicReloading();
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
index aca104c..726becf 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
@@ -17,6 +17,9 @@
package org.apache.isis.applib.services.layout;
import javax.inject.Inject;
+import javax.xml.bind.Marshaller;
+
+import com.google.common.collect.ImmutableMap;
import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.ActionLayout;
@@ -32,6 +35,9 @@ import org.apache.isis.applib.value.Clob;
@Mixin
public class Object_downloadLayoutXml {
+ public static final String TNS = "http://isis.apache.org/schema/applib/layout";
+ public static final String SCHEMA_LOCATION = "http://isis.apache.org/schema/applib/layout/layout-1.0.xsd";
+
private final Object object;
public Object_downloadLayoutXml(final Object object) {
@@ -53,7 +59,12 @@ public class Object_downloadLayoutXml {
@ParameterLayout(named = "File name")
final String fileName) {
final ObjectLayoutMetadata metadata = getObjectLayoutMetadata();
- final String xml = jaxbService.toXml(metadata);
+ final String xml = jaxbService.toXml(metadata,
+ ImmutableMap.<String,Object>of(
+ Marshaller.JAXB_SCHEMA_LOCATION,
+ TNS + " " + SCHEMA_LOCATION
+ ));
+
return new Clob(Util.withSuffix(fileName, "xml"), "text/xml", xml);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetdecorator/FacetDecoratorSet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetdecorator/FacetDecoratorSet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetdecorator/FacetDecoratorSet.java
index c540e30..38eb045 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetdecorator/FacetDecoratorSet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetdecorator/FacetDecoratorSet.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.facetdecorator;
import java.text.MessageFormat;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -81,10 +80,6 @@ public class FacetDecoratorSet implements ApplicationScopedComponent {
}
}
- public Set<FacetDecorator> getFacetDecorators() {
- return Collections.unmodifiableSet(facetDecoratorSet);
- }
-
public boolean isEmpty() {
return facetDecoratorByFacetType.isEmpty();
}
@@ -114,10 +109,12 @@ public class FacetDecoratorSet implements ApplicationScopedComponent {
if (isEmpty()) {
return;
}
- final Class<? extends Facet>[] facetTypes = holder.getFacetTypes();
+ final Set<Class<? extends Facet>> facetTypes = facetDecoratorByFacetType.keySet();
for (final Class<? extends Facet> facetType : facetTypes) {
final Facet facet = holder.getFacet(facetType);
- decorateFacet(facet, holder);
+ if(facet != null) {
+ decorateFacet(facet, holder);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
index 4d8db93..2a63428 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
@@ -19,8 +19,8 @@
package org.apache.isis.core.metamodel.facets.object.layoutmetadata;
-import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
+import org.apache.isis.core.metamodel.facetapi.Facet;
/**
* Corresponds to providing a <code>.layout.xml</code> file for the domain object's class.
@@ -28,8 +28,13 @@ import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
public interface ObjectLayoutMetadataFacet extends Facet {
/**
- * Will have been {@link org.apache.isis.applib.services.layout.ObjectLayoutMetadataService#normalize(ObjectLayoutMetadata, Class) normalized}.
+ * Will have been normalized by framework earlier.
*/
ObjectLayoutMetadata getMetadata();
-}
+ /**
+ * (Re)load, in support of dynamic layout reloading.
+ */
+ void reloadMetadata();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
index 95e3712..9538e72 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
@@ -18,19 +18,72 @@
*/
package org.apache.isis.core.metamodel.facets.object.layoutmetadata;
+import java.util.Collection;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.layout.v1_0.ActionHolder;
+import org.apache.isis.applib.layout.v1_0.ActionLayoutMetadata;
+import org.apache.isis.applib.layout.v1_0.CollectionLayoutMetadata;
+import org.apache.isis.applib.layout.v1_0.Column;
+import org.apache.isis.applib.layout.v1_0.ColumnHolder;
import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
+import org.apache.isis.applib.layout.v1_0.PropertyGroup;
+import org.apache.isis.applib.layout.v1_0.PropertyLayoutMetadata;
+import org.apache.isis.applib.layout.v1_0.Tab;
+import org.apache.isis.applib.layout.v1_0.TabGroup;
+import org.apache.isis.applib.services.i18n.TranslationService;
import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+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.spec.ObjectSpecification;
+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 class ObjectLayoutMetadataFacetDefault
extends FacetAbstract
implements ObjectLayoutMetadataFacet {
- private final ObjectLayoutMetadata metadata;
- private final ObjectLayoutMetadataService objectLayoutMetadataService;
+ private static final Logger LOG = LoggerFactory.getLogger(ObjectLayoutMetadataFacetDefault.class);
+
public static Class<? extends Facet> type() {
return ObjectLayoutMetadataFacet.class;
@@ -39,27 +92,375 @@ public class ObjectLayoutMetadataFacetDefault
public static ObjectLayoutMetadataFacet create(
final FacetHolder facetHolder,
- final ObjectLayoutMetadata objectLayoutMetadata,
+ final TranslationService translationService,
final ObjectLayoutMetadataService objectLayoutMetadataService) {
- if(objectLayoutMetadata == null) {
- return null;
- }
- return new ObjectLayoutMetadataFacetDefault(facetHolder, objectLayoutMetadata, objectLayoutMetadataService);
+ return new ObjectLayoutMetadataFacetDefault(facetHolder, translationService, objectLayoutMetadataService);
}
+ private final TranslationService translationService;
+ private final ObjectLayoutMetadataService objectLayoutMetadataService;
+
+ private boolean blacklisted;
+ private ObjectLayoutMetadata metadata;
+
private ObjectLayoutMetadataFacetDefault(
final FacetHolder facetHolder,
- final ObjectLayoutMetadata metadata,
+ final TranslationService translationService,
final ObjectLayoutMetadataService objectLayoutMetadataService) {
super(ObjectLayoutMetadataFacetDefault.type(), facetHolder, Derivation.NOT_DERIVED);
- this.metadata = metadata;
this.objectLayoutMetadataService = objectLayoutMetadataService;
+ this.translationService = translationService;
}
+ @Override
+ public boolean isNoop() {
+ getMetadata();
+ return blacklisted;
+ }
+ @Override
public ObjectLayoutMetadata getMetadata() {
- final ObjectSpecification objectSpecification = (ObjectSpecification) getFacetHolder();
- return objectLayoutMetadataService.normalize(metadata, objectSpecification.getCorrespondingClass());
+ if(blacklisted) {
+ return null;
+ }
+ reloadMetadata();
+ return this.metadata;
+ }
+
+ @Override
+ public void reloadMetadata() {
+ if (metadata != null && !objectLayoutMetadataService.isDynamicReloading()) {
+ return;
+ }
+ final Class<?> domainClass = getSpecification().getCorrespondingClass();
+ final ObjectLayoutMetadata metadata = objectLayoutMetadataService.fromXml(domainClass);
+ this.metadata = normalize(metadata);
+ blacklisted = this.metadata == null;
+ }
+
+ private ObjectLayoutMetadata normalize(final ObjectLayoutMetadata metadata) {
+ if(metadata == null) {
+ return null;
+ }
+ if(LOG.isInfoEnabled()) {
+ LOG.info("Normalizing layout metadata for " + getSpecification().getCorrespondingClass().getName());
+ }
+ doNormalize(metadata, getSpecification());
+ return metadata;
+ }
+
+ private void doNormalize(final ObjectLayoutMetadata metadata, final ObjectSpecification objectSpec) {
+
+ 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(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
+ overwrite(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
+ }
+
+ /**
+ * Ensures that all object members (properties, collections and actions) are in the metadata.
+ *
+ * <p>
+ * 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 ObjectLayoutMetadata metadata,
+ final Map<String, OneToOneAssociation> oneToOneAssociationById,
+ final Map<String, OneToManyAssociation> oneToManyAssociationById,
+ final Map<String, ObjectAction> objectActionById) {
+
+ final LinkedHashMap<String, PropertyLayoutMetadata> propertyIds = metadata.getAllPropertiesById();
+ final LinkedHashMap<String, CollectionLayoutMetadata> collectionIds = metadata.getAllCollectionsById();
+ final LinkedHashMap<String, ActionLayoutMetadata> actionIds = metadata.getAllActionsById();
+
+ final AtomicReference<PropertyGroup> defaultPropertyGroupRef = new AtomicReference<>();
+ final AtomicReference<Column> firstColumnRef = new AtomicReference<>();
+ final AtomicReference<TabGroup> lastTabGroupRef = new AtomicReference<>();
+
+ // capture the first column, and also
+ // capture the first property group (if any) with the default name ('General')
+ metadata.visit(new ObjectLayoutMetadata.VisitorAdapter() {
+ @Override
+ public void visit(final Column column) {
+ firstColumnRef.compareAndSet(null, column);
+ }
+ @Override
+ public void visit(final PropertyGroup propertyGroup) {
+ if(MemberGroupLayoutFacet.DEFAULT_GROUP.equals(propertyGroup.getName())) {
+ defaultPropertyGroupRef.compareAndSet(null, propertyGroup);
+ }
+ }
+ @Override
+ public void visit(final TabGroup tabGroup) {
+ lastTabGroupRef.set(tabGroup);
+ }
+ });
+
+ // any missing properties will be added to the (first) 'General' property group found
+ // if there is no default ('General') property group
+ // then one will be added to the first Column of the first Tab.
+ 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()) {
+ // ensure that there is a property group to use
+ boolean wasSet = defaultPropertyGroupRef.compareAndSet(null, new PropertyGroup(MemberGroupLayoutFacet.DEFAULT_GROUP));
+ final PropertyGroup defaultPropertyGroup = defaultPropertyGroupRef.get();
+ if(wasSet) {
+ firstColumnRef.get().getPropertyGroups().add(defaultPropertyGroup);
+ }
+ for (final String propertyId : missingPropertyIds) {
+ defaultPropertyGroup.getProperties().add(new PropertyLayoutMetadata(propertyId));
+ }
+ }
+
+
+ // any missing collections will be added as tabs to the last TabGroup.
+ // If there is only a single tab group then a new TabGroup will be added first
+ 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()) {
+ while(metadata.getTabGroups().size() < 2) {
+ final TabGroup tabGroup = new TabGroup();
+ metadata.getTabGroups().add(tabGroup);
+ lastTabGroupRef.set(tabGroup);
+ }
+ final TabGroup lastTabGroup = lastTabGroupRef.get();
+ for (final String collectionId : missingCollectionIds) {
+ final Tab tab = new Tab();
+ lastTabGroup.getTabs().add(tab);
+ Column left = new Column(12);
+ tab.setLeft(left);
+ final CollectionLayoutMetadata layoutMetadata = new CollectionLayoutMetadata(collectionId);
+ layoutMetadata.setDefaultView("table");
+ left.getCollections().add(layoutMetadata);
+ }
+ }
+
+ // any missing actions will be added as domain object actions (in the header)
+ 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()) {
+ for (String actionId : missingActionIds) {
+ List<ActionLayoutMetadata> actions = metadata.getActions();
+ if(actions == null) {
+ actions = Lists.newArrayList();
+ metadata.setActions(actions);
+ }
+ actions.add(new ActionLayoutMetadata(actionId));
+ }
+ }
+ }
+
+ 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 ObjectLayoutMetadata metadata,
+ final Map<String, OneToOneAssociation> oneToOneAssociationById,
+ final Map<String, OneToManyAssociation> oneToManyAssociationById,
+ final Map<String, ObjectAction> objectActionById) {
+
+ final Map<String, int[]> propertySequenceByGroup = Maps.newHashMap();
+
+ metadata.visit(new ObjectLayoutMetadata.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 ActionLayoutMetadata actionLayoutMetadata) {
+ final ActionHolder actionHolder = actionLayoutMetadata.getOwner();
+ final ObjectAction objectAction = objectActionById.get(actionLayoutMetadata.getId());
+ if(objectAction == null) {
+ return;
+ }
+
+ final String memberOrderName;
+ final int memberOrderSequence;
+ if(actionHolder instanceof PropertyGroup) {
+ final PropertyGroup propertyGroup = (PropertyGroup) actionHolder;
+ final List<PropertyLayoutMetadata> properties = propertyGroup.getProperties();
+ final PropertyLayoutMetadata propertyLayoutMetadata = properties.get(0); // any will do
+ memberOrderName = propertyLayoutMetadata.getId();
+ memberOrderSequence = actionPropertyGroupSequence++;
+ } else if(actionHolder instanceof PropertyLayoutMetadata) {
+ final PropertyLayoutMetadata propertyLayoutMetadata = (PropertyLayoutMetadata) actionHolder;
+ memberOrderName = propertyLayoutMetadata.getId();
+ memberOrderSequence = actionPropertySequence++;
+ } else if(actionHolder instanceof CollectionLayoutMetadata) {
+ final CollectionLayoutMetadata collectionLayoutMetadata = (CollectionLayoutMetadata) actionHolder;
+ memberOrderName = collectionLayoutMetadata.getId();
+ memberOrderSequence = actionCollectionSequence++;
+ } else {
+ // DomainObject
+ memberOrderName = null;
+ memberOrderSequence = actionDomainObjectSequence++;
+ }
+ FacetUtil.addFacet(
+ new MemberOrderFacetXml(memberOrderName, ""+memberOrderSequence, translationService, objectAction));
+
+
+ if(actionHolder instanceof PropertyGroup) {
+ if(actionLayoutMetadata.getPosition() == null ||
+ actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
+ actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.RIGHT) {
+ actionLayoutMetadata.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.PANEL);
+ }
+ } else if(actionHolder instanceof PropertyLayoutMetadata) {
+ if(actionLayoutMetadata.getPosition() == null ||
+ actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL_DROPDOWN ||
+ actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL) {
+ actionLayoutMetadata.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.BELOW);
+ }
+ } else {
+ // doesn't do anything for DomainObject or Collection
+ actionLayoutMetadata.setPosition(null);
+ }
+
+ FacetUtil.addFacet(ActionPositionFacetForActionXml.create(actionLayoutMetadata, objectAction));
+ FacetUtil.addFacet(BookmarkPolicyFacetForActionXml.create(actionLayoutMetadata, objectAction));
+ FacetUtil.addFacet(CssClassFacetForActionXml.create(actionLayoutMetadata, objectAction));
+ FacetUtil.addFacet(CssClassFaFacetForActionXml.create(actionLayoutMetadata, objectAction));
+ FacetUtil.addFacet(DescribedAsFacetForActionXml.create(actionLayoutMetadata, objectAction));
+ FacetUtil.addFacet(HiddenFacetForActionLayoutXml.create(actionLayoutMetadata, objectAction));
+ FacetUtil.addFacet(NamedFacetForActionXml.create(actionLayoutMetadata, objectAction));
+ }
+
+ @Override
+ public void visit(final PropertyLayoutMetadata propertyLayoutMetadata) {
+ final OneToOneAssociation oneToOneAssociation = oneToOneAssociationById.get(propertyLayoutMetadata.getId());
+ if(oneToOneAssociation == null) {
+ return;
+ }
+
+ FacetUtil.addFacet(CssClassFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(DescribedAsFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(HiddenFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(LabelAtFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(MultiLineFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(NamedFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(
+ RenderedAdjustedFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+ FacetUtil.addFacet(TypicalLengthFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
+
+ // @MemberOrder#name based on owning property group, @MemberOrder#sequence monotonically increasing
+ final PropertyGroup propertyGroup = propertyLayoutMetadata.getOwner();
+ final String groupName = propertyGroup.getName();
+ final String sequence = nextInSequenceFor(groupName, propertySequenceByGroup);
+ FacetUtil.addFacet(
+ new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
+ }
+
+ @Override
+ public void visit(final CollectionLayoutMetadata collectionLayoutMetadata) {
+ final OneToManyAssociation oneToManyAssociation = oneToManyAssociationById.get(collectionLayoutMetadata.getId());
+ if(oneToManyAssociation == null) {
+ return;
+ }
+
+ FacetUtil.addFacet(CssClassFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+ FacetUtil.addFacet(
+ DefaultViewFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+ FacetUtil.addFacet(
+ DescribedAsFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+ FacetUtil.addFacet(HiddenFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+ FacetUtil.addFacet(NamedFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+ FacetUtil.addFacet(PagedFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+ FacetUtil.addFacet(SortedByFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
+
+ // @MemberOrder#name based on the collection's id (so that each has a single "member group")
+ final String groupName = collectionLayoutMetadata.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 Column column = collectionLayoutMetadata.getOwner();
+ final ColumnHolder holder = column.getOwner();
+ if(holder instanceof Tab) {
+ final Tab tab = (Tab) holder;
+ if(tab.getContents().size() == 1) {
+ final String collectionName = oneToManyAssociation.getName();
+ tab.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;
+ }
+
+ private ObjectSpecification getSpecification() {
+ return (ObjectSpecification)getFacetHolder();
+ }
+
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
index 0f1b4e8..479849c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
@@ -19,7 +19,7 @@ package org.apache.isis.core.metamodel.facets.object.layoutmetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
+import org.apache.isis.applib.services.i18n.TranslationService;
import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -38,17 +38,13 @@ public class ObjectLayoutMetadataFacetFactory extends FacetFactoryAbstract imple
@Override
public void process(final ProcessClassContext processClassContext) {
- final Class<?> cls = processClassContext.getCls();
final FacetHolder facetHolder = processClassContext.getFacetHolder();
+ final TranslationService translationService = servicesInjector.lookupService(TranslationService.class);
final ObjectLayoutMetadataService objectLayoutMetadataService = servicesInjector.lookupService(ObjectLayoutMetadataService.class);
FacetUtil.addFacet(
- ObjectLayoutMetadataFacetDefault.create(facetHolder, readMetadata(cls), objectLayoutMetadataService));
- }
-
- private ObjectLayoutMetadata readMetadata(final Class<?> domainClass) {
- final ObjectLayoutMetadataService objectLayoutMetadataService = servicesInjector.lookupService(ObjectLayoutMetadataService.class);
- return objectLayoutMetadataService.fromXml(domainClass);
+ ObjectLayoutMetadataFacetDefault.create(facetHolder,
+ translationService, objectLayoutMetadataService));
}
private ServicesInjector servicesInjector;
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
index 3080769..6431486 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
@@ -19,16 +19,10 @@ package org.apache.isis.core.metamodel.services.layout;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.Resources;
@@ -38,60 +32,17 @@ import org.slf4j.LoggerFactory;
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.v1_0.ActionHolder;
-import org.apache.isis.applib.layout.v1_0.ActionLayoutMetadata;
-import org.apache.isis.applib.layout.v1_0.CollectionLayoutMetadata;
-import org.apache.isis.applib.layout.v1_0.Column;
-import org.apache.isis.applib.layout.v1_0.ColumnHolder;
import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
-import org.apache.isis.applib.layout.v1_0.PropertyGroup;
-import org.apache.isis.applib.layout.v1_0.PropertyLayoutMetadata;
-import org.apache.isis.applib.layout.v1_0.Tab;
-import org.apache.isis.applib.layout.v1_0.TabGroup;
-import org.apache.isis.applib.services.i18n.TranslationService;
import org.apache.isis.applib.services.jaxb.JaxbService;
import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
-import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
-import org.apache.isis.core.metamodel.deployment.DeploymentCategoryAware;
-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.layoutmetadata.ObjectLayoutMetadataFacet;
-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.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;
-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 ObjectLayoutMetadataServiceDefault
- implements ObjectLayoutMetadataService, DeploymentCategoryAware , SpecificationLoaderAware {
+ implements ObjectLayoutMetadataService, SpecificationLoaderAware {
private static final Logger LOG = LoggerFactory.getLogger(ObjectLayoutMetadataServiceDefault.class);
@@ -139,316 +90,6 @@ public class ObjectLayoutMetadataServiceDefault
}
- @Override
- public ObjectLayoutMetadata normalize(final ObjectLayoutMetadata objectLayoutMetadata, final Class<?> domainClass) {
- // caching (of whether validated) is enabled only in production.
- return objectLayoutMetadata.isNormalized() && deploymentCategory.isProduction()
- ? objectLayoutMetadata
- : deriveAndOverwrite(objectLayoutMetadata, domainClass);
- }
-
- private ObjectLayoutMetadata deriveAndOverwrite(final ObjectLayoutMetadata objectLayoutMetadata, final Class<?> domainClass) {
- synchronized (objectLayoutMetadata) {
- final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
- doDeriveAndOverwrite(objectLayoutMetadata, objectSpec);
- objectLayoutMetadata.setNormalized(true);
- }
- return objectLayoutMetadata;
- }
-
- private void doDeriveAndOverwrite(final ObjectLayoutMetadata metadata, final ObjectSpecification objectSpec) {
-
- 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(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
- overwrite(metadata, oneToOneAssociationById, oneToManyAssociationById, objectActionById);
- }
-
- /**
- * Ensures that all object members (properties, collections and actions) are in the metadata.
- *
- * <p>
- * 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 ObjectLayoutMetadata metadata,
- final Map<String, OneToOneAssociation> oneToOneAssociationById,
- final Map<String, OneToManyAssociation> oneToManyAssociationById,
- final Map<String, ObjectAction> objectActionById) {
-
- final LinkedHashMap<String, PropertyLayoutMetadata> propertyIds = metadata.getAllPropertiesById();
- final LinkedHashMap<String, CollectionLayoutMetadata> collectionIds = metadata.getAllCollectionsById();
- final LinkedHashMap<String, ActionLayoutMetadata> actionIds = metadata.getAllActionsById();
-
- final AtomicReference<PropertyGroup> defaultPropertyGroupRef = new AtomicReference<>();
- final AtomicReference<Column> firstColumnRef = new AtomicReference<>();
- final AtomicReference<TabGroup> lastTabGroupRef = new AtomicReference<>();
-
- // capture the first column, and also
- // capture the first property group (if any) with the default name ('General')
- metadata.visit(new ObjectLayoutMetadata.VisitorAdapter() {
- @Override
- public void visit(final Column column) {
- firstColumnRef.compareAndSet(null, column);
- }
- @Override
- public void visit(final PropertyGroup propertyGroup) {
- if(MemberGroupLayoutFacet.DEFAULT_GROUP.equals(propertyGroup.getName())) {
- defaultPropertyGroupRef.compareAndSet(null, propertyGroup);
- }
- }
- @Override
- public void visit(final TabGroup tabGroup) {
- lastTabGroupRef.set(tabGroup);
- }
- });
-
- // any missing properties will be added to the (first) 'General' property group found
- // if there is no default ('General') property group
- // then one will be added to the first Column of the first Tab.
- final List<String>[] propertyIdTuple = surplusAndMissing(propertyIds.keySet(), oneToOneAssociationById.keySet());
- final List<String> surplusPropertyIds = propertyIdTuple[0];
- final List<String> missingPropertyIds = propertyIdTuple[1];
-
- for (String surplusPropertyId : surplusPropertyIds) {
- propertyIds.get(surplusPropertyId).setMetadataError("No such property");
- }
-
- if(!missingPropertyIds.isEmpty()) {
- // ensure that there is a property group to use
- boolean wasSet = defaultPropertyGroupRef.compareAndSet(null, new PropertyGroup(MemberGroupLayoutFacet.DEFAULT_GROUP));
- final PropertyGroup defaultPropertyGroup = defaultPropertyGroupRef.get();
- if(wasSet) {
- firstColumnRef.get().getPropertyGroups().add(defaultPropertyGroup);
- }
- for (final String propertyId : missingPropertyIds) {
- defaultPropertyGroup.getProperties().add(new PropertyLayoutMetadata(propertyId));
- }
- }
-
-
- // any missing collections will be added as tabs to the last TabGroup.
- // If there is only a single tab group then a new TabGroup will be added first
- final List<String>[] collectionIdTuple = surplusAndMissing(collectionIds.keySet(), oneToManyAssociationById.keySet());
- final List<String> surplusCollectionIds = collectionIdTuple[0];
- final List<String> missingCollectionIds = collectionIdTuple[1];
-
- for (String surplusCollectionId : surplusCollectionIds) {
- collectionIds.get(surplusCollectionId).setMetadataError("No such collection");
- }
-
- if(!missingCollectionIds.isEmpty()) {
- while(metadata.getTabGroups().size() < 2) {
- final TabGroup tabGroup = new TabGroup();
- metadata.getTabGroups().add(tabGroup);
- lastTabGroupRef.set(tabGroup);
- }
- final TabGroup lastTabGroup = lastTabGroupRef.get();
- for (final String collectionId : missingCollectionIds) {
- final Tab tab = new Tab();
- lastTabGroup.getTabs().add(tab);
- Column left = new Column(12);
- tab.setLeft(left);
- final CollectionLayoutMetadata layoutMetadata = new CollectionLayoutMetadata(collectionId);
- layoutMetadata.setDefaultView("table");
- left.getCollections().add(layoutMetadata);
- }
- }
-
- // any missing actions will be added as domain object actions (in the header)
- final List<String>[] actionIdTuple = surplusAndMissing(actionIds.keySet(), objectActionById.keySet());
- final List<String> surplusActionIds = actionIdTuple[0];
- final List<String> missingActionIds = actionIdTuple[1];
-
- for (String surplusActionId : surplusActionIds) {
- actionIds.get(surplusActionId).setMetadataError("No such action");
- }
-
- if(!missingActionIds.isEmpty()) {
- for (String actionId : missingActionIds) {
- List<ActionLayoutMetadata> actions = metadata.getActions();
- if(actions == null) {
- actions = Lists.newArrayList();
- metadata.setActions(actions);
- }
- actions.add(new ActionLayoutMetadata(actionId));
- }
- }
- }
-
- /**
- * Returns a 2-element array (a tuple) of [first-second, second-first]
- */
- static <T> List<T>[] surplusAndMissing(final java.util.Collection<T> first, final java.util.Collection<T> second){
- final List<T> firstNotSecond = Lists.newArrayList(first);
- firstNotSecond.removeAll(second);
- final List<T> secondNotFirst = Lists.newArrayList(second);
- secondNotFirst.removeAll(first);
- return new List[]{ firstNotSecond, secondNotFirst };
- }
-
- private void overwrite(
- final ObjectLayoutMetadata metadata,
- final Map<String, OneToOneAssociation> oneToOneAssociationById,
- final Map<String, OneToManyAssociation> oneToManyAssociationById,
- final Map<String, ObjectAction> objectActionById) {
-
- metadata.visit(new ObjectLayoutMetadata.VisitorAdapter() {
- private final Map<String, int[]> propertySequenceByGroup = Maps.newHashMap();
- 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 ActionLayoutMetadata actionLayoutMetadata) {
- final ActionHolder actionHolder = actionLayoutMetadata.getOwner();
- final ObjectAction objectAction = objectActionById.get(actionLayoutMetadata.getId());
- if(objectAction == null) {
- return;
- }
-
- final String memberOrderName;
- final int memberOrderSequence;
- if(actionHolder instanceof PropertyGroup) {
- final PropertyGroup propertyGroup = (PropertyGroup) actionHolder;
- final List<PropertyLayoutMetadata> properties = propertyGroup.getProperties();
- final PropertyLayoutMetadata propertyLayoutMetadata = properties.get(0); // any will do
- memberOrderName = propertyLayoutMetadata.getId();
- memberOrderSequence = actionPropertyGroupSequence++;
- } else if(actionHolder instanceof PropertyLayoutMetadata) {
- final PropertyLayoutMetadata propertyLayoutMetadata = (PropertyLayoutMetadata) actionHolder;
- memberOrderName = propertyLayoutMetadata.getId();
- memberOrderSequence = actionPropertySequence++;
- } else if(actionHolder instanceof CollectionLayoutMetadata) {
- final CollectionLayoutMetadata collectionLayoutMetadata = (CollectionLayoutMetadata) actionHolder;
- memberOrderName = collectionLayoutMetadata.getId();
- memberOrderSequence = actionCollectionSequence++;
- } else {
- // DomainObject
- memberOrderName = null;
- memberOrderSequence = actionDomainObjectSequence++;
- }
- FacetUtil.addFacet(
- new MemberOrderFacetXml(memberOrderName, ""+memberOrderSequence, translationService, objectAction));
-
-
- if(actionHolder instanceof PropertyGroup) {
- if(actionLayoutMetadata.getPosition() == null ||
- actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.BELOW ||
- actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.RIGHT) {
- actionLayoutMetadata.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.PANEL);
- }
- } else if(actionHolder instanceof PropertyLayoutMetadata) {
- if(actionLayoutMetadata.getPosition() == null ||
- actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL_DROPDOWN ||
- actionLayoutMetadata.getPosition() == org.apache.isis.applib.annotation.ActionLayout.Position.PANEL) {
- actionLayoutMetadata.setPosition(org.apache.isis.applib.annotation.ActionLayout.Position.BELOW);
- }
- } else {
- // doesn't do anything for DomainObject or Collection
- actionLayoutMetadata.setPosition(null);
- }
-
- FacetUtil.addFacet(ActionPositionFacetForActionXml.create(actionLayoutMetadata, objectAction));
- FacetUtil.addFacet(BookmarkPolicyFacetForActionXml.create(actionLayoutMetadata, objectAction));
- FacetUtil.addFacet(CssClassFacetForActionXml.create(actionLayoutMetadata, objectAction));
- FacetUtil.addFacet(CssClassFaFacetForActionXml.create(actionLayoutMetadata, objectAction));
- FacetUtil.addFacet(DescribedAsFacetForActionXml.create(actionLayoutMetadata, objectAction));
- FacetUtil.addFacet(HiddenFacetForActionLayoutXml.create(actionLayoutMetadata, objectAction));
- FacetUtil.addFacet(NamedFacetForActionXml.create(actionLayoutMetadata, objectAction));
- }
-
- @Override
- public void visit(final PropertyLayoutMetadata propertyLayoutMetadata) {
- final OneToOneAssociation oneToOneAssociation = oneToOneAssociationById.get(propertyLayoutMetadata.getId());
- if(oneToOneAssociation == null) {
- return;
- }
-
- FacetUtil.addFacet(CssClassFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(DescribedAsFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(HiddenFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(LabelAtFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(MultiLineFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(NamedFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(RenderedAdjustedFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
- FacetUtil.addFacet(TypicalLengthFacetForPropertyXml.create(propertyLayoutMetadata, oneToOneAssociation));
-
- // @MemberOrder#name based on owning property group, @MemberOrder#sequence monotonically increasing
- final PropertyGroup propertyGroup = propertyLayoutMetadata.getOwner();
- final String groupName = propertyGroup.getName();
- final String sequence = nextInSequenceFor(groupName, propertySequenceByGroup);
- FacetUtil.addFacet(
- new MemberOrderFacetXml(groupName, sequence, translationService, oneToOneAssociation));
- }
-
- @Override
- public void visit(final CollectionLayoutMetadata collectionLayoutMetadata) {
- final OneToManyAssociation oneToManyAssociation = oneToManyAssociationById.get(collectionLayoutMetadata.getId());
- if(oneToManyAssociation == null) {
- return;
- }
-
- FacetUtil.addFacet(CssClassFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
- FacetUtil.addFacet(DefaultViewFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
- FacetUtil.addFacet(DescribedAsFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
- FacetUtil.addFacet(HiddenFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
- FacetUtil.addFacet(NamedFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
- FacetUtil.addFacet(PagedFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
- FacetUtil.addFacet(SortedByFacetForCollectionXml.create(collectionLayoutMetadata, oneToManyAssociation));
-
- // @MemberOrder#name based on the collection's id (so that each has a single "member group")
- final String groupName = collectionLayoutMetadata.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 Column column = collectionLayoutMetadata.getOwner();
- final ColumnHolder holder = column.getOwner();
- if(holder instanceof Tab) {
- final Tab tab = (Tab) holder;
- if(tab.getContents().size() == 1) {
- final String collectionName = oneToManyAssociation.getName();
- tab.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;
- }
-
@Override
public ObjectLayoutMetadata toMetadata(final Object domainObject) {
@@ -462,16 +103,22 @@ public class ObjectLayoutMetadataServiceDefault
return facet != null? facet.getMetadata(): null;
}
+ ////////////////////////////////////////////////////////
+ private boolean dynamicReloading;
- //region > injected dependencies
- private DeploymentCategory deploymentCategory;
+ @Override
+ public void toggleDynamicReloading() {
+ this.dynamicReloading = !this.dynamicReloading;
+ }
@Override
- public void setDeploymentCategory(final DeploymentCategory deploymentCategory) {
- this.deploymentCategory = deploymentCategory;
+ public boolean isDynamicReloading() {
+ return this.dynamicReloading;
}
+ //region > injected dependencies
+
private SpecificationLoader specificationLookup;
@Override
@@ -479,12 +126,9 @@ public class ObjectLayoutMetadataServiceDefault
this.specificationLookup = specificationLookup;
}
-
@Inject
JaxbService jaxbService;
- @Inject
- TranslationService translationService;
//endregion
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
index fadfae2..900ecc3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
@@ -132,6 +132,50 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
// //////////////////////////////////////
+ public static class SwitchOnDynamicReloadingOfLayoutsDomainEvent extends ActionDomainEvent {
+ }
+
+ @Action(
+ domainEvent = SwitchOnDynamicReloadingOfLayoutsDomainEvent.class,
+ semantics = SemanticsOf.SAFE,
+ restrictTo = RestrictTo.PROTOTYPING
+ )
+ @ActionLayout(
+ cssClassFa = "fa-check"
+ )
+ @MemberOrder(sequence="500.400.2")
+ public void switchOnDynamicReloadingOfLayouts() {
+ objectLayoutMetadataService.toggleDynamicReloading();
+ }
+ public boolean hideSwitchOnDynamicReloadingOfLayouts() {
+ return objectLayoutMetadataService.isDynamicReloading();
+ }
+
+ // //////////////////////////////////////
+
+ public static class SwitchOffDynamicReloadingOfLayoutsDomainEvent extends ActionDomainEvent {
+ }
+
+ @Action(
+ domainEvent = SwitchOffDynamicReloadingOfLayoutsDomainEvent.class,
+ semantics = SemanticsOf.SAFE,
+ restrictTo = RestrictTo.PROTOTYPING
+ )
+ @ActionLayout(
+ cssClassFa = "fa-times"
+ )
+ @MemberOrder(sequence="500.400.3")
+ public void switchOffDynamicReloadingOfLayouts() {
+ objectLayoutMetadataService.toggleDynamicReloading();
+ }
+ public boolean hideSwitchOffDynamicReloadingOfLayouts() {
+ return !objectLayoutMetadataService.isDynamicReloading();
+ }
+
+
+
+ // //////////////////////////////////////
+
@Inject
ObjectLayoutMetadataService objectLayoutMetadataService;
@@ -146,5 +190,4 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
this.specificationLoader = specificationLoader;
}
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
index e4abde8..5f4c0d1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
@@ -33,6 +33,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.core.commons.components.ApplicationScopedComponent;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.debug.DebugBuilder;
@@ -256,7 +258,12 @@ public final class ObjectReflectorDefault
private void loadSpecificationsForServices() {
for (final Class<?> serviceClass : getServiceClasses()) {
- internalLoadSpecification(serviceClass);
+ final DomainService domainService = serviceClass.getAnnotation(DomainService.class);
+ if(domainService != null) {
+ if(domainService.nature() == NatureOfService.VIEW || domainService.nature() == NatureOfService.VIEW_CONTRIBUTIONS_ONLY) {
+ internalLoadSpecification(serviceClass);
+ }
+ }
}
}
@@ -515,6 +522,7 @@ public final class ObjectReflectorDefault
facetDecoratorSet.decorate(specSpi);
specSpi.updateFromFacetValues();
specSpi.setIntrospectionState(IntrospectionState.INTROSPECTED);
+
}
@Override
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index 9628a34..a6e71df 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@ -49,6 +49,7 @@ import org.apache.isis.core.metamodel.facets.FacetedMethod;
import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
import org.apache.isis.core.metamodel.facets.object.facets.FacetsFacet;
+import org.apache.isis.core.metamodel.facets.object.layoutmetadata.ObjectLayoutMetadataFacet;
import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader.ReaderException;
import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader2;
@@ -189,13 +190,14 @@ public class FacetedMethodsBuilder {
public Properties introspectClass() {
- if (LOG.isDebugEnabled()) {
- LOG.debug("introspecting " + getClassName() + ": class-level details");
+ if (LOG.isInfoEnabled()) {
+ LOG.info("introspecting " + getClassName() + ": class-level details");
}
// process facets at object level
// this will also remove some methods, such as the superclass methods.
+ final ObjectLayoutMetadataFacet facet = spec.getFacet(ObjectLayoutMetadataFacet.class);
final Properties metadataProperties = readMetadataProperties(introspectedClass);
getFacetProcessor().process(introspectedClass, metadataProperties, methodRemover, spec);
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
index 5aa6444..070a88d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
@@ -22,6 +22,9 @@ import java.util.List;
import com.google.common.collect.Lists;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.Bulk;
import org.apache.isis.applib.annotation.InvokedOn;
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index 071f760..afd556e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -176,6 +176,8 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
sortCacheAndUpdateActions(actions);
}
+
+
if(isNotIntrospected()) {
facetedMethodsBuilder.introspectClassPostProcessing(metadataProperties);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/metamodel/src/test/java/org/apache/isis/core/metamodel/layoutxml/v1_0/ObjectLayoutMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/layoutxml/v1_0/ObjectLayoutMetadataTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/layoutxml/v1_0/ObjectLayoutMetadataTest.java
index 73df1fb..c5e8c1b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/layoutxml/v1_0/ObjectLayoutMetadataTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/layoutxml/v1_0/ObjectLayoutMetadataTest.java
@@ -77,8 +77,9 @@ public class ObjectLayoutMetadataTest {
left.getCollections().add(similarToColl);
similarToColl.setId("similarTo");
- PropertyLayoutMetadata namePropertyLayoutMetadata = leftPropGroup.getProperties().get(0);
- namePropertyLayoutMetadata.setId("name");
+ left.getPropertyGroups().add(new PropertyGroup("General"));
+ PropertyLayoutMetadata namePropertyLayoutMetadata = new PropertyLayoutMetadata("name");
+ left.getPropertyGroups().get(0).getProperties().add(namePropertyLayoutMetadata);
ActionLayoutMetadata updateNameActionLayoutMetadata = new ActionLayoutMetadata();
updateNameActionLayoutMetadata.setId("updateName");
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index bebb67c..559e110 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -126,11 +126,14 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
VIEW, EDIT;
}
+ private final Map<PropertyMemento, ScalarModel> propertyScalarModels;
private ObjectAdapterMemento adapterMemento;
+ private ObjectAdapterMemento contextAdapterIfAny;
+
private Mode mode = Mode.VIEW;
private RenderingHint renderingHint = RenderingHint.REGULAR;
- private final Map<PropertyMemento, ScalarModel> propertyScalarModels = Maps.newHashMap();
private Hint hint;
+ private final PendingModel pendingModel;
/**
* Toggled by 'entityDetailsButton'.
@@ -149,7 +152,7 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
// //////////////////////////////////////////////////////////
public EntityModel() {
- pendingModel = new PendingModel(this);
+ this((ObjectAdapterMemento)null);
}
public EntityModel(final PageParameters pageParameters) {
@@ -162,8 +165,13 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
}
public EntityModel(final ObjectAdapterMemento adapterMemento) {
+ this(adapterMemento, Maps.<PropertyMemento, ScalarModel>newHashMap());
+ }
+
+ public EntityModel(final ObjectAdapterMemento adapterMemento, final Map<PropertyMemento, ScalarModel> propertyScalarModels) {
this.adapterMemento = adapterMemento;
this.pendingModel = new PendingModel(this);
+ this.propertyScalarModels = propertyScalarModels;
}
public static String oidStr(final PageParameters pageParameters) {
@@ -608,8 +616,6 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
}
}
- private final PendingModel pendingModel;
- private ObjectAdapterMemento contextAdapterIfAny;
public ObjectAdapter getPendingElseCurrentAdapter() {
return pendingModel.getPendingElseCurrentAdapter();
@@ -642,19 +648,27 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
return tabMetadata;
}
- public EntityModel withTabMetadata(final Tab tabMetadata) {
- this.tabMetadata = tabMetadata;
- return this;
+ /**
+ * Returns a new copy that SHARES the property scalar models (for edit form).
+ */
+ public EntityModel cloneWithTabMetadata(final Tab tabMetadata) {
+ final EntityModel entityModel = new EntityModel(this.adapterMemento, this.propertyScalarModels);
+ entityModel.tabMetadata = tabMetadata;
+ return entityModel;
}
private Column columnMetadata;
private Column.Hint columnHint;
- public EntityModel withColumnMetadata(final Column columnMetadata, final Column.Hint columnHint) {
- this.columnMetadata = columnMetadata;
- this.columnHint = columnHint;
- return this;
+ /**
+ * Returns a new copy that SHARES the property scalar models (for edit form).
+ */
+ public EntityModel cloneWithColumnMetadata(final Column columnMetadata, final Column.Hint columnHint) {
+ final EntityModel entityModel = new EntityModel(this.adapterMemento, this.propertyScalarModels);
+ entityModel.columnMetadata = columnMetadata;
+ entityModel.columnHint = columnHint;
+ return entityModel;
}
public Column getColumnMetadata() {
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
index 32c0900..004ba23 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
@@ -22,8 +22,6 @@ package org.apache.isis.viewer.wicket.ui.components.entity.combined;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
-import org.apache.isis.core.metamodel.facets.object.layoutmetadata.ObjectLayoutMetadataFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.viewer.wicket.model.models.EntityModel;
import org.apache.isis.viewer.wicket.ui.ComponentFactory;
import org.apache.isis.viewer.wicket.ui.ComponentType;
@@ -44,14 +42,11 @@ public class EntityCombinedPanelFactory extends EntityComponentFactoryAbstract {
@Override
protected ApplicationAdvice doAppliesTo(final EntityModel entityModel) {
- final ObjectSpecification specification = entityModel.getTypeOfSpecification();
- // opposite to the EntityTabbedPanelFactory
- return appliesIf(!specification.containsDoOpFacet(ObjectLayoutMetadataFacet.class));
+ return appliesIf(false); // TODO: remove
}
@Override
public Component createComponent(final String id, final IModel<?> model) {
- final EntityModel entityModel = (EntityModel) model;
- return new EntityCombinedPanel(id, entityModel);
+ throw new IllegalStateException("shouldn't be called"); // TODO: remove
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityColumnMembers.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityColumnMembers.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityColumnMembers.java
index 3e0cd3f..a294969 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityColumnMembers.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityColumnMembers.java
@@ -73,14 +73,13 @@ public class EntityColumnMembers extends PanelAbstract<EntityModel> {
final Component owningPanel) {
super(id, entityModel);
- this.owningPanel = owningPanel; // for repainting
+ this.owningPanel = owningPanel; // for repainting, perhaps
buildGui();
}
private void buildGui() {
- final EntityModel entityModel = (EntityModel) getModel();
- addPropertiesAndCollections(this, entityModel);
+ addPropertiesAndCollections(this, getModel());
}
private void addPropertiesAndCollections(
http://git-wip-us.apache.org/repos/asf/isis/blob/47f4aea4/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
index 24837b6..31c54a1 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/properties/EntityPropertiesForm.java
@@ -238,9 +238,7 @@ public class EntityPropertiesForm extends FormAbstract<ObjectAdapter> implements
final Hint hint) {
final Column columnMetaDataIfAny = hint.from(tabMetaDataIfAny);
- final EntityModel entityModelWithHints =
- new EntityModel(entityModel.getPageParameters())
- .withColumnMetadata(columnMetaDataIfAny, hint);
+ final EntityModel entityModelWithHints = entityModel.cloneWithColumnMetadata(columnMetaDataIfAny, hint);
final EntityColumnMembers columnMembers =
new EntityColumnMembers("entityMembers", entityModelWithHints, markupContainer);