ISIS-993: simplifying and finetuning. - layout.json disabled completely if a layout.xml is discovered - got rid of the enable/disable dynamic reloading, went back to checking deployment category for isProduction mode or not - ObjectLayoutMetadataService caches bad XML and also maintains xml -> metadata map (non-prod mode only) - blacklisting only applies if in non-prod mode - combined getMetadata() and reloadMetadata() - ensure that members are sorted correctly when in property groups (within their col / tab) - set up service specifications as being markAsService eagerly, rather than later on. - removing EntityCombinedPanelFactory, now use EntityTabGroupsPanelFactory for both cases.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/9a39de94 Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/9a39de94 Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/9a39de94 Branch: refs/heads/ISIS-993 Commit: 9a39de942da744830a4d8f2b0815aefbdf9bde15 Parents: 4529127 Author: Dan Haywood <d...@haywood-associates.co.uk> Authored: Wed Jan 13 01:50:17 2016 +0000 Committer: Dan Haywood <d...@haywood-associates.co.uk> Committed: Mon Jan 25 15:06:07 2016 +0000 ---------------------------------------------------------------------- .../layout/v1_0/ObjectLayoutMetadata.java | 13 ++++ .../layout/ObjectLayoutMetadataService.java | 13 ++-- .../isis/core/commons/lang/ClassExtensions.java | 5 ++ .../ObjectLayoutMetadataFacet.java | 7 -- .../ObjectLayoutMetadataFacetDefault.java | 52 +++++++------- .../ObjectLayoutMetadataFacetFactory.java | 2 +- .../layoutmetadata/LayoutMetadataReader2.java | 2 +- .../json/LayoutMetadataReaderFromJson.java | 30 +++++++- .../ObjectLayoutMetadataServiceDefault.java | 76 +++++++++++++++----- .../services/metamodel/MetadataMenu.java | 43 ----------- .../spec/feature/ObjectAssociation.java | 5 ++ .../specloader/ObjectReflectorDefault.java | 18 ++++- .../specimpl/FacetedMethodsBuilder.java | 5 +- .../dflt/ObjectSpecificationDefault.java | 11 --- .../ComponentFactoryRegistrarDefault.java | 2 - .../combined/EntityCombinedPanelFactory.java | 52 -------------- .../entity/tabgroups/EntityTabGroupsPanel.java | 14 ---- .../tabgroups/EntityTabGroupsPanelFactory.java | 10 +-- .../wicket/ui/pages/entity/EntityPage.java | 20 +++--- 19 files changed, 176 insertions(+), 204 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 4af327c..727bba2 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 @@ -251,4 +251,17 @@ public class ObjectLayoutMetadata implements Dto, ActionHolder, Serializable { } + 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/9a39de94/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 e29ff47..1de0147 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 @@ -22,7 +22,13 @@ import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata; public interface ObjectLayoutMetadataService { /** - * Returns raw (unnormalized) metadata, per the <code>.layout.xml</code> file. + * Whether any metadata exists for this domain class, and if so then whether it is valid or invalid. + */ + @Programmatic + boolean exists(Class<?> domainClass); + + /** + * Returns raw (unnormalized) metadata, eg per the <code>.layout.xml</code> file. */ @Programmatic ObjectLayoutMetadata fromXml(Class<?> domainClass); @@ -39,10 +45,5 @@ public interface ObjectLayoutMetadataService { @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/9a39de94/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java index 5f6983d..01ce5ca 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java @@ -174,6 +174,11 @@ public final class ClassExtensions { return Resources.toString(url, Charset.defaultCharset()); } + public static boolean exists(final Class<?> cls, final String resourceName) { + final URL url = Resources.getResource(cls, resourceName); + return url != null; + } + public static Class<?> asWrapped(final Class<?> primitiveClassExtendee) { return ClassUtil.wrapperClasses.get(primitiveClassExtendee); } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 2a63428..eb7efcd 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 @@ -27,14 +27,7 @@ import org.apache.isis.core.metamodel.facetapi.Facet; */ public interface ObjectLayoutMetadataFacet extends Facet { - /** - * 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/9a39de94/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 9538e72..fdc12ef 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 @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -42,6 +43,7 @@ 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.deployment.DeploymentCategory; import org.apache.isis.core.metamodel.facetapi.Facet; import org.apache.isis.core.metamodel.facetapi.FacetAbstract; import org.apache.isis.core.metamodel.facetapi.FacetHolder; @@ -93,59 +95,57 @@ public class ObjectLayoutMetadataFacetDefault public static ObjectLayoutMetadataFacet create( final FacetHolder facetHolder, final TranslationService translationService, - final ObjectLayoutMetadataService objectLayoutMetadataService) { - return new ObjectLayoutMetadataFacetDefault(facetHolder, translationService, objectLayoutMetadataService); + final ObjectLayoutMetadataService objectLayoutMetadataService, + final DeploymentCategory deploymentCategory) { + return new ObjectLayoutMetadataFacetDefault(facetHolder, translationService, objectLayoutMetadataService, deploymentCategory); } private final TranslationService translationService; + private final DeploymentCategory deploymentCategory; private final ObjectLayoutMetadataService objectLayoutMetadataService; - private boolean blacklisted; private ObjectLayoutMetadata metadata; + private boolean blacklisted; private ObjectLayoutMetadataFacetDefault( final FacetHolder facetHolder, final TranslationService translationService, - final ObjectLayoutMetadataService objectLayoutMetadataService) { + final ObjectLayoutMetadataService objectLayoutMetadataService, + final DeploymentCategory deploymentCategory) { super(ObjectLayoutMetadataFacetDefault.type(), facetHolder, Derivation.NOT_DERIVED); this.objectLayoutMetadataService = objectLayoutMetadataService; this.translationService = translationService; + this.deploymentCategory = deploymentCategory; } - @Override - public boolean isNoop() { - getMetadata(); - return blacklisted; - } - + /** + * Blacklisting only occurs if running in production mode. + */ @Override public ObjectLayoutMetadata getMetadata() { - if(blacklisted) { - return null; - } - reloadMetadata(); - return this.metadata; - } - - @Override - public void reloadMetadata() { - if (metadata != null && !objectLayoutMetadataService.isDynamicReloading()) { - return; + if (deploymentCategory.isProduction() || blacklisted) { + return metadata; } final Class<?> domainClass = getSpecification().getCorrespondingClass(); final ObjectLayoutMetadata metadata = objectLayoutMetadataService.fromXml(domainClass); + if(deploymentCategory.isProduction() && metadata == null) { + blacklisted = true; + } this.metadata = normalize(metadata); - blacklisted = this.metadata == null; + return this.metadata; } private ObjectLayoutMetadata normalize(final ObjectLayoutMetadata metadata) { if(metadata == null) { return null; } - if(LOG.isInfoEnabled()) { - LOG.info("Normalizing layout metadata for " + getSpecification().getCorrespondingClass().getName()); - } + // if have .layout.json and then add a .layout.xml without restarting, then the normalizing is required + // in order to trample over the .layout.json's original facets. + // if(metadata.isNormalized()) { + // return metadata; + // } doNormalize(metadata, getSpecification()); + metadata.setNormalized(true); return metadata; } @@ -424,7 +424,7 @@ public class ObjectLayoutMetadataFacetDefault final ColumnHolder holder = column.getOwner(); if(holder instanceof Tab) { final Tab tab = (Tab) holder; - if(tab.getContents().size() == 1) { + if(tab.getContents().size() == 1 && Strings.isNullOrEmpty(tab.getName()) ) { final String collectionName = oneToManyAssociation.getName(); tab.setName(collectionName); } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 479849c..28c69e6 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 @@ -44,7 +44,7 @@ public class ObjectLayoutMetadataFacetFactory extends FacetFactoryAbstract imple final ObjectLayoutMetadataService objectLayoutMetadataService = servicesInjector.lookupService(ObjectLayoutMetadataService.class); FacetUtil.addFacet( ObjectLayoutMetadataFacetDefault.create(facetHolder, - translationService, objectLayoutMetadataService)); + translationService, objectLayoutMetadataService, getDeploymentCategory())); } private ServicesInjector servicesInjector; http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java index 533d13a..0df1fea 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java @@ -18,7 +18,7 @@ package org.apache.isis.core.metamodel.layoutmetadata; public interface LayoutMetadataReader2 extends LayoutMetadataReader { - public static class Support { + class Support { public static Support entitiesOnly() { return new Support(false,false,false,false,false,false,false); http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java index 0a29c6f..5c5c039 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java @@ -43,6 +43,7 @@ import org.apache.isis.applib.annotation.Render.Type; import org.apache.isis.applib.annotation.When; import org.apache.isis.applib.annotation.Where; import org.apache.isis.applib.filter.Filter; +import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService; import org.apache.isis.core.commons.lang.ClassExtensions; import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet; import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet; @@ -78,6 +79,8 @@ import org.apache.isis.core.metamodel.layoutmetadata.PagedFacetRepr; import org.apache.isis.core.metamodel.layoutmetadata.PropertyLayoutFacetRepr; import org.apache.isis.core.metamodel.layoutmetadata.RenderFacetRepr; import org.apache.isis.core.metamodel.layoutmetadata.TypicalLengthFacetRepr; +import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector; +import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware; import org.apache.isis.core.metamodel.spec.ActionType; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.spec.ObjectSpecifications; @@ -86,7 +89,7 @@ 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; -public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2 { +public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2, ServicesInjectorAware { private static final Logger LOG = LoggerFactory.getLogger(LayoutMetadataReaderFromJson.class); @@ -411,6 +414,17 @@ public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2 { return null; } + try { + final ObjectLayoutMetadataService objectLayoutMetadataService = getObjectLayoutMetadataService(); + if(objectLayoutMetadataService.exists(domainClass)) { + blacklisted.add(domainClass); + return null; + } + } catch (IllegalArgumentException ex) { + // ignore + } + + final String resourceName = domainClass.getSimpleName() + ".layout.json"; try { content = ClassExtensions.resourceContentOf(domainClass, resourceName); @@ -683,4 +697,18 @@ public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2 { return getClass().getName(); } + + + private ObjectLayoutMetadataService getObjectLayoutMetadataService() { + return servicesInjector.lookupService(ObjectLayoutMetadataService.class); + } + + + private ServicesInjector servicesInjector; + + @Override + public void setServicesInjector(final ServicesInjector servicesInjector) { + this.servicesInjector = servicesInjector; + } + } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 35010c2..f2861b8 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,11 +19,12 @@ package org.apache.isis.core.metamodel.services.layout; import java.io.IOException; import java.net.URL; import java.nio.charset.Charset; -import java.util.Set; +import java.util.Map; +import java.util.Objects; import javax.inject.Inject; -import com.google.common.collect.Sets; +import com.google.common.collect.Maps; import com.google.common.io.Resources; import org.slf4j.Logger; @@ -35,6 +36,8 @@ import org.apache.isis.applib.annotation.Programmatic; import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata; 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.facets.object.layoutmetadata.ObjectLayoutMetadataFacet; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.spec.SpecificationLoader; @@ -42,15 +45,29 @@ import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware; @DomainService(nature = NatureOfService.DOMAIN) public class ObjectLayoutMetadataServiceDefault - implements ObjectLayoutMetadataService, SpecificationLoaderAware { + implements ObjectLayoutMetadataService, SpecificationLoaderAware, DeploymentCategoryAware { private static final Logger LOG = LoggerFactory.getLogger(ObjectLayoutMetadataServiceDefault.class); + // for better logging messages (used only in prototyping mode) + private final Map<Class<?>, String> badXmlByClass = Maps.newHashMap(); + + // cache (used only in prototyping mode) + private final Map<String, ObjectLayoutMetadata> metadataByXml = Maps.newHashMap(); + + @Override + @Programmatic + public boolean exists(final Class<?> domainClass) { + final URL resource = Resources.getResource(domainClass, resourceNameFor(domainClass)); + return resource != null; + } + + @Override @Programmatic public ObjectLayoutMetadata fromXml(Class<?> domainClass) { + final String resourceName = resourceNameFor(domainClass); final String xml; - final String resourceName = domainClass.getSimpleName() + ".layout.xml"; try { xml = resourceContentOf(domainClass, resourceName); } catch (IOException | IllegalArgumentException ex) { @@ -63,11 +80,39 @@ public class ObjectLayoutMetadataServiceDefault return null; } + + if(!deploymentCategory.isProduction()) { + final ObjectLayoutMetadata objectLayoutMetadata = metadataByXml.get(xml); + if(objectLayoutMetadata != null) { + return objectLayoutMetadata; + } + + final String badXml = badXmlByClass.get(domainClass); + if(badXml != null) { + if(Objects.equals(xml, badXml)) { + // seen this before and already logged; just quit + return null; + } else { + // this different XML might be good + badXmlByClass.remove(domainClass); + } + } + + } + try { final ObjectLayoutMetadata metadata = jaxbService.fromXml(ObjectLayoutMetadata.class, xml); + if(!deploymentCategory.isProduction()) { + metadataByXml.put(xml, metadata); + } return metadata; } catch(Exception ex) { + if(!deploymentCategory.isProduction()) { + // save fact that this was bad XML, so that we don't log again if called next time + badXmlByClass.put(domainClass, xml); + } + // note that we don't blacklist if the file exists but couldn't be parsed; // the developer might fix so we will want to retry. final String message = "Failed to parse " + resourceName + " file (" + ex.getMessage() + ")"; @@ -82,9 +127,13 @@ public class ObjectLayoutMetadataServiceDefault return Resources.toString(url, Charset.defaultCharset()); } + private String resourceNameFor(final Class<?> domainClass) { + return domainClass.getSimpleName() + ".layout.xml"; + } @Override + @Programmatic public ObjectLayoutMetadata toMetadata(final Object domainObject) { return toMetadata(domainObject.getClass()); } @@ -98,17 +147,6 @@ public class ObjectLayoutMetadataServiceDefault //////////////////////////////////////////////////////// - private boolean dynamicReloading; - - @Override - public void toggleDynamicReloading() { - this.dynamicReloading = !this.dynamicReloading; - } - - @Override - public boolean isDynamicReloading() { - return this.dynamicReloading; - } //region > injected dependencies @@ -119,10 +157,16 @@ public class ObjectLayoutMetadataServiceDefault this.specificationLookup = specificationLookup; } + private DeploymentCategory deploymentCategory; + + @Override + public void setDeploymentCategory(final DeploymentCategory deploymentCategory) { + this.deploymentCategory = deploymentCategory; + } + @Inject JaxbService jaxbService; - //endregion } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 900ecc3..cc05eca 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 @@ -130,49 +130,6 @@ 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(); - } - - // ////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java index 8837916..9c87476 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java @@ -19,6 +19,7 @@ package org.apache.isis.core.metamodel.spec.feature; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -38,6 +39,7 @@ import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet; import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet; import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet; import org.apache.isis.core.metamodel.facets.object.value.ValueFacet; +import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderComparator; import org.apache.isis.core.metamodel.specloader.specimpl.ContributeeMember; /** @@ -405,6 +407,9 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder { for(ObjectAssociation association: associations) { addAssociationIntoGroup(associationsByGroup, association); } + for (Map.Entry<String, List<ObjectAssociation>> objectAssociations : associationsByGroup.entrySet()) { + Collections.sort(objectAssociations.getValue(), new MemberOrderComparator(true)); + } return associationsByGroup; } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 5f4c0d1..2957dd7 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 @@ -245,6 +245,9 @@ public final class ObjectReflectorDefault // wire subcomponents into each other this.runtimeContext.injectInto(facetProcessor); + for (final LayoutMetadataReader layoutMetadataReader : layoutMetadataReaders) { + this.runtimeContext.injectInto(layoutMetadataReader); + } // initialize subcomponents facetDecoratorSet.init(); @@ -261,12 +264,13 @@ public final class ObjectReflectorDefault final DomainService domainService = serviceClass.getAnnotation(DomainService.class); if(domainService != null) { if(domainService.nature() == NatureOfService.VIEW || domainService.nature() == NatureOfService.VIEW_CONTRIBUTIONS_ONLY) { - internalLoadSpecification(serviceClass); + internalLoadSpecification(serviceClass, domainService.nature()); } } } } + private void loadSpecificationsForMixins() { final Set<Class<?>> mixinTypes = AppManifest.Registry.instance().getMixinTypes(); if(mixinTypes == null) { @@ -390,11 +394,16 @@ public final class ObjectReflectorDefault } private ObjectSpecification internalLoadSpecification(final Class<?> type) { + return internalLoadSpecification(type, null); + } + + private ObjectSpecification internalLoadSpecification(final Class<?> type, final NatureOfService nature) { final Class<?> substitutedType = classSubstitutor.getClass(type); - return substitutedType != null ? loadSpecificationForSubstitutedClass(substitutedType) : null; + return substitutedType != null ? loadSpecificationForSubstitutedClass(substitutedType, nature) : null; } - private ObjectSpecification loadSpecificationForSubstitutedClass(final Class<?> type) { + + private ObjectSpecification loadSpecificationForSubstitutedClass(final Class<?> type, final NatureOfService nature) { Assert.assertNotNull(type); final String typeName = type.getName(); @@ -405,6 +414,9 @@ public final class ObjectReflectorDefault return spec; } final ObjectSpecification specification = createSpecification(type); + if(nature != null) { + specification.markAsService(); + } if (specification == null) { throw new IsisException("Failed to create specification for class " + typeName); } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 a6e71df..b5a1605 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 @@ -40,7 +40,6 @@ import org.apache.isis.core.commons.lang.ListExtensions; import org.apache.isis.core.commons.lang.MethodUtil; import org.apache.isis.core.commons.util.ToString; import org.apache.isis.core.metamodel.exceptions.MetaModelException; -import org.apache.isis.core.metamodel.facetapi.FacetHolder; import org.apache.isis.core.metamodel.facetapi.FeatureType; import org.apache.isis.core.metamodel.facetapi.MethodRemover; import org.apache.isis.core.metamodel.facets.FacetFactory; @@ -49,7 +48,6 @@ 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; @@ -116,7 +114,7 @@ public class FacetedMethodsBuilder { } } - private final FacetHolder spec; + private final ObjectSpecificationAbstract spec; private final Class<?> introspectedClass; private final List<Method> methods; @@ -197,7 +195,6 @@ public class FacetedMethodsBuilder { // 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/9a39de94/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 afd556e..65448e9 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 @@ -264,19 +264,8 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl return isService; } - /** - * TODO: should ensure that service has at least one user action; fix when - * specification knows of its hidden methods. - * - * <pre> - * if (objectActions != null && objectActions.length == 0) { - * throw new ObjectSpecificationException("Service object " + getFullName() + " should have at least one user action"); - * } - * </pre> - */ @Override public void markAsService() { - ensureServiceHasNoAssociations(); isService = true; } http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java index befd252..3cf6308 100644 --- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java +++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java @@ -40,7 +40,6 @@ import org.apache.isis.viewer.wicket.ui.components.collectioncontents.summary.Co import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory; import org.apache.isis.viewer.wicket.ui.components.empty.EmptyCollectionPanelFactory; import org.apache.isis.viewer.wicket.ui.components.entity.collections.EntityCollectionsPanelFactory; -import org.apache.isis.viewer.wicket.ui.components.entity.combined.EntityCombinedPanelFactory; import org.apache.isis.viewer.wicket.ui.components.entity.header.EntityHeaderPanelFactory; import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconAndTitlePanelFactory; import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconTitleAndCopyLinkPanelFactory; @@ -168,7 +167,6 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr // top-level componentFactories.add(new EntityTabGroupsPanelFactory()); - componentFactories.add(new EntityCombinedPanelFactory()); // lower-level componentFactories.add(new EntityIconAndTitlePanelFactory()); http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/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 deleted file mode 100644 index 004ba23..0000000 --- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.viewer.wicket.ui.components.entity.combined; - -import org.apache.wicket.Component; -import org.apache.wicket.model.IModel; - -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; -import org.apache.isis.viewer.wicket.ui.components.entity.EntityComponentFactoryAbstract; - -/** - * {@link ComponentFactory} for {@link EntityCombinedPanel}. - */ -public class EntityCombinedPanelFactory extends EntityComponentFactoryAbstract { - - private static final long serialVersionUID = 1L; - - private static final String NAME = "combined"; - - public EntityCombinedPanelFactory() { - super(ComponentType.ENTITY, NAME, EntityCombinedPanel.class); - } - - @Override - protected ApplicationAdvice doAppliesTo(final EntityModel entityModel) { - return appliesIf(false); // TODO: remove - } - - @Override - public Component createComponent(final String id, final IModel<?> model) { - throw new IllegalStateException("shouldn't be called"); // TODO: remove - } -} http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java index 0889e1a..6b274a5 100644 --- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java +++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java @@ -21,10 +21,7 @@ package org.apache.isis.viewer.wicket.ui.components.entity.tabgroups; import java.util.List; -import javax.xml.bind.Marshaller; - import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; @@ -37,8 +34,6 @@ import org.apache.wicket.model.Model; import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata; import org.apache.isis.applib.layout.v1_0.Tab; import org.apache.isis.applib.layout.v1_0.TabGroup; -import org.apache.isis.applib.services.jaxb.JaxbService; -import org.apache.isis.applib.services.layout.Object_downloadLayoutXml; import org.apache.isis.core.metamodel.adapter.ObjectAdapter; import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet; import org.apache.isis.core.metamodel.facets.object.layoutmetadata.ObjectLayoutMetadataFacet; @@ -80,15 +75,6 @@ public class EntityTabGroupsPanel extends PanelAbstract<EntityModel> { final ObjectLayoutMetadata objectLayoutMetadata = objectLayoutMetadataFacet.getMetadata(); - // TODO: debugging, remove - final JaxbService jaxbService = getServicesInjector().lookupService(JaxbService.class); - final String xml = jaxbService.toXml(objectLayoutMetadata, - ImmutableMap.<String,Object>of( - Marshaller.JAXB_SCHEMA_LOCATION, - Object_downloadLayoutXml.TNS + " " + Object_downloadLayoutXml.SCHEMA_LOCATION)); - System.out.println(xml); - - addOrReplace(ComponentType.ENTITY_SUMMARY, model); final List<TabGroup> tabGroups = FluentIterable http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java index d602730..722f98b 100644 --- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java +++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java @@ -22,6 +22,7 @@ package org.apache.isis.viewer.wicket.ui.components.entity.tabgroups; import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata; 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; @@ -44,19 +45,14 @@ public class EntityTabGroupsPanelFactory extends EntityComponentFactoryAbstract } @Override - protected ApplicationAdvice doAppliesTo(final EntityModel entityModel) { - return super.doAppliesTo(entityModel); // TODO: remove this override - } - - @Override public Component createComponent(final String id, final IModel<?> model) { final EntityModel entityModel = (EntityModel) model; final ObjectSpecification specification = entityModel.getTypeOfSpecification(); final ObjectLayoutMetadataFacet facet = specification.getFacet(ObjectLayoutMetadataFacet.class); - facet.reloadMetadata(); - final boolean hasLayout = !facet.isNoop(); + final ObjectLayoutMetadata layoutMetadata = facet.getMetadata(); + final boolean hasLayout = layoutMetadata != null; return hasLayout ? new EntityTabGroupsPanel(id, entityModel) : new EntityCombinedPanel(id, entityModel); http://git-wip-us.apache.org/repos/asf/isis/blob/9a39de94/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java index 609be99..b104ac3 100644 --- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java +++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java @@ -29,6 +29,7 @@ import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.util.string.Strings; +import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata; import org.apache.isis.core.metamodel.adapter.ObjectAdapter; import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking; import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException; @@ -138,16 +139,15 @@ public class EntityPage extends PageAbstract { final ObjectLayoutMetadataFacet facet = entityModel.getTypeOfSpecification() .getFacet(ObjectLayoutMetadataFacet.class); if(facet != null) { - // the facet should always exist - // - // it's sufficient to simply call reloadMetadata(). - // The facet checks the ObjectLayoutMetadataService to determine if dynamic reloading is enabled. - facet.reloadMetadata(); - if(facet.getMetadata() == null) { - // fallback to invalidating entire cache - if(!getDeploymentType().isProduction()) { - getSpecificationLoader().invalidateCacheFor(objectAdapter.getObject()); - } + // the facet should always exist, in fact + // just enough to ask for the metadata. + // This will cause the current ObjectSpec to be updated as a side effect. + final ObjectLayoutMetadata metadata = facet.getMetadata(); + + // if none, then fallback to invalidating entire cache + // (this is the original LayoutMetadataFromJson behaviour) + if(metadata == null && !getDeploymentType().isProduction()) { + getSpecificationLoader().invalidateCacheFor(objectAdapter.getObject()); } }