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/06/24 07:00:17 UTC
[isis] branch master updated: ISIS-2761: fixes Vaadin and JavaFX
provisioning issues
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 3e11ab8 ISIS-2761: fixes Vaadin and JavaFX provisioning issues
3e11ab8 is described below
commit 3e11ab8a79a3e10776cca9229497a2e8e3d0b182
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Jun 24 09:00:07 2021 +0200
ISIS-2761: fixes Vaadin and JavaFX provisioning issues
so can work on a shared object-icon resolver utility
also changes the RO Viewer's object-icon resource href value 'image' ->
'object-icon'
---
.../session/InteractionServiceDefault.java | 10 +-
.../java/demoapp/webapp/vaadin/DemoAppVaadin.java | 10 +-
.../javafx/ui/components/object/ObjectViewFx.java | 27 +++--
.../viewer/javafx/ui/main/MainViewFx.java | 8 +-
.../restfulobjects/applib/RepresentationType.java | 8 +-
.../domainobjects/DomainObjectReprRenderer.java | 6 +-
.../resources/DomainObjectResourceServerside.java | 121 +++++----------------
.../viewer/resources/_DomainObjectIcons.java | 74 +++++++++++++
8 files changed, 143 insertions(+), 121 deletions(-)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java
index 0a3ba9a..5c18284 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java
@@ -88,7 +88,7 @@ import lombok.extern.log4j.Log4j2;
public class InteractionServiceDefault
implements
InteractionService,
- InteractionLayerTracker {
+ InteractionLayerTracker {
@Inject AuthenticationManager authenticationManager;
@Inject MetamodelEventService runtimeEventService;
@@ -110,7 +110,7 @@ implements
//@PostConstruct .. too early, needs services to be provisioned first
@EventListener
- public void init(ContextRefreshedEvent event) {
+ public void init(final ContextRefreshedEvent event) {
requires(authenticationManager, "authenticationManager");
@@ -311,7 +311,7 @@ implements
return interactionLayerStack.get().size()==1;
}
- private void postInteractionOpened(IsisInteraction interaction) {
+ private void postInteractionOpened(final IsisInteraction interaction) {
interactionId.set(interaction.getInteractionId());
interactionScopeAwareBeans.forEach(bean->bean.beforeEnteringTransactionalBoundary(interaction));
txBoundaryHandler.onOpen(interaction);
@@ -320,7 +320,7 @@ implements
interactionScopeLifecycleHandler.onTopLevelInteractionOpened();
}
- private void preInteractionClosed(IsisInteraction interaction) {
+ private void preInteractionClosed(final IsisInteraction interaction) {
completeAndPublishCurrentCommand();
interactionScopeLifecycleHandler.onTopLevelInteractionClosing(); // cleanup the isis-session scope
val isSynchronizationActive = TransactionSynchronizationManager.isSynchronizationActive();
@@ -330,7 +330,7 @@ implements
interaction.close(); // do this last
}
- private void closeInteractionLayerStackDownToStackSize(int downToStackSize) {
+ private void closeInteractionLayerStackDownToStackSize(final int downToStackSize) {
log.debug("about to close authenication stack down to size {} (conversation-id={}, total-sessions-on-stack={}, {})",
downToStackSize,
diff --git a/examples/demo/vaadin/src/main/java/demoapp/webapp/vaadin/DemoAppVaadin.java b/examples/demo/vaadin/src/main/java/demoapp/webapp/vaadin/DemoAppVaadin.java
index fe86481..00f681d 100644
--- a/examples/demo/vaadin/src/main/java/demoapp/webapp/vaadin/DemoAppVaadin.java
+++ b/examples/demo/vaadin/src/main/java/demoapp/webapp/vaadin/DemoAppVaadin.java
@@ -32,14 +32,16 @@ import org.apache.isis.valuetypes.asciidoc.ui.wkt.IsisModuleValAsciidocUiWkt;
import org.apache.isis.valuetypes.sse.ui.wkt.IsisModuleValSseUiWkt;
import org.apache.isis.viewer.wicket.viewer.IsisModuleViewerWicketViewer;
-import demoapp.web.DemoAppManifestCommon;
+import demoapp.dom.DemoModuleCommon;
+import demoapp.web.DemoAppManifestJdo;
/**
* Bootstrap the application.
*/
@SpringBootApplication
@Import({
- DemoAppManifestCommon.class,
+ DemoModuleCommon.class,
+ DemoAppManifestJdo.class,
// INCUBATING
IsisModuleIncViewerVaadinViewer.class, // vaadin viewer
@@ -59,13 +61,15 @@ public class DemoAppVaadin extends SpringBootServletInitializer {
* @implNote this is to support the <em>Spring Boot Maven Plugin</em>, which auto-detects an
* entry point by searching for classes having a {@code main(...)}
*/
- public static void main(String[] args) {
+ public static void main(final String[] args) {
IsisPresets.logging(InteractionServiceDefault.class, "debug");
// IsisPresets.logging(VaadinAuthenticationHandler.class, "debug");
// IsisPresets.logging(IsisServletForVaadin.class, "debug");
IsisPresets.logging(_Probe.class, "debug"); // enable debug entry logging
+ System.setProperty("spring.profiles.active", "demo-jdo");
+
SpringApplication.run(new Class[] { DemoAppVaadin.class }, args);
}
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/object/ObjectViewFx.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/object/ObjectViewFx.java
index f494419..0c8de07f 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/object/ObjectViewFx.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/object/ObjectViewFx.java
@@ -77,6 +77,11 @@ public class ObjectViewFx extends VBox {
final Consumer<ManagedAction> actionEventHandler,
final ManagedObject managedObject) {
+ if(ManagedObjects.isNullOrUnspecifiedOrEmpty(managedObject)) {
+ log.warn("invalid managedObject, skipping");
+ return;
+ }
+
log.info("binding object interaction to owner {}", managedObject.getSpecification().getFeatureIdentifier());
_Assert.assertTrue(uiContext.getInteractionService().isInInteraction(), "requires an active interaction");
@@ -87,20 +92,20 @@ public class ObjectViewFx extends VBox {
val gridVisitor = new UiGridLayout.Visitor<Pane, TabPane>(this) {
@Override
- protected void onObjectTitle(Pane container, DomainObjectLayoutData domainObjectData) {
+ protected void onObjectTitle(final Pane container, final DomainObjectLayoutData domainObjectData) {
val label = _fx.h2(_fx.newLabel(container, objectTitle));
label.maxWidthProperty().bind(
container.widthProperty());
}
@Override
- protected Pane newRow(Pane container, BS3Row bs3Row) {
+ protected Pane newRow(final Pane container, final BS3Row bs3Row) {
val uiRow = _fx.newFlowPane(container);
return uiRow;
}
@Override
- protected Pane newCol(Pane container, BS3Col bs3col) {
+ protected Pane newCol(final Pane container, final BS3Col bs3col) {
val uiCol = _fx.newVBox(container);
@@ -119,7 +124,7 @@ public class ObjectViewFx extends VBox {
}
@Override
- protected Pane newActionPanel(Pane container) {
+ protected Pane newActionPanel(final Pane container) {
val uiActionPanel = _fx.newFlowPane(container);
_fx.toolbarLayout(uiActionPanel);
@@ -127,13 +132,13 @@ public class ObjectViewFx extends VBox {
}
@Override
- protected TabPane newTabGroup(Pane container, BS3TabGroup tabGroupData) {
+ protected TabPane newTabGroup(final Pane container, final BS3TabGroup tabGroupData) {
val uiTabGroup = _fx.newTabGroup(container);
return uiTabGroup;
}
@Override
- protected Pane newTab(TabPane container, BS3Tab tabData) {
+ protected Pane newTab(final TabPane container, final BS3Tab tabData) {
val uiTab = _fx.newTab(container, tabData.getName());
val uiTabContentPane = new VBox();
uiTab.setContent(uiTabContentPane);
@@ -141,7 +146,7 @@ public class ObjectViewFx extends VBox {
}
@Override
- protected Pane newFieldSet(Pane container, FieldSet fieldSetData) {
+ protected Pane newFieldSet(final Pane container, final FieldSet fieldSetData) {
val titledPanel = _fx.add(container, new TitledPanel(fieldSetData.getName()));
@@ -156,12 +161,12 @@ public class ObjectViewFx extends VBox {
@Override
- protected void onClearfix(Pane container, BS3ClearFix clearFixData) {
+ protected void onClearfix(final Pane container, final BS3ClearFix clearFixData) {
// TODO Auto-generated method stub
}
@Override
- protected void onAction(Pane container, ActionLayoutData actionData) {
+ protected void onAction(final Pane container, final ActionLayoutData actionData) {
val owner = managedObject;
val interaction = ActionInteraction.start(owner, actionData.getId(), Where.OBJECT_FORMS);
@@ -188,7 +193,7 @@ public class ObjectViewFx extends VBox {
}
@Override
- protected void onProperty(Pane container, PropertyLayoutData propertyData) {
+ protected void onProperty(final Pane container, final PropertyLayoutData propertyData) {
val owner = managedObject;
@@ -222,7 +227,7 @@ public class ObjectViewFx extends VBox {
}
@Override
- protected void onCollection(Pane container, CollectionLayoutData collectionData) {
+ protected void onCollection(final Pane container, final CollectionLayoutData collectionData) {
val owner = managedObject;
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MainViewFx.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MainViewFx.java
index 7ec0abf..4f0f228 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MainViewFx.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MainViewFx.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.iactnlayer.InteractionService;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ManagedObjects;
import org.apache.isis.core.runtime.context.IsisAppCommonContext;
import org.apache.isis.incubator.viewer.javafx.model.context.UiContextFx;
import org.apache.isis.incubator.viewer.javafx.model.events.JavaFxViewerConfig;
@@ -112,7 +113,7 @@ public class MainViewFx {
header.getTertiary().buildMenuItems(commonContext, rightMenuBuilder);
}
- private void replaceContent(Node node) {
+ private void replaceContent(final Node node) {
contentPane.getChildren().clear();
contentPane.getChildren().add(node);
}
@@ -122,8 +123,9 @@ public class MainViewFx {
uiContext.route(metaModelContext::getHomePageAdapter);
}
- private Node uiComponentForActionResult(ManagedObject actionResult) {
- if (actionResult.getSpecification().isParentedOrFreeCollection()) {
+ private Node uiComponentForActionResult(final ManagedObject actionResult) {
+ if (ManagedObjects.isSpecified(actionResult)
+ && actionResult.getSpecification().isParentedOrFreeCollection()) {
return TableViewFx.fromCollection(uiContext, actionResult, Where.STANDALONE_TABLES);
} else {
return ObjectViewFx.fromObject(
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java b/viewers/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java
index 7dd4858..93ba153 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java
@@ -108,7 +108,7 @@ public enum RepresentationType {
RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS3,
RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS3,
null),
- OBJECT_IMAGE(
+ OBJECT_ICON(
"image/png",
"image/png",
null),
@@ -198,16 +198,16 @@ public enum RepresentationType {
* Clones the (immutable) {@link #getMediaType() media type}, adding in one additional
* parameter value.
*/
- public MediaType getMediaType(String parameter, String paramValue) {
+ public MediaType getMediaType(final String parameter, final String paramValue) {
return getJsonMediaType(Collections.singletonMap(parameter, paramValue));
}
- public MediaType getJsonMediaType(Map<String, String> mediaTypeParams) {
+ public MediaType getJsonMediaType(final Map<String, String> mediaTypeParams) {
Map<String, String> parameters = new HashMap<>(jsonMediaType.getParameters());
parameters.putAll(mediaTypeParams);
return new MediaType(jsonMediaType.getType(), jsonMediaType.getSubtype(), parameters);
}
- public MediaType getXmlMediaType(Map<String, String> mediaTypeParams) {
+ public MediaType getXmlMediaType(final Map<String, String> mediaTypeParams) {
if(xmlMediaType == null) {
return null;
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index 3a6a0ee..2d869d4 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -81,8 +81,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
final Rel rel = Rel.OBJECT_ICON;
final String objectRef = ManagedObjects.stringifyElseFail(objectAdapter, "/");
- final String url = "objects/" + objectRef + "/image";
- return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.OBJECT_IMAGE, url);
+ final String url = "objects/" + objectRef + "/object-icon";
+ return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.OBJECT_ICON, url);
}
private static enum Mode {
@@ -457,7 +457,7 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
}
- public static Object valueOrRef(IResourceContext context, JsonValueEncoder jsonValueEncoder, ManagedObject adapter) {
+ public static Object valueOrRef(final IResourceContext context, final JsonValueEncoder jsonValueEncoder, final ManagedObject adapter) {
val spec = adapter.getSpecification();
if(spec.isValue()) {
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index 39aada8..26d8fc8 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.viewer.restfulobjects.viewer.resources;
-import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
@@ -45,12 +44,9 @@ import org.apache.isis.applib.layout.component.DomainObjectLayoutData;
import org.apache.isis.applib.layout.component.PropertyLayoutData;
import org.apache.isis.applib.layout.grid.Grid;
import org.apache.isis.applib.layout.links.Link;
-import org.apache.isis.commons.internal.base._Bytes;
-import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.applib.services.iactnlayer.InteractionLayerTracker;
import org.apache.isis.commons.internal.codec._UrlDecoderUtil;
-import org.apache.isis.commons.internal.resources._Resources;
import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.applib.services.iactnlayer.InteractionLayerTracker;
import org.apache.isis.core.metamodel.consent.Consent;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.context.MetaModelContext;
@@ -60,7 +56,6 @@ import org.apache.isis.core.metamodel.interactions.managed.MemberInteraction.Acc
import org.apache.isis.core.metamodel.interactions.managed.PropertyInteraction;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ManagedObjects.EntityUtil;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.Rel;
import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
@@ -102,7 +97,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response persist(@PathParam("domainType") String domainType, final InputStream object) {
+ public Response persist(@PathParam("domainType") final String domainType, final InputStream object) {
val resourceContext = createResourceContext(
RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS, RepresentationService.Intent.JUST_CREATED);
@@ -158,7 +153,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response object(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId) {
+ public Response object(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId) {
val resourceContext = createResourceContext(
RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS, RepresentationService.Intent.ALREADY_PERSISTENT);
@@ -178,7 +173,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response object(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, final InputStream object) {
+ public Response object(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, final InputStream object) {
val resourceContext = createResourceContext(
RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS, RepresentationService.Intent.ALREADY_PERSISTENT);
@@ -209,14 +204,14 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
@DELETE
@Path("/{domainType}/{instanceId}")
@Override
- public Response deleteMethodNotSupported(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId) {
+ public Response deleteMethodNotSupported(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting objects is not supported.");
}
@POST
@Path("/{domainType}/{instanceId}")
@Override
- public Response postMethodNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId) {
+ public Response postMethodNotAllowed(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to object resource is not allowed.");
}
@@ -225,64 +220,9 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
// domain object layout
// //////////////////////////////////////////////////////////
- static class IconKey {
- private final Class<?> domainClass;
- private final String modifier;
-
- IconKey(final Class<?> domainClass, final String modifier) {
- this.domainClass = domainClass;
- this.modifier = modifier;
- }
-
- String getImageName() {
- final StringBuilder buf = new StringBuilder(domainClass.getSimpleName());
- if(!_Strings.isNullOrEmpty(modifier)) {
- buf.append("-").append(modifier);
- }
- buf.append(".png");
- return buf.toString();
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
-
- final IconKey iconKey = (IconKey) o;
-
- if (domainClass != null ? !domainClass.equals(iconKey.domainClass) : iconKey.domainClass != null) {
- return false;
- }
- return modifier != null ? modifier.equals(iconKey.modifier) : iconKey.modifier == null;
- }
-
- @Override
- public int hashCode() {
- int result = domainClass != null ? domainClass.hashCode() : 0;
- result = 31 * result + (modifier != null ? modifier.hashCode() : 0);
- return result;
- }
-
- byte[] toBytes() {
- String imageName = getImageName();
-
- try {
-
- final InputStream resource = _Resources.load(domainClass, imageName);
- return _Bytes.of(resource);
-
- } catch (IOException e) {
- return null;
- }
-
- }
- }
-
@Override
@GET
- @Path("/{domainType}/{instanceId}/image")
+ @Path("/{domainType}/{instanceId}/object-icon")
@Consumes({ MediaType.WILDCARD })
@Produces({
"image/png"
@@ -293,18 +233,15 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
@PathParam("instanceId")
final String instanceId) {
- createResourceContext(
- RepresentationType.OBJECT_LAYOUT, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
+// createResourceContext(
+// RepresentationType.OBJECT_ICON, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
- final ManagedObject objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId);
- final ObjectSpecification objectSpec = objectAdapter.getSpecification();
- final String iconName = objectSpec.getIconName(objectAdapter);
- final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
- final IconKey iconKey = new IconKey(correspondingClass, iconName);
- final byte[] bytes = iconKey.toBytes();
- return bytes != null
- ? Response.ok(bytes).build()
- : Response.status(Response.Status.NOT_FOUND).build();
+ val objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId);
+
+ return _DomainObjectIcons.loadIcon(objectAdapter)
+ .map(Response::ok)
+ .orElseGet(Responses::ofNotFound)
+ .build();
}
@Override
@@ -426,7 +363,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response propertyDetails(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId) {
+ public Response propertyDetails(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId) {
val resourceContext = createResourceContext(
RepresentationType.OBJECT_PROPERTY, Where.OBJECT_FORMS, RepresentationService.Intent.NOT_APPLICABLE);
@@ -448,7 +385,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response modifyProperty(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId, final InputStream body) {
+ public Response modifyProperty(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId, final InputStream body) {
val resourceContext = createResourceContext(
ResourceDescriptor.generic(Where.OBJECT_FORMS, RepresentationService.Intent.NOT_APPLICABLE));
@@ -478,7 +415,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response clearProperty(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId) {
+ public Response clearProperty(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId) {
val resourceContext = createResourceContext(
ResourceDescriptor.generic(Where.OBJECT_FORMS, RepresentationService.Intent.NOT_APPLICABLE));
@@ -498,7 +435,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
@POST
@Path("/{domainType}/{instanceId}/properties/{propertyId}")
@Override
- public Response postPropertyNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId, @PathParam("propertyId") String propertyId) {
+ public Response postPropertyNotAllowed(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to a property resource is not allowed.");
}
@@ -514,7 +451,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response accessCollection(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId) {
+ public Response accessCollection(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId) {
val resourceContext = createResourceContext(
RepresentationType.OBJECT_COLLECTION, Where.PARENTED_TABLES, RepresentationService.Intent.NOT_APPLICABLE);
@@ -534,7 +471,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response addToSet(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId, final InputStream body) {
+ public Response addToSet(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId, final InputStream body) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "The framework no longer supports mutable collections.");
}
@@ -547,7 +484,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response addToList(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId, final InputStream body) {
+ public Response addToList(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId, final InputStream body) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "The framework no longer supports mutable collections.");
}
@@ -560,7 +497,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response removeFromCollection(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId) {
+ public Response removeFromCollection(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "The framework no longer supports mutable collections.");
}
@@ -577,7 +514,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response actionPrompt(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId) {
+ public Response actionPrompt(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId) {
val resourceContext = createResourceContext(
RepresentationType.OBJECT_ACTION, Where.OBJECT_FORMS, RepresentationService.Intent.NOT_APPLICABLE);
@@ -591,21 +528,21 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
@DELETE
@Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
- public Response deleteActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId, @PathParam("actionId") String actionId) {
+ public Response deleteActionPromptNotAllowed(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting action prompt resource is not allowed.");
}
@POST
@Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
- public Response postActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId, @PathParam("actionId") String actionId) {
+ public Response postActionPromptNotAllowed(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to an action prompt resource is not allowed.");
}
@PUT
@Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
- public Response putActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId, @PathParam("actionId") String actionId) {
+ public Response putActionPromptNotAllowed(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId) {
throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Putting to an action prompt resource is not allowed.");
}
@@ -676,7 +613,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeAction(
- @PathParam("domainType") String domainType,
+ @PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@PathParam("actionId") final String actionId,
final InputStream body) {
@@ -696,7 +633,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
@DELETE
@Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
@Override
- public Response deleteInvokeActionNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") String instanceId, @PathParam("actionId") String actionId) {
+ public Response deleteInvokeActionNotAllowed(@PathParam("domainType") final String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId) {
throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting an action invocation resource is not allowed.");
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainObjectIcons.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainObjectIcons.java
new file mode 100644
index 0000000..1efafef
--- /dev/null
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/_DomainObjectIcons.java
@@ -0,0 +1,74 @@
+/*
+ * 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.restfulobjects.viewer.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+
+import org.apache.isis.commons.internal.base._Bytes;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.resources._Resources;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ManagedObjects;
+
+import lombok.val;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+class _DomainObjectIcons {
+
+ public Optional<byte[]> loadIcon(
+ final @Nullable ManagedObject object) {
+
+ if(ManagedObjects.isNullOrUnspecifiedOrEmpty(object)) {
+ return Optional.empty();
+ }
+
+ val spec = object.getSpecification();
+
+ return Optional.ofNullable(
+ loadIcon(
+ spec.getCorrespondingClass(),
+ spec.getIconName(object)
+ ));
+ }
+
+ //TODO[2761] that's a naive implementation; refactor the Wicket Viewer's icon resolving logic into a reusable utility or service
+ private byte[] loadIcon(
+ final Class<?> domainClass,
+ final String iconNameModifier) {
+
+ val iconResourceName = _Strings.isNotEmpty(iconNameModifier)
+ ? domainClass.getSimpleName() + "-" + iconNameModifier
+ : domainClass.getSimpleName();
+
+ try {
+ final InputStream resource = _Resources
+ .load(domainClass, iconResourceName + ".png");
+ return _Bytes.of(resource);
+
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+}