You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/02/08 19:29:51 UTC

[30/32] git commit: ISIS-327: done

ISIS-327: done


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/ed11bc04
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/ed11bc04
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/ed11bc04

Branch: refs/heads/master
Commit: ed11bc0437b9fbca016324430446ccd4e4d9f7e6
Parents: 7b745ec
Author: Dan Haywood <da...@apache.org>
Authored: Fri Feb 8 17:52:28 2013 +0000
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Feb 8 18:00:49 2013 +0000

----------------------------------------------------------------------
 .../EventSerializerRendererContext.java            |    6 +-
 .../RestfulObjectsSpecEventSerializer.java         |   24 ++-
 core/pom.xml                                       |   22 +-
 .../system/session/IsisSessionFactoryAbstract.java |  125 +++++++++
 ...ssionFactoryAbstractTest_init_and_shutdown.java |  205 +++++++++++++++
 .../src/main/webapp/WEB-INF/isis.properties        |    3 +
 6 files changed, 369 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/ed11bc04/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
index 9cb2ee7..98b6711 100644
--- a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/EventSerializerRendererContext.java
@@ -12,15 +12,17 @@ import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 
 public class EventSerializerRendererContext implements RendererContext {
 
+    private final String baseUrl;
     private final Where where;
     
-    public EventSerializerRendererContext(Where where) {
+    public EventSerializerRendererContext(String baseUrl, Where where) {
+        this.baseUrl = baseUrl;
         this.where = where;
     }
 
     @Override
     public String urlFor(String url) {
-        return "[base]/" + url;
+        return baseUrl + url;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/ed11bc04/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
index 8a23976..29e1b14 100644
--- a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/eventserializer/RestfulObjectsSpecEventSerializer.java
@@ -1,6 +1,10 @@
 package org.apache.isis.viewer.restfulobjects.rendering.eventserializer;
 
 import java.io.IOException;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Where;
@@ -20,15 +24,29 @@ public class RestfulObjectsSpecEventSerializer implements EventSerializer {
     private final static JsonMapper jsonMapper = JsonMapper.instance();
 
     private final static DomainObjectReprRenderer.Factory objectRendererFactory = new DomainObjectReprRenderer.Factory();
-    
+    private final static String BASE_URL_KEY = RestfulObjectsSpecEventSerializer.class.getName() + ".baseUrl";
+    private static final String BASE_URL_DEFAULT = "http://localhost:8080/restful/";
+
+    private String baseUrl;
+
+    @PostConstruct
+    public void init(Map<String,String> props) {
+        final String baseUrlFromConfig = props.get(BASE_URL_KEY);
+        baseUrl = baseUrlFromConfig != null? baseUrlFromConfig: BASE_URL_DEFAULT;
+    }
+
+    @PreDestroy
+    public void shutdown() {
+    }
+
     @Programmatic
     @Override
     public Object serialize(EventMetadata metadata, EventPayload payload) {
-        final RendererContext rendererContext = new EventSerializerRendererContext(Where.OBJECT_FORMS);
+        final RendererContext rendererContext = new EventSerializerRendererContext(baseUrl, Where.OBJECT_FORMS);
 
         final JsonRepresentation payloadRepr = asPayloadRepr(rendererContext, payload);
         final JsonRepresentation eventRepr = asEventRepr(metadata, payloadRepr);
-        
+
         return jsonFor(eventRepr);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/ed11bc04/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index e42e438..82b01aa 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1261,17 +1261,7 @@ ${license.additional-notes}
                     </exclusion>
                 </exclusions>
             </dependency>
-	        <dependency>
-	            <groupId>org.apache.geronimo.specs</groupId>
-                <artifactId>geronimo-jsp_2.1_spec</artifactId>
-	            <version>1.0.1</version>
-	        </dependency>
-	          <dependency>
-	            <groupId>org.apache.geronimo.specs</groupId>
-	            <artifactId>geronimo-jta_1.1_spec</artifactId>
-	            <version>1.1.1</version>
-	          </dependency>
-            
+
             <dependency>
                 <groupId>org.htmlparser</groupId>
                 <artifactId>htmlparser</artifactId>
@@ -1338,6 +1328,16 @@ ${license.additional-notes}
             <!-- Specs -->
             <dependency>
                 <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-jsp_2.1_spec</artifactId>
+                <version>1.0.1</version>
+            </dependency>
+              <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-jta_1.1_spec</artifactId>
+                <version>1.1.1</version>
+              </dependency>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
                 <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
                 <version>1.1.1</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/isis/blob/ed11bc04/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstract.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstract.java
index 26d3088..4915bb9 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstract.java
@@ -24,13 +24,20 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 
+import java.lang.reflect.Method;
 import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.lang.JavaClassUtils;
 import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
+import org.apache.isis.core.metamodel.adapter.util.InvokeUtils;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authorization.AuthorizationManager;
@@ -41,6 +48,7 @@ import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
 import org.apache.isis.core.runtime.userprofile.UserProfile;
 import org.apache.isis.core.runtime.userprofile.UserProfileLoader;
+import org.apache.log4j.Logger;
 
 /**
  * Creates an implementation of
@@ -57,6 +65,8 @@ import org.apache.isis.core.runtime.userprofile.UserProfileLoader;
  */
 public abstract class IsisSessionFactoryAbstract implements IsisSessionFactory {
 
+    private final static Logger LOG = Logger.getLogger(IsisSessionFactoryAbstract.class);
+    
     private final DeploymentType deploymentType;
     private final IsisConfiguration configuration;
     private final TemplateImageLoader templateImageLoader;
@@ -91,8 +101,61 @@ public abstract class IsisSessionFactoryAbstract implements IsisSessionFactory {
         this.persistenceSessionFactory = persistenceSessionFactory;
         this.serviceList = serviceList;
         this.oidMarshaller = oidMarshaller;
+        
+        validateServices(serviceList);
+    }
+
+    /**
+     * Validate domain services lifecycle events.
+     * 
+     * <p>
+     * Specifically:
+     * <ul>
+     * <li>All {@link PostConstruct} methods must either take no arguments or take a {@link Properties} object.</li>
+     * <li>All {@link PreDestroy} methods must take no arguments.</li>
+     * </ul>
+     * 
+     * <p>
+     * If this isn't the case, then we fail fast.
+     */
+    private void validateServices(List<Object> serviceList) {
+        for (Object service : serviceList) {
+            final Method[] methods = service.getClass().getMethods();
+            for (Method method : methods) {
+                validatePostConstructMethods(service, method);
+                validatePreDestroyMethods(service, method);
+            }
+        }
     }
 
+    private void validatePostConstructMethods(Object service, Method method) {
+        PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
+        if(postConstruct == null) {
+            return;
+        }
+        final int numParams = method.getParameterTypes().length;
+        if(numParams == 0) {
+            return;
+        }
+        if(numParams == 1 && method.getParameterTypes()[0].isAssignableFrom(Map.class)) {
+            return;
+        }
+        throw new IllegalStateException("Domain service " + service.getClass().getName() + " has @PostConstruct method " + method.getName() + "; such methods must take either no argument or 1 argument of type Map<String,String>"); 
+    }
+
+    private void validatePreDestroyMethods(Object service, Method method) {
+        PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
+        if(preDestroy == null) {
+            return;
+        }
+        final int numParams = method.getParameterTypes().length;
+        if(numParams == 0) {
+            return;
+        }
+        throw new IllegalStateException("Domain service " + service.getClass().getName() + " has @PreDestroy method " + method.getName() + "; such methods must take no arguments"); 
+    }
+
+
     // ///////////////////////////////////////////
     // init, shutdown
     // ///////////////////////////////////////////
@@ -117,10 +180,16 @@ public abstract class IsisSessionFactoryAbstract implements IsisSessionFactory {
         authenticationManager.init();
         authorizationManager.init();
         persistenceSessionFactory.init();
+        
+        initServices(getConfiguration());
     }
 
+    
     @Override
     public void shutdown() {
+        
+        shutdownServices();
+        
         persistenceSessionFactory.shutdown();
         authenticationManager.shutdown();
         specificationLoaderSpi.shutdown();
@@ -128,6 +197,62 @@ public abstract class IsisSessionFactoryAbstract implements IsisSessionFactory {
         userProfileLoader.shutdown();
     }
 
+    protected void initServices(IsisConfiguration configuration) {
+        final List<Object> services = getServices();
+        Map<String, String> props = configuration.asMap();
+        for (Object service : services) {
+            callPostConstructIfExists(service, props);
+        }
+    }
+
+    private void callPostConstructIfExists(Object service, Map<String, String> props) {
+        LOG.info("calling @PostConstruct on all domain services");
+        Method[] methods = service.getClass().getMethods();
+        for (Method method : methods) {
+            PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
+            if(postConstruct == null) {
+                continue;
+            }
+            LOG.info("calling @PostConstruct method: " + service.getClass().getName() + ": " + method.getName());
+
+            final int numParams = method.getParameterTypes().length;
+            
+            // unlike shutdown, we don't swallow exceptions; would rather fail early
+            if(numParams == 0) {
+                InvokeUtils.invoke(method, service);
+            } else {
+                InvokeUtils.invoke(method, service, new Object[]{props});
+            }
+        }
+    }
+
+
+    protected void shutdownServices() {
+        final List<Object> services = getServices();
+        for (Object service : services) {
+            callPreDestroyIfExists(service);
+        }
+    }
+
+    private void callPreDestroyIfExists(Object service) {
+        LOG.info("calling @PreDestroy on all domain services");
+        final Method[] methods = service.getClass().getMethods();
+        for (Method method : methods) {
+            PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
+            if(preDestroy == null) {
+                continue;
+            }
+            LOG.info("calling @PreDestroy method: " + service.getClass().getName() + ": " + method.getName());
+            try {
+                InvokeUtils.invoke(method, service);
+            } catch(Exception ex) {
+                // do nothing
+                LOG.warn("@PreDestroy method threw exception - continuing anyway", ex);
+            }
+        }
+    }
+
+
     @Override
     public IsisSession openSession(final AuthenticationSession authenticationSession) {
         final PersistenceSession persistenceSession = persistenceSessionFactory.createPersistenceSession();

http://git-wip-us.apache.org/repos/asf/isis/blob/ed11bc04/core/runtime/src/test/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstractTest_init_and_shutdown.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstractTest_init_and_shutdown.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstractTest_init_and_shutdown.java
new file mode 100644
index 0000000..bf8a186
--- /dev/null
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryAbstractTest_init_and_shutdown.java
@@ -0,0 +1,205 @@
+package org.apache.isis.core.runtime.system.session;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.core.runtime.authorization.AuthorizationManager;
+import org.apache.isis.core.runtime.imageloader.TemplateImageLoader;
+import org.apache.isis.core.runtime.system.DeploymentType;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
+import org.apache.isis.core.runtime.userprofile.UserProfileLoader;
+import org.apache.isis.core.unittestsupport.jmock.auto.Mock;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+public class IsisSessionFactoryAbstractTest_init_and_shutdown {
+
+    public static class DomainServiceWithNoPostConstructOrPreDestroy {
+    }
+
+    public static class DomainServiceWithValidPostConstructNoParams {
+        boolean called = false;
+        @PostConstruct
+        public void postConstruct() {
+            called = true;
+        }
+    }
+
+    public static class DomainServiceWithValidPostConstructPropertiesParam {
+        boolean called = false;
+        Map<String, String> props;
+        @PostConstruct
+        public void postConstruct(Map<String,String> props) {
+            this.props = props;
+            called = true;
+        }
+    }
+
+    public static class DomainServiceWithValidPostConstructSubtypeOfPropertiesParam {
+        boolean called = false;
+        Object props;
+        @PostConstruct
+        public void postConstruct(Object props) {
+            this.props = props;
+            called = true;
+        }
+    }
+
+    public static class DomainServiceWithInvalidPostConstructWrongNumberParams {
+        @PostConstruct
+        public void postConstruct(int i, Properties props) {}
+    }
+
+    public static class DomainServiceWithInvalidPostConstructWrongTypeOfParam {
+        @PostConstruct
+        public void postConstruct(int i) {}
+    }
+
+    public static class DomainServiceWithValidPreDestroyNoParams {
+        boolean called = false;
+        @PostConstruct
+        public void postConstruct() {
+            called = true;
+        }
+    }
+
+    public static class DomainServiceWithInvalidPreDestroyWrongNumberParams {
+        @PostConstruct
+        public void postConstruct(int i) {}
+    }
+
+
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private DeploymentType deploymentType;
+    @Mock
+    private SpecificationLoaderSpi specificationLoader;
+    @Mock
+    private TemplateImageLoader templateImageLoader;
+    @Mock
+    private AuthenticationManager authenticationManager;
+    @Mock
+    private AuthorizationManager authorizationManager;
+    @Mock
+    private UserProfileLoader userProfileLoader;
+    @Mock
+    private PersistenceSessionFactory persistenceSessionFactory;
+    @Mock
+    private OidMarshaller oidMarshaller;
+    
+    private IsisConfigurationDefault configuration;
+    private List<Object> serviceList;
+
+    private IsisSessionFactoryAbstract isfa;
+
+    
+    @Before
+    public void setUp() throws Exception {
+        configuration = new IsisConfigurationDefault();
+        configuration.add("foo", "bar");
+        
+        serviceList = Lists.newArrayList();
+        context.ignoring(deploymentType, specificationLoader, templateImageLoader, authenticationManager, authorizationManager, userProfileLoader, persistenceSessionFactory, oidMarshaller);
+    }
+    
+    @Test
+    public void emptyListOfServices() {
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+    }
+
+    @Test
+    public void preConstruct_DomainServiceWithNoPostConstructOrPreDestroy() {
+        serviceList.add(new DomainServiceWithNoPostConstructOrPreDestroy());
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+        
+        isfa.init();
+        isfa.shutdown();
+    }
+
+    @Test
+    public void preConstruct_DomainServiceWithValidPostConstructNoParams() {
+        DomainServiceWithValidPostConstructNoParams domainService = new DomainServiceWithValidPostConstructNoParams();
+        serviceList.add(domainService);
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+        isfa.init();
+        assertThat(domainService.called,is(true));
+        isfa.shutdown();
+    }
+
+    @Test
+    public void preConstruct_DomainServiceWithValidPostConstructPropertiesParam() {
+        DomainServiceWithValidPostConstructPropertiesParam domainService = new DomainServiceWithValidPostConstructPropertiesParam();
+        serviceList.add(domainService);
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+        isfa.init();
+        assertThat(domainService.called,is(true));
+        assertThat(domainService.props.get("foo"), is("bar"));
+        isfa.shutdown();
+    }
+
+    @Test
+    public void preConstruct_DomainServiceWithValidPostConstructSubtypeOfPropertiesParam() {
+        DomainServiceWithValidPostConstructSubtypeOfPropertiesParam domainService = new DomainServiceWithValidPostConstructSubtypeOfPropertiesParam();
+        serviceList.add(domainService);
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+        isfa.init();
+        assertThat(domainService.called,is(true));
+        assertThat(domainService.props, is(not(nullValue())));
+        isfa.shutdown();
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void preConstruct_DomainServiceWithInvalidPostConstructWrongNumberParams() {
+        serviceList.add(new DomainServiceWithInvalidPostConstructWrongNumberParams());
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void preConstruct_DomainServiceWithInvalidPostConstructWrongTypeOfParam() {
+        serviceList.add(new DomainServiceWithInvalidPostConstructWrongTypeOfParam());
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+    }
+
+    @Test
+    public void preConstruct_DomainServiceWithValidPreDestroyNoParams() {
+        DomainServiceWithValidPreDestroyNoParams domainService = new DomainServiceWithValidPreDestroyNoParams();
+        serviceList.add(domainService);
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+        isfa.init();
+        assertThat(domainService.called,is(true));
+        isfa.shutdown();
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void preConstruct_DomainServiceWithInvalidPreDestroyWrongNumberParams() {
+        serviceList.add(new DomainServiceWithInvalidPreDestroyWrongNumberParams());
+        isfa = createIsisSessionFactoryAbstract(serviceList);
+    }
+
+
+    private IsisSessionFactoryAbstract createIsisSessionFactoryAbstract(List<Object> serviceList) {
+        return new IsisSessionFactoryAbstract(deploymentType, configuration, specificationLoader, templateImageLoader, authenticationManager, authorizationManager, userProfileLoader, persistenceSessionFactory, serviceList, oidMarshaller) {
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/ed11bc04/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
index 757952d..741a7c4 100644
--- a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
+++ b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
@@ -175,3 +175,6 @@ isis.services = objstore.jdo.todo.ToDoItemsJdo,\
 #isis.fixtures.prefix= 
 #isis.fixtures= 
 
+
+org.apache.isis.viewer.restfulobjects.rendering.eventserializer.RestfulObjectsSpecEventSerializer.baseUrl=http://localhost:8080/restful/
+