You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/05/19 18:49:36 UTC
[isis] branch master updated: ISIS-2677: recursively lookup the
type hierarchy for layout candidate files
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 1cb644e ISIS-2677: recursively lookup the type hierarchy for layout candidate files
1cb644e is described below
commit 1cb644eba95ec13540be402a3adfe57a7eb1fe1e
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed May 19 20:49:17 2021 +0200
ISIS-2677: recursively lookup the type hierarchy for layout candidate
files
---
.../commons/internal/resources/_Resources.java | 2 +-
.../services/grid/GridLoaderServiceDefault.java | 116 ++++++++++++---------
...dLoaderServiceDefault_resourceNameFor_Test.java | 54 ++++++----
.../JavaLangStringEntity.layout.xml} | 0
4 files changed, 105 insertions(+), 67 deletions(-)
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/resources/_Resources.java b/commons/src/main/java/org/apache/isis/commons/internal/resources/_Resources.java
index a3d9454..a45804c 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/resources/_Resources.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/resources/_Resources.java
@@ -57,7 +57,7 @@ public final class _Resources {
* @param resourceName
* @return An input stream for reading the resource, or null if the resource could not be found.
*/
- public static InputStream load(
+ public static @Nullable InputStream load(
final @NonNull Class<?> contextClass,
final @NonNull String resourceName) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault.java
index 2689b75..56a1074 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault.java
@@ -19,11 +19,12 @@
package org.apache.isis.core.metamodel.services.grid;
import java.io.IOException;
-import java.net.URL;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
@@ -36,12 +37,16 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.layout.grid.Grid;
import org.apache.isis.applib.services.grid.GridLoaderService;
import org.apache.isis.applib.services.message.MessageService;
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.reflection._Reflect;
+import org.apache.isis.commons.internal.reflection._Reflect.InterfacePolicy;
import org.apache.isis.commons.internal.resources._Resources;
import org.apache.isis.core.config.environment.IsisSystemEnvironment;
+import lombok.NonNull;
import lombok.Value;
+import lombok.val;
import lombok.extern.log4j.Log4j2;
@Service
@@ -62,13 +67,20 @@ public class GridLoaderServiceDefault implements GridLoaderService {
private final String layoutIfAny;
}
+ @Value
+ static class XmlAndResourceName {
+ private final @NonNull String xmlContent;
+ private final @NonNull String resourceName;
+ }
+
+
// for better logging messages (used only in prototyping mode)
private final Map<DomainClassAndLayout, String> badXmlByDomainClassAndLayout = _Maps.newHashMap();
@Value
static class DomainClassAndLayoutAndXml {
private final DomainClassAndLayout domainClassAndLayout;
- private final String xml;
+ private final XmlAndResourceName xml;
}
// cache (used only in prototyping mode)
@@ -81,13 +93,13 @@ public class GridLoaderServiceDefault implements GridLoaderService {
@Override
public void remove(final Class<?> domainClass) {
- final String layoutIfAny = null;
- final DomainClassAndLayout dcal = new DomainClassAndLayout(domainClass, layoutIfAny);
if(!supportsReloading()) {
return;
}
+ final String layoutIfAny = null;
+ final DomainClassAndLayout dcal = new DomainClassAndLayout(domainClass, layoutIfAny);
badXmlByDomainClassAndLayout.remove(dcal);
- final String xml = loadXml(dcal);
+ final XmlAndResourceName xml = loadXml(dcal).orElse(null);
if(xml == null) {
return;
}
@@ -96,13 +108,13 @@ public class GridLoaderServiceDefault implements GridLoaderService {
@Override
public boolean existsFor(final Class<?> domainClass) {
- return resourceNameFor(new DomainClassAndLayout(domainClass, null)) != null;
+ return loadXml(new DomainClassAndLayout(domainClass, null)).isPresent();
}
@Override
public Grid load(final Class<?> domainClass, final String layoutIfAny) {
final DomainClassAndLayout dcal = new DomainClassAndLayout(domainClass, layoutIfAny);
- final String xml = loadXml(dcal);
+ final XmlAndResourceName xml = loadXml(dcal).orElse(null);
if(xml == null) {
return null;
}
@@ -116,7 +128,7 @@ public class GridLoaderServiceDefault implements GridLoaderService {
final String badXml = badXmlByDomainClassAndLayout.get(dcal);
if(badXml != null) {
- if(Objects.equals(xml, badXml)) {
+ if(Objects.equals(xml.getXmlContent(), badXml)) {
// seen this before and already logged; just quit
return null;
} else {
@@ -127,7 +139,7 @@ public class GridLoaderServiceDefault implements GridLoaderService {
}
try {
- final Grid grid = gridReader.loadGrid(xml);
+ final Grid grid = gridReader.loadGrid(xml.getXmlContent());
grid.setDomainClass(domainClass);
if(supportsReloading()) {
gridByDomainClassAndLayoutAndXml.put(dcalax, grid);
@@ -137,12 +149,12 @@ public class GridLoaderServiceDefault implements GridLoaderService {
if(supportsReloading()) {
// save fact that this was bad XML, so that we don't log again if called next time
- badXmlByDomainClassAndLayout.put(dcal, xml);
+ badXmlByDomainClassAndLayout.put(dcal, xml.getXmlContent());
}
// 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 resourceName = resourceNameFor(dcal);
+ final String resourceName = xml.getResourceName();
final String message = "Failed to parse " + resourceName + " file (" + ex.getMessage() + ")";
if(supportsReloading()) {
messageService.warnUser(message);
@@ -153,45 +165,55 @@ public class GridLoaderServiceDefault implements GridLoaderService {
}
}
+ // -- HELPER
+ Optional<XmlAndResourceName> loadXml(final DomainClassAndLayout dcal) {
+ return _Reflect.streamTypeHierarchy(dcal.getDomainClass(), InterfacePolicy.EXCLUDE)
+ .map(type->loadXml(type, dcal.getLayoutIfAny()))
+ .filter(Optional::isPresent)
+ .findFirst()
+ .map(Optional::get);
+ }
- private String loadXml(final DomainClassAndLayout dcal) {
- final String resourceName = resourceNameFor(dcal);
- if(resourceName == null) {
- log.debug("Failed to locate layout file for '{}'", dcal.toString());
- return null;
- }
- try {
- return _Resources.loadAsStringUtf8(dcal.domainClass, resourceName);
- } catch (IOException ex) {
- log.debug(
- "Failed to locate file {} (relative to {}.class)",
- resourceName, dcal.domainClass.getName(), ex);
- return null;
- }
+ private Optional<XmlAndResourceName> loadXml(
+ final @NonNull Class<?> domainClass,
+ final @Nullable String layoutIfAny) {
+ return streamResourceNameCandidatesFor(domainClass, layoutIfAny)
+ .map(candidateResourceName->tryLoadXml(domainClass, candidateResourceName))
+ .filter(Optional::isPresent)
+ .findFirst()
+ .map(Optional::get);
}
- String resourceNameFor(final DomainClassAndLayout dcal) {
- final List<String> candidateResourceNames = _Lists.newArrayList();
- if(dcal.layoutIfAny != null) {
- candidateResourceNames.add(
- String.format("%s-%s.layout.xml", dcal.domainClass.getSimpleName(), dcal.layoutIfAny));
- }
- candidateResourceNames.add(
- String.format("%s.layout.xml", dcal.domainClass.getSimpleName()));
- candidateResourceNames.add(
- String.format("%s.layout.fallback.xml", dcal.domainClass.getSimpleName()));
- for (final String candidateResourceName : candidateResourceNames) {
- try {
- final URL resource = _Resources.getResourceUrl(dcal.domainClass, candidateResourceName);
- if (resource != null) {
- return candidateResourceName;
- }
- } catch(IllegalArgumentException ex) {
- // continue
- }
+ private Stream<String> streamResourceNameCandidatesFor(
+ final @NonNull Class<?> domainClass,
+ final @Nullable String layoutIfAny) {
+
+ val typeSimpleName = domainClass.getSimpleName();
+
+ return _Strings.isNotEmpty(layoutIfAny)
+ ? Stream.of(
+ String.format("%s-%s.layout.xml", typeSimpleName, layoutIfAny),
+ String.format("%s.layout.xml", typeSimpleName),
+ String.format("%s.layout.fallback.xml", typeSimpleName))
+ : Stream.of(
+ String.format("%s.layout.xml", typeSimpleName),
+ String.format("%s.layout.fallback.xml", typeSimpleName));
+ }
+
+ private Optional<XmlAndResourceName> tryLoadXml(
+ final @NonNull Class<?> type,
+ final @NonNull String candidateResourceName) {
+ try {
+ return Optional.ofNullable(
+ _Resources.loadAsStringUtf8(type, candidateResourceName))
+ .map(xml->new XmlAndResourceName(xml, candidateResourceName));
+ } catch (IOException ex) {
+ log.error(
+ "Failed to load layout file {} (relative to {}.class)",
+ candidateResourceName, type.getName(), ex);
}
- return null;
+ return Optional.empty();
}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault_resourceNameFor_Test.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault_resourceNameFor_Test.java
index 90132bf..7077150 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault_resourceNameFor_Test.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/GridLoaderServiceDefault_resourceNameFor_Test.java
@@ -18,41 +18,57 @@
*/
package org.apache.isis.core.metamodel.services.grid;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.isis.core.metamodel.services.grid.GridLoaderServiceDefault.DomainClassAndLayout;
public class GridLoaderServiceDefault_resourceNameFor_Test {
private GridLoaderServiceDefault gridLoaderServiceDefault;
- @Before
- public void setUp() throws Exception {
+ @BeforeEach
+ void setUp() throws Exception {
gridLoaderServiceDefault = new GridLoaderServiceDefault();
}
@Test
- public void when_default_exists() {
- final String s = gridLoaderServiceDefault.resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo.class, null));
- Assert.assertThat(s, is(equalTo("Foo.layout.xml")));
+ void when_default_exists() {
+ assertEquals(
+ "Foo.layout.xml",
+ resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo.class, null)));
}
@Test
- public void when_fallback_exists() {
- final String s = gridLoaderServiceDefault.resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo2.class, null));
- Assert.assertThat(s, is(equalTo("Foo2.layout.fallback.xml")));
+ void when_fallback_exists() {
+ assertEquals(
+ "Foo2.layout.fallback.xml",
+ resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo2.class, null)));
}
+
@Test
- public void when_default_and_fallback_both_exist() {
- final String s = gridLoaderServiceDefault.resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo3.class, null));
- Assert.assertThat(s, is(equalTo("Foo3.layout.xml")));
+ void when_default_and_fallback_both_exist() {
+ assertEquals(
+ "Foo3.layout.xml",
+ resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo3.class, null)));
}
+
@Test
- public void when_neither_exist() {
- final String s = gridLoaderServiceDefault.resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo4.class, null));
- Assert.assertNull(s);
+ void when_neither_exist() {
+ assertEquals(
+ (String)null,
+ resourceNameFor(new GridLoaderServiceDefault.DomainClassAndLayout(Foo4.class, null)));
+ }
+
+ // -- HELPER
+
+ private String resourceNameFor(DomainClassAndLayout dcal) {
+ return gridLoaderServiceDefault.loadXml(dcal)
+ .map(xml->xml.getResourceName())
+ .orElse(null);
}
+
+
}
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/strings/jdo/JavaLangStringJdo.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/strings/persistence/JavaLangStringEntity.layout.xml
similarity index 100%
rename from examples/demo/domain/src/main/java/demoapp/dom/types/javalang/strings/jdo/JavaLangStringJdo.layout.xml
rename to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/strings/persistence/JavaLangStringEntity.layout.xml