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 2014/11/13 18:12:40 UTC
[1/7] isis git commit: ISIS-948: refactoring the EventBusService (and
EventBusServiceDefault subclass) so that the guava EventBus is actually
instantiated only once, in effect with singleton scope,
rather than with request-scoped.
Repository: isis
Updated Branches:
refs/heads/master d15cec100 -> f436bcb12
ISIS-948: refactoring the EventBusService (and EventBusServiceDefault subclass) so that the guava EventBus is actually instantiated only once, in effect with singleton scope, rather than with request-scoped.
Although this design is not symmetrical (in the various @PostConstruct and @PreDestroy lifecycle methods), it has many fewer moving parts. Making the guava EventBus a singleton means that all events flow through this single instance. We rely on the proxies of the request-scoped services to dispatch to the appropriate instance on the thread (assuming that a transaction is running for that thread).
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/55fc862f
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/55fc862f
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/55fc862f
Branch: refs/heads/master
Commit: 55fc862fdeb2e743a9baa5279a32dd853c089790
Parents: d15cec1
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 12:15:56 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 12:15:56 2014 +0000
----------------------------------------------------------------------
.../services/eventbus/EventBusService.java | 222 ++++++++++++++++---
.../eventbus/EventBusServiceDefault.java | 42 +++-
.../eventbus/RequestScopedEventBus.java | 186 ----------------
.../service/eventbus/EventBusServiceJdo.java | 1 -
4 files changed, 221 insertions(+), 230 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/55fc862f/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
index 8325e8a..44287e7 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
@@ -16,11 +16,10 @@
*/
package org.apache.isis.applib.services.eventbus;
-import java.util.Map;
+import java.util.Collections;
import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import com.google.common.collect.MapMaker;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import org.apache.isis.applib.annotation.Hidden;
@@ -50,64 +49,145 @@ public abstract class EventBusService {
*/
public static class Noop extends EventBusService {
@Override
- public void register(Object domainObject) {}
+ public void register(Object domainService) {}
@Override
- public void unregister(Object domainObject) {}
+ public void unregister(Object domainService) {}
@Override
public void post(Object event) {}
@Override
protected EventBus getEventBus() {
return null;
}
+ @Override
+ protected EventBus newEventBus() { return null; }
}
public static final EventBusService NOOP = new Noop();
-
+
+ //region > init, shutdown
+
/**
- * @return an {@link EventBus} scoped to the current session.
+ * Cannot do the setup of the event bus here (so this is asymmetric with <code>@PreDestroy</code>) because there is
+ * no guarantee of the order in which <code>@PostConstruct</code> is called on any request-scoped services. We
+ * therefore allow all services (singleton or request-scoped) to {@link #register(Object) register} themselves
+ * with this service in their <code>@PostConstruct</code> and do the actual instantiation of the guava
+ * {@link com.google.common.eventbus.EventBus} and registering of subscribers lazily, in {@link #getEventBus()}.
+ * This lifecycle method ({@link #init()}) is therefore a no-op.
+ *
+ * <p>
+ * The guava {@link com.google.common.eventbus.EventBus} can however (and is) be torndown in the
+ * <code>@PreDestroy</code> {@link #shutdown()} lifecycle method.
+ * </p>
*/
@Programmatic
- protected abstract EventBus getEventBus();
+ @PostConstruct
+ public void init() {
+ // no-op
+ }
+
+ @Programmatic
+ @PreDestroy
+ public void shutdown() {
+ teardownEventBus();
+ }
+
+ //endregion
//region > register, unregister
+ /**
+ * Both singleton and request-scoped domain services can register on the event bus; this should be done in their
+ * <code>@PostConstruct</code> callback method.
+ *
+ * <p>
+ * <b>Important:</b> Request-scoped services should register their proxy, not themselves. This is because it is
+ * the responsibility of the proxy to ensure that the correct underlying (thread-local) instance of the service
+ * is delegated to. If the actual instance were to be registered, this would cause a memory leak and all sorts
+ * of other unexpected issues.
+ * </p>
+ *
+ * <p>
+ * Also, request-scoped services should <i>NOT</i> unregister themselves. This is because the
+ * <code>@PreDestroy</code> lifecycle method is called at the end of each transaction. The proxy needs to
+ * remain registered on behalf for any subsequent transactions.
+ * </p>
+ *
+ * <p>For example:</p>
+ * <pre>
+ * @RequestScoped @DomainService
+ * public class SomeSubscribingService {
+ *
+ * private EventBusService ebs;
+ * public void injectBus(EventBusService ebs) { this.ebs = ebs; }
+ *
+ * private SomeSubscribingService proxy;
+ * public void injectProxy(SomeSubscribingService proxy) { this.proxy = proxy; }
+ *
+ * @PostConstruct
+ * public void startRequest() {
+ * // register with bus
+ * ebs.register(proxy);
+ * }
+ * @PreDestroy
+ * public void endRequest() {
+ * //no-op
+ * }
+ * }
+ * </pre>
+ *
+ * <p>
+ * The <code>@PostConstruct</code> callback is the correct place to register for both singleton and
+ * request-scoped services. For singleton domain services, this is done during the initial bootstrapping of
+ * the system. For request-scoped services, this is done for the first transaction. In fact, because
+ * singleton domain services are initialized <i>within a current transaction</i>, the request-scoped services
+ * will actually be registered <i>before</i> the singleton services. Each subsequent transaction will have the
+ * request-scoped service re-register with the event bus, however the event bus stores its subscribers in a
+ * set and so these re-registrations are basically a no-op.
+ * </p>
+ *
+ * @param domainService
+ */
@Programmatic
- public void register(Object domainObject) {
- referenceCountBySubscriber.putIfAbsent(domainObject, new AtomicInteger(0));
- referenceCountBySubscriber.get(domainObject).incrementAndGet();
+ public void register(final Object domainService) {
+ if(eventBus != null) {
+ throw new IllegalStateException("Event bus has already been created; too late to register any further subscribers");
+ }
+ subscribers.add(domainService);
}
+ /**
+ * Notionally allows subscribers to unregister from the event bus; however this is a no-op.
+ *
+ * <p>
+ * It is safe for singleton services to unregister from the bus, however this is only ever called when the
+ * app is being shutdown so there is no real effect. For request-scoped services meanwhile that (as
+ * explained in {@link #register(Object)}'s documentation) actually register their proxy, it would be an error
+ * to unregister the proxy; subsequent transactions (for this thread or others) must be routed through that
+ * proxy.
+ * </p>
+ */
@Programmatic
- public void unregister(Object domainObject) {
- final AtomicInteger atomicInteger = referenceCountBySubscriber.get(domainObject);
- atomicInteger.decrementAndGet();
+ public void unregister(final Object domainService) {
+ // intentionally no-op
}
//endregion
//region > subscribers
- private final ConcurrentMap<Object, AtomicInteger> referenceCountBySubscriber = new MapMaker().weakKeys().makeMap();
+ private final Set<Object> subscribers = Sets.newConcurrentHashSet();
/**
- * Not API
+ * Returns an immutable snapshot of the current subscribers.
*/
@Programmatic
public Set<Object> getSubscribers() {
-
-
-
- // only those subscribers that are "active"
- Set<Object> subscribers = Sets.newLinkedHashSet();
- for (Map.Entry<Object, AtomicInteger> subscriberReferenceCount : this.referenceCountBySubscriber.entrySet()) {
- if(subscriberReferenceCount.getValue().get()>0) {
- subscribers.add(subscriberReferenceCount.getKey());
- }
- }
- return subscribers;
+ return Collections.unmodifiableSet(Sets.newLinkedHashSet(subscribers));
}
//endregion
-
+
+ //region > post
+
/**
* Post an event.
*/
@@ -119,10 +199,86 @@ public abstract class EventBusService {
getEventBus().post(event);
}
-
+ //endregion
+
+
+ //region > getEventBus
+
+ /**
+ * Lazily populated in {@link #getEventBus()}.
+ */
+ private EventBus eventBus;
+
+ /**
+ * Lazily populates the event bus for the current {@link #getSubscribers() subscribers}.
+ */
+ @Programmatic
+ protected EventBus getEventBus() {
+ setupEventBus();
+ return eventBus;
+ }
+
+ /**
+ * Set of subscribers registered with the event bus.
+ *
+ * <p>
+ * Lazily populated in {@link #setupEventBus()}.
+ * </p>
+ */
+ private Set<Object> registeredSubscribers;
+
+ /**
+ * Populates {@link #eventBus} with the {@link #registeredSubscribers currently registered subscribers}.
+ *
+ * <p>
+ * Guava event bus will throw an exception if attempt to unsubscribe any subscribers that were not subscribed.
+ * It is therefore the responsibility of this service to remember which services were registered
+ * at the start of the request, and to unregister precisely this same set of services at the end.
+ * </p>
+ *
+ * <p>
+ * That said, the Guava event bus is only ever instantiated once (it is in essence an application-scoped singleton),
+ * and so once created it is not possible for any subscribers to be registered. For this reason, the
+ * {@link #register(Object)} will throw an exception if any attempt is made to register once the event bus
+ * has been instantiated.
+ * </p>
+ */
+ protected void setupEventBus() {
+ if(eventBus != null) {
+ return;
+ }
+ this.eventBus = newEventBus();
+
+ registeredSubscribers = getSubscribers();
+
+ for (Object subscriber : this.registeredSubscribers) {
+ eventBus.register(subscriber);
+ }
+ }
+
+ protected void teardownEventBus() {
+ if(registeredSubscribers != null) {
+ for (Object subscriber : this.registeredSubscribers) {
+ eventBus.unregister(subscriber);
+ }
+ }
+
+ this.eventBus = null;
+ }
+
+ //endregion
+
+ //region > hook methods (newEventBus, skip)
+
+ /**
+ * Mandatory hook method for subclass to instantiate an appropriately configured Guava event bus.
+ */
+ protected abstract EventBus newEventBus();
+
+
/**
* A hook to allow subclass implementations to skip the publication of certain events.
- *
+ *
* <p>
* For example, the <tt>EventBusServiceJdo</tt> does not publish events if the method
* is called by JDO/DataNucleus infrastructure, eg during hydration or commits.
@@ -130,5 +286,9 @@ public abstract class EventBusService {
protected boolean skip(Object event) {
return false;
}
+
+ //endregion
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/55fc862f/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
index 3e5e5f9..8733456 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
@@ -16,10 +16,17 @@
*/
package org.apache.isis.core.runtime.services.eventbus;
-import javax.inject.Inject;
+import java.util.List;
+import com.google.common.base.Throwables;
import com.google.common.eventbus.EventBus;
-import org.apache.isis.applib.annotation.Programmatic;
+import com.google.common.eventbus.SubscriberExceptionContext;
+import com.google.common.eventbus.SubscriberExceptionHandler;
+import org.apache.isis.applib.NonRecoverableException;
+import org.apache.isis.applib.RecoverableException;
import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.core.commons.exceptions.IsisApplicationException;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
/**
* @deprecated - because <tt>EventBusServiceJdo</tt> is annotated as the default implementation.
@@ -27,22 +34,33 @@ import org.apache.isis.applib.services.eventbus.EventBusService;
@Deprecated
public class EventBusServiceDefault extends EventBusService {
- //region > API (getEventBus)
-
- @Programmatic
@Override
- protected EventBus getEventBus() {
- return requestScopedEventBus.getEventBus();
+ protected EventBus newEventBus() {
+ return new EventBus(newEventBusSubscriberExceptionHandler());
}
- //endregion
-
- //region > injected services
+ protected SubscriberExceptionHandler newEventBusSubscriberExceptionHandler() {
+ return new SubscriberExceptionHandler(){
+ @Override
+ public void handleException(Throwable exception, SubscriberExceptionContext context) {
+ final List<Throwable> causalChain = Throwables.getCausalChain(exception);
+ for (Throwable cause : causalChain) {
+ if(cause instanceof RecoverableException || cause instanceof NonRecoverableException) {
+ getTransactionManager().getTransaction().setAbortCause(new IsisApplicationException(exception));
+ return;
+ }
+ }
+ // otherwise simply ignore
+ }
+ };
+ }
- @Inject
- private RequestScopedEventBus requestScopedEventBus;
+ protected IsisTransactionManager getTransactionManager() {
+ return IsisContext.getTransactionManager();
+ }
//endregion
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/55fc862f/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/RequestScopedEventBus.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/RequestScopedEventBus.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/RequestScopedEventBus.java
deleted file mode 100644
index 39b12ba..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/RequestScopedEventBus.java
+++ /dev/null
@@ -1,186 +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.core.runtime.services.eventbus;
-
-import java.util.List;
-import java.util.Set;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.RequestScoped;
-import com.google.common.base.Throwables;
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.SubscriberExceptionContext;
-import com.google.common.eventbus.SubscriberExceptionHandler;
-import org.apache.isis.applib.NonRecoverableException;
-import org.apache.isis.applib.RecoverableException;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.core.commons.exceptions.IsisApplicationException;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
-
-
-/**
- * Manages a guava {@link com.google.common.eventbus.EventBus}, scoped and private to a given request.
- *
- * <p>
- * This involves obtaining the set of subscribers from the (owning, singleton) {@link org.apache.isis.applib.services.eventbus.EventBusService event bus service}
- * and registering/unregistering them with the guava event bus at the appropriate time.
- * </p>
- */
-@DomainService
-@RequestScoped
-public class RequestScopedEventBus {
-
- //region > startRequest, endRequest
-
- /**
- * Cannot do the setup of the event bus here (so this is asymmetric with <code>@PreDestroy</code>) because there is
- * no guarantee of the order in which <code>@PostConstruct</code> is called on any request-scoped services. We
- * therefore let the request-scoped services register themselves with (the owning, singleton)
- * {@link org.apache.isis.applib.services.eventbus.EventBusService} in their
- * <code>@PostConstruct</code> and do the actual instantiation of the guava {@link com.google.common.eventbus.EventBus}
- * and registering of subscribers lazily, in {@link #getEventBus()}. This lifecycle method ({@link #startRequest()})
- * is therefore a no-op.
- *
- * <p>
- * The guava {@link com.google.common.eventbus.EventBus} can however (and is) be torndown in the
- * <code>@PreDestroy</code> {@link #endRequest()} lifecycle method.
- * </p>
- */
- @Programmatic
- @PostConstruct
- public void startRequest() {
- // no-op
- }
-
- @Programmatic
- @PreDestroy
- public void endRequest() {
- teardownEventBus();
- }
-
- //endregion
-
- //region > (guava) event bus
-
- /**
- * Lazily populated in {@link #getEventBus()}.
- */
- private EventBus eventBus;
-
- /**
- * Lazily populates the event bus and captures the set of subscribers from
- * {@link EventBusServiceDefault#getSubscribers()}}.
- *
- * <p>
- * These are torn down when the {@link #endRequest() request ends}.
- * </p>
- */
- @Programmatic
- public EventBus getEventBus() {
- setupEventBus();
- return eventBus;
- }
-
- /**
- * Set of subscribers registered with the event bus.
- *
- * <p>
- * Lazily populated in {@link #setupEventBus()}.
- * </p>
- */
- private Set<Object> subscribers;
-
- /**
- * Populates {@link #eventBus} and {@link #subscribers}.
- *
- * <p>
- * Guava event bus will throw an exception if attempt to unsubscribe any subscribers that were not subscribed.
- * It is therefore the responsibility of this (wrapper) service to remember which services were registered
- * at the start of the request, and to unregister precisely this same set of services at the end.
- * </p>
- */
- protected void setupEventBus() {
- if(eventBus != null) {
- return;
- }
- this.eventBus = newEventBus();
-
- // "pulls" subscribers from the (singleton) event bus service
- subscribers = eventBusService.getSubscribers();
-
- for (Object subscriber : this.subscribers) {
- eventBus.register(subscriber);
- }
- }
-
- protected void teardownEventBus() {
- if(subscribers != null) {
- for (Object subscriber : this.subscribers) {
- eventBus.unregister(subscriber);
- }
- }
-
- this.eventBus = null;
- }
-
- protected EventBus newEventBus() {
- return new EventBus(newEventBusSubscriberExceptionHandler());
- }
-
- protected SubscriberExceptionHandler newEventBusSubscriberExceptionHandler() {
- return new SubscriberExceptionHandler(){
- @Override
- public void handleException(Throwable exception, SubscriberExceptionContext context) {
- final List<Throwable> causalChain = Throwables.getCausalChain(exception);
- for (Throwable cause : causalChain) {
- if(cause instanceof RecoverableException || cause instanceof NonRecoverableException) {
- getTransactionManager().getTransaction().setAbortCause(new IsisApplicationException(exception));
- return;
- }
- }
- // otherwise simply ignore
- }
- };
- }
-
- protected IsisTransactionManager getTransactionManager() {
- return IsisContext.getTransactionManager();
- }
-
- //endregion
-
- //region > injected services
- private EventBusServiceDefault eventBusService;
- /**
- * Singleton holding the list of subscribers.
- *
- * <p>
- * Must use an <code>injectXxx</code> method because Isis does not (currently) support field injection into
- * request-scoped services (the javassist proxy does not delegate on).
- * </p>
- */
- @Programmatic
- public void injectEventBusService(EventBusServiceDefault eventBusService) {
- this.eventBusService = eventBusService;
- }
-
- //endregion
-
-}
-
http://git-wip-us.apache.org/repos/asf/isis/blob/55fc862f/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
index ba59510..a7f4c64 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
@@ -38,7 +38,6 @@ import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis.Hint;
@DomainService
public class EventBusServiceJdo extends EventBusServiceDefault {
-
/**
* skip if called in any way by way of the {@link JDOStateManagerForIsis}.
*
[3/7] isis git commit: ISIS-537: updates to javadoc only,
Posted by da...@apache.org.
ISIS-537: updates to javadoc only,
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/3f918025
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/3f918025
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/3f918025
Branch: refs/heads/master
Commit: 3f918025a3fdae1a13692ed06123091a941354cc
Parents: c8485ac
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 13:46:39 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 13:46:39 2014 +0000
----------------------------------------------------------------------
.../viewer/wicket/model/common/OnConcurrencyExceptionHandler.java | 3 ++-
.../isis/viewer/wicket/model/common/OnSelectionHandler.java | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/3f918025/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java
index 6b11659..71b1e71 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnConcurrencyExceptionHandler.java
@@ -26,7 +26,8 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
/**
- * Decouples the mechanism for selecting entities returned in collections.
+ * Decouples the handling of concurrency exceptions when a bulk action is invoked (between the toggle box column and the
+ * standalone collection panel).
*/
public interface OnConcurrencyExceptionHandler extends Serializable {
http://git-wip-us.apache.org/repos/asf/isis/blob/3f918025/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
index 17e1d4d..491c144 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/common/OnSelectionHandler.java
@@ -25,7 +25,8 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
/**
- * Decouples the mechanism for selecting entities returned in collections.
+ * Decouples the selecting of items (by a toggle box column) from the invocation of bulk actions on those items (by
+ * the standalone collection panel).
*/
public interface OnSelectionHandler extends Serializable {
[2/7] isis git commit: ISIS-948: adding validation to
EventBusService#register method (in EventBusServiceDefault subclass, in fact);
improvements to javadoc.
Posted by da...@apache.org.
ISIS-948: adding validation to EventBusService#register method (in EventBusServiceDefault subclass, in fact); improvements to javadoc.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/c8485acd
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/c8485acd
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/c8485acd
Branch: refs/heads/master
Commit: c8485acd75522815529826393d7daa8d1823de4e
Parents: 55fc862
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 12:38:30 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 12:38:30 2014 +0000
----------------------------------------------------------------------
.../services/eventbus/EventBusService.java | 21 ++++++-----
.../eventbus/EventBusServiceDefault.java | 37 +++++++++++++++++++-
2 files changed, 48 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/c8485acd/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
index 44287e7..8a994a1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
@@ -33,6 +33,7 @@ import org.apache.isis.applib.annotation.Programmatic;
* Only domain services (not domain entities or view models) should be registered; only they are guaranteed to be
* instantiated and resident in memory.
* </p>
+ *
* <p>
* It <i>is</i> possible to register request-scoped services, however they should register their proxy
* rather than themselves. This ensures that the actual subscribers are all singletons. This implementation uses
@@ -117,11 +118,8 @@ public abstract class EventBusService {
* @RequestScoped @DomainService
* public class SomeSubscribingService {
*
- * private EventBusService ebs;
- * public void injectBus(EventBusService ebs) { this.ebs = ebs; }
- *
- * private SomeSubscribingService proxy;
- * public void injectProxy(SomeSubscribingService proxy) { this.proxy = proxy; }
+ * @Inject private EventBusService ebs;
+ * @Inject private SomeSubscribingService proxy;
*
* @PostConstruct
* public void startRequest() {
@@ -149,9 +147,14 @@ public abstract class EventBusService {
*/
@Programmatic
public void register(final Object domainService) {
- if(eventBus != null) {
- throw new IllegalStateException("Event bus has already been created; too late to register any further subscribers");
- }
+ doRegister(domainService);
+ }
+
+ /**
+ * Extracted out only to make it easier for subclasses to override {@link #register(Object)} if there were ever a
+ * need to.
+ */
+ protected void doRegister(Object domainService) {
subscribers.add(domainService);
}
@@ -207,7 +210,7 @@ public abstract class EventBusService {
/**
* Lazily populated in {@link #getEventBus()}.
*/
- private EventBus eventBus;
+ protected EventBus eventBus;
/**
* Lazily populates the event bus for the current {@link #getSubscribers() subscribers}.
http://git-wip-us.apache.org/repos/asf/isis/blob/c8485acd/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
index 8733456..cd3626c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
@@ -17,6 +17,7 @@
package org.apache.isis.core.runtime.services.eventbus;
import java.util.List;
+import javax.enterprise.context.RequestScoped;
import com.google.common.base.Throwables;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.SubscriberExceptionContext;
@@ -25,15 +26,49 @@ import org.apache.isis.applib.NonRecoverableException;
import org.apache.isis.applib.RecoverableException;
import org.apache.isis.applib.services.eventbus.EventBusService;
import org.apache.isis.core.commons.exceptions.IsisApplicationException;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.runtime.services.RequestScopedService;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
/**
- * @deprecated - because <tt>EventBusServiceJdo</tt> is annotated as the default implementation.
+ * @deprecated - but only because {@link org.apache.isis.objectstore.jdo.datanucleus.service.eventbus.EventBusServiceJdo}
+ * is annotated (with <code>@DomainService</code>) as the default implementation. The functionality in this implementation
+ * is still required.
*/
@Deprecated
public class EventBusServiceDefault extends EventBusService {
+ /**
+ * {@inheritDoc}
+ *
+ * This service overrides the method to perform additional validation that (a) request-scoped services register
+ * their proxies, not themselves, and (b) that singleton services are never registered after the event bus has
+ * been created.
+ *
+ * <p>
+ * Note that we <i>do</i> allow for request-scoped services to register (their proxies) multiple times, ie at
+ * the beginning of each transaction. Because the subscribers are stored in a set, these additional
+ * registrations are in effect ignored.
+ * </p>
+ */
+ @Override
+ public void register(final Object domainService) {
+ if(domainService instanceof RequestScopedService) {
+ // ok; allow to be registered multiple times (each xactn) since stored in a set.
+ } else {
+ if (Annotations.getAnnotation(domainService.getClass(), RequestScoped.class) != null) {
+ throw new IllegalArgumentException("Request-scoped services must register their proxy, not themselves");
+ }
+ // a singleton
+ if(eventBus != null) {
+ // ... coming too late to the party.
+ throw new IllegalStateException("Event bus has already been created; too late to register any further (singleton) subscribers");
+ }
+ }
+ super.register(domainService);
+ }
+
@Override
protected EventBus newEventBus() {
return new EventBus(newEventBusSubscriberExceptionHandler());
[6/7] isis git commit: ISIS-928: removing very old commented out code
in JavassistImposteriser.
Posted by da...@apache.org.
ISIS-928: removing very old commented out code in JavassistImposteriser.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/ad8e6b88
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/ad8e6b88
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/ad8e6b88
Branch: refs/heads/master
Commit: ad8e6b8838571791c16b5551f78a78718449a929
Parents: 235c18f
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 14:25:18 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 14:25:18 2014 +0000
----------------------------------------------------------------------
.../jmocking/JavassistImposteriser.java | 67 --------------------
1 file changed, 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/ad8e6b88/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jmocking/JavassistImposteriser.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jmocking/JavassistImposteriser.java b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jmocking/JavassistImposteriser.java
index df56eb5..fdeb449 100644
--- a/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jmocking/JavassistImposteriser.java
+++ b/core/unittestsupport/src/main/java/org/apache/isis/core/unittestsupport/jmocking/JavassistImposteriser.java
@@ -110,61 +110,9 @@ public class JavassistImposteriser implements Imposteriser {
proxyFactory.setInterfaces(ancilliaryTypes);
return proxyFactory.createClass();
-
- // original cglib code:
-
- // final Enhancer enhancer = new Enhancer() {
- // @Override
- // @SuppressWarnings("unchecked")
- // protected void filterConstructors(Class sc, List constructors) {
- // // Don't filter
- // }
- // };
- // enhancer.setClassLoader(SearchingClassLoader.combineLoadersOf(mockedType, ancilliaryTypes));
- // enhancer.setUseFactory(true);
- // if (mockedType.isInterface()) {
- // enhancer.setSuperclass(Object.class);
- // enhancer.setInterfaces(prepend(mockedType, ancilliaryTypes));
- // }
- // else {
- // enhancer.setSuperclass(mockedType);
- // enhancer.setInterfaces(ancilliaryTypes);
- // }
- // enhancer.setCallbackTypes(new Class[]{InvocationHandler.class, NoOp.class});
- // enhancer.setCallbackFilter(IGNORE_BRIDGE_METHODS);
- // if (mockedType.getSigners() != null) {
- // enhancer.setNamingPolicy(NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES);
- // }
- //
- // try {
- // return enhancer.createClass();
- // }
- // catch (CodeGenerationException e) {
- // // Note: I've only been able to manually test this. It exists to help people writing
- // // Eclipse plug-ins or using other environments that have sophisticated class loader
- // // structures.
- // throw new IllegalArgumentException("could not imposterise " + mockedType, e);
- // }
-
}
- // original cglib code:
-
- // private static final NamingPolicy NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES = new DefaultNamingPolicy() {
- // @Override
- // public String getClassName(String prefix, String source, Object key, Predicate names) {
- // return "org.jmock.codegen." + super.getClassName(prefix, source, key, names);
- // }
- // };
- //
- // private static final CallbackFilter IGNORE_BRIDGE_METHODS = new CallbackFilter() {
- // public int accept(Method method) {
- // return method.isBridge() ? 1 : 0;
- // }
- // };
-
-
private Object proxy(Class<?> proxyClass, final Invokable mockObject) {
final ProxyObject proxyObject = (ProxyObject) objenesis.newInstance(proxyClass);
@@ -176,19 +124,6 @@ public class JavassistImposteriser implements Imposteriser {
});
return proxyObject;
-
- // original cglib code:
-
- // final Factory proxy = (Factory)objenesis.newInstance(proxyClass);
- // proxy.setCallbacks(new Callback[] {
- // new InvocationHandler() {
- // public Object invoke(Object receiver, Method method, Object[] args) throws Throwable {
- // return mockObject.invoke(new Invocation(receiver, method, args));
- // }
- // },
- // NoOp.INSTANCE
- // });
- // return proxy;
}
private static Class<?>[] combine(Class<?> first, Class<?>... rest) {
@@ -197,6 +132,4 @@ public class JavassistImposteriser implements Imposteriser {
System.arraycopy(rest, 0, all, 1, rest.length);
return all;
}
-
- //public static class ClassWithSuperclassToWorkAroundCglibBug {}
}
[4/7] isis git commit: ISIS-537: removing unused/no-op code.
Posted by da...@apache.org.
ISIS-537: removing unused/no-op code.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/41a723d9
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/41a723d9
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/41a723d9
Branch: refs/heads/master
Commit: 41a723d909f60c5f72d21ad56b0c2b639ee1abea
Parents: 3f91802
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 13:47:58 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 13:47:58 2014 +0000
----------------------------------------------------------------------
.../multiple/CollectionContentsMultipleViewsPanel.java | 8 --------
1 file changed, 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/41a723d9/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
index 9e60554..a6d5d9a 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
@@ -109,12 +109,6 @@ public class CollectionContentsMultipleViewsPanel
this.addOrReplace(underlyingView);
}
- if(selectorDropdownPanelIfAny != null) {
-
- } else {
-
- }
-
// hide any unused placeholders
while(i<MAX_NUM_UNDERLYING_VIEWS) {
String underlyingId = underlyingIdPrefix + "-" + i;
@@ -189,8 +183,6 @@ public class CollectionContentsMultipleViewsPanel
// ignore
}
}
-
-
}
[5/7] isis git commit: ISIS-537: fixing a bug with
ModelAbstract#clearHint, adding a unit test to cover.
Posted by da...@apache.org.
ISIS-537: fixing a bug with ModelAbstract#clearHint, adding a unit test to cover.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/235c18f7
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/235c18f7
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/235c18f7
Branch: refs/heads/master
Commit: 235c18f701143e96ed385216619525b1798bf20e
Parents: 41a723d
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 14:23:39 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 14:23:39 2014 +0000
----------------------------------------------------------------------
component/viewer/wicket/model/pom.xml | 5 +
.../wicket/model/models/ModelAbstract.java | 8 +-
.../wicket/model/models/ModelAbstractTest.java | 170 +++++++++++++++++++
3 files changed, 177 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/235c18f7/component/viewer/wicket/model/pom.xml
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/pom.xml b/component/viewer/wicket/model/pom.xml
index d631017..f954ad5 100644
--- a/component/viewer/wicket/model/pom.xml
+++ b/component/viewer/wicket/model/pom.xml
@@ -65,6 +65,11 @@
<groupId>org.apache.isis.core</groupId>
<artifactId>isis-core-runtime</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-unittestsupport</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/isis/blob/235c18f7/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
index 8e65177..1ae3735 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
@@ -73,17 +73,13 @@ public abstract class ModelAbstract<T> extends LoadableDetachableModel<T> implem
if(value != null) {
hints.put(hintKey, value);
} else {
- clearHint(component, hintKey);
+ hints.remove(hintKey);
}
}
@Override
public void clearHint(Component component, String key) {
- if(component == null) {
- return;
- }
- String hintKey = hintKey(component, key);
- hints.remove(hintKey);
+ setHint(component, key, null);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/235c18f7/component/viewer/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java b/component/viewer/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java
new file mode 100644
index 0000000..4655239
--- /dev/null
+++ b/component/viewer/wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java
@@ -0,0 +1,170 @@
+/**
+ * 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.model.models;
+
+import java.util.Map;
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.jmock.Expectations;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.viewer.wicket.model.hints.UiHintPathSignificant;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class ModelAbstractTest {
+
+ @Rule
+ public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
+
+ ModelAbstract<String> target;
+
+ static class UiHintPathSignificantComponent extends Component implements UiHintPathSignificant {
+ public UiHintPathSignificantComponent(String id) {
+ super(id);
+ }
+
+ public UiHintPathSignificantComponent(String id, IModel<?> model) {
+ super(id, model);
+ }
+
+ @Override
+ protected void onRender() {
+ }
+ }
+
+ static class UiHintPathSignificantMarkupContainer extends MarkupContainer implements UiHintPathSignificant {
+ public UiHintPathSignificantMarkupContainer(String id) {
+ super(id);
+ }
+
+ public UiHintPathSignificantMarkupContainer(String id, IModel<?> model) {
+ super(id, model);
+ }
+
+ @Override
+ protected void onRender() {
+ }
+ }
+
+ MarkupContainer mockParent;
+ Component mockComponent1;
+ Component mockComponent2;
+
+ @Before
+ public void setUp() throws Exception {
+ target = new ModelAbstract<String>("foo"){
+ @Override
+ protected String load() {
+ return null;
+ }
+ };
+
+ mockParent = context.mock(UiHintPathSignificantMarkupContainer.class, "parent");
+ mockComponent1 = context.mock(UiHintPathSignificantComponent.class, "component1");
+ mockComponent2 = context.mock(UiHintPathSignificantComponent.class, "component2");
+
+ context.checking(new Expectations() {{
+ allowing(mockParent).getId();
+ will(returnValue("parent"));
+
+ allowing(mockComponent1).getId();
+ will(returnValue("id1"));
+
+ allowing(mockComponent2).getId();
+ will(returnValue("id2"));
+
+ ignoring(mockComponent1);
+ ignoring(mockComponent2);
+
+ }});
+
+ mockComponent1.setParent(mockParent);
+ mockComponent2.setParent(mockParent);
+ }
+
+ public static class Hints extends ModelAbstractTest {
+
+ @Test
+ public void empty() throws Exception {
+ assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
+ }
+
+ @Test
+ public void single() throws Exception {
+ target.setHint(mockComponent1, "key1", "value1");
+ assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+ }
+
+ @Test
+ public void clear() throws Exception {
+ target.setHint(mockComponent1, "key1", "value1");
+ assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+ target.clearHint(mockComponent1, "key1");
+ assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
+ }
+
+ @Test
+ public void setToNull() throws Exception {
+ target.setHint(mockComponent1, "key1", "value1");
+ assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+ target.setHint(mockComponent1, "key1", null);
+ assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
+ }
+
+ @Test
+ public void multipleKeys() throws Exception {
+ target.setHint(mockComponent1, "key1", "value1");
+ target.setHint(mockComponent1, "key2", "value2");
+ assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+ assertThat(target.getHint(mockComponent1, "key2"), is("value2"));
+ }
+
+ @Test
+ public void multipleComponents() throws Exception {
+ target.setHint(mockComponent1, "key", "valueA");
+ target.setHint(mockComponent2, "key", "valueB");
+ assertThat(target.getHint(mockComponent1, "key"), is("valueA"));
+ assertThat(target.getHint(mockComponent2, "key"), is("valueB"));
+ }
+
+ @Test
+ public void smoke() throws Exception {
+ target.setHint(mockComponent1, "X", "1.X");
+ target.setHint(mockComponent1, "A", "1.A");
+ target.setHint(mockComponent1, "B", "1.B");
+ target.setHint(mockComponent1, "C", "1.C");
+ target.setHint(mockComponent2, "X", "2.X");
+ target.setHint(mockComponent2, "P", "2.P");
+ target.setHint(mockComponent2, "Q", "2.Q");
+ target.setHint(mockComponent2, "R", "2.R");
+
+ final Map<String, String> hints = target.getHints();
+ assertThat(hints.size(), is(8));
+ assertThat(hints.get("id1-X"), is("1.X"));
+ assertThat(hints.get("id2-X"), is("2.X"));
+ assertThat(hints.get("id1-B"), is("1.B"));
+ assertThat(hints.get("id2-R"), is("2.R"));
+ }
+ }
+
+}
\ No newline at end of file
[7/7] isis git commit: ISIS-951: introducing menu separators;
also getting rid of the btn-warning for prototype, using subtler
italics instead.
Posted by da...@apache.org.
ISIS-951: introducing menu separators; also getting rid of the btn-warning for prototype, using subtler italics instead.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f436bcb1
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f436bcb1
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f436bcb1
Branch: refs/heads/master
Commit: f436bcb124830b3d94063ebdbb221c6ecb786d11
Parents: ad8e6b8
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 16:25:23 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 16:25:23 2014 +0000
----------------------------------------------------------------------
.../cssmenu/AppActionsCssMenuFactory.java | 11 ++-
.../cssmenu/ApplicationActionsPanel.html | 6 +-
.../cssmenu/ApplicationActionsPanel.java | 81 ++++++++++++++------
.../widgets/cssmenu/CssMenuBuilder.java | 2 +-
.../components/widgets/cssmenu/CssMenuItem.java | 38 ++++++---
.../widgets/cssmenu/CssMenuItemPanel.html | 2 +-
.../widgets/cssmenu/CssMenuPanel.java | 19 +----
.../widgets/cssmenu/CssSubMenuItemsPanel.html | 2 +-
.../wicket/ui/pages/bootstrap-overrides.css | 17 ++++
.../exceprecog/ExceptionRecognizer.java | 5 +-
.../exceprecog/ExceptionRecognizer2.java | 3 +
.../ExceptionRecognizerComposite.java | 6 ++
12 files changed, 133 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
index 12d544c..3d9e8ba 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
@@ -61,7 +61,8 @@ public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {
private final ObjectAdapter serviceAdapter;
private final ObjectAdapterMemento serviceAdapterMemento;
private final ObjectAction objectAction;
-
+ public boolean separator;
+
LogicalServiceAction(final String serviceName, final ObjectAdapter serviceAdapter, final ObjectAction objectAction) {
this.serviceName = serviceName;
this.serviceAdapter = serviceAdapter;
@@ -133,7 +134,8 @@ public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {
}
final ObjectAdapterMemento serviceAdapterMemento = logicalServiceAction.serviceAdapterMemento;
final ObjectAction objectAction = logicalServiceAction.objectAction;
- final Builder subMenuItemBuilder = serviceMenuItem.newSubMenuItem(serviceAdapterMemento, objectAction, cssMenuContext);
+ final boolean separator = logicalServiceAction.separator;
+ final Builder subMenuItemBuilder = serviceMenuItem.newSubMenuItem(serviceAdapterMemento, objectAction, separator, cssMenuContext);
if (subMenuItemBuilder == null) {
// not visible
continue;
@@ -201,13 +203,18 @@ public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {
final Map<String, List<LogicalServiceAction>> serviceActionsByName = Maps.newTreeMap();
// map available services
+ ObjectAdapter lastServiceAdapter = null;
for (LogicalServiceAction serviceAction : serviceActions) {
List<LogicalServiceAction> serviceActionsForName = serviceActionsByName.get(serviceAction.serviceName);
if(serviceActionsForName == null) {
serviceActionsForName = Lists.newArrayList();
serviceActionsByName.put(serviceAction.serviceName, serviceActionsForName);
+ } else {
+ // capture whether this action is from a different service
+ serviceAction.separator = lastServiceAdapter != serviceAction.serviceAdapter;
}
serviceActionsForName.add(serviceAction);
+ lastServiceAdapter = serviceAction.serviceAdapter;
}
return serviceActionsByName;
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
index 0a37c74..0562067 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
@@ -13,7 +13,7 @@
<wicket:fragment wicket:id="leafItem">
<a class="menuLink" wicket:id="menuLink">
- <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span> <span wicket:id="menuLinkLabel"></span>
+ <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span> <span class="menuLinkLabel" wicket:id="menuLinkLabel"></span>
</a>
</wicket:fragment>
@@ -26,6 +26,10 @@
</ul>
</wicket:fragment>
+ <wicket:fragment wicket:id="empty">
+ </wicket:fragment>
+
+
</wicket:panel>
</body>
</html>
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
index fa6f4be..48b34d4 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
@@ -6,6 +6,7 @@ import de.agilecoders.wicket.extensions.markup.html.bootstrap.button.DropdownAut
import java.util.List;
import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
@@ -49,7 +50,7 @@ public class ApplicationActionsPanel extends Panel {
CssMenuItem menuItem = listItem.getModelObject();
listItem.add(new Label("name", menuItem.getName()));
- List<CssMenuItem> subMenuItems = menuItem.getSubMenuItems();
+ List<CssMenuItem> subMenuItems = withSeparators(menuItem);
// fake data to test multi-level menus
@@ -88,7 +89,9 @@ public class ApplicationActionsPanel extends Panel {
listItem.add(folderItem);
folderItem.add(new Label("folderName", subMenuItem.getName()));
- ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems", subMenuItem.getSubMenuItems()) {
+ final List<CssMenuItem> menuItems = withSeparators(subMenuItem);
+ ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems",
+ menuItems) {
@Override
protected void populateItem(ListItem<CssMenuItem> listItem) {
CssMenuItem subMenuItem = listItem.getModelObject();
@@ -103,35 +106,63 @@ public class ApplicationActionsPanel extends Panel {
folderItem.add(subMenuItemsView);
}
- private void addLeafItem(CssMenuItem menuItem, ListItem<CssMenuItem> listItem) {
- Fragment leafItem = new Fragment("content", "leafItem", ApplicationActionsPanel.this);
+ private List<CssMenuItem> withSeparators(CssMenuItem subMenuItem) {
+ final List<CssMenuItem> subMenuItems = subMenuItem.getSubMenuItems();
+ final List<CssMenuItem> itemsWithSeparators = Lists.newArrayList();
+ for (CssMenuItem menuItem : subMenuItems) {
+ if(menuItem.isSeparator()) {
+ // nasty...
+ // ... we add it twice, but mutate it along the way
+ itemsWithSeparators.add(
+ CssMenuItem.newMenuItem(menuItem.getName() + "-separator")
+ .separator(menuItem.isSeparator())
+ .prototyping(menuItem.isPrototyping())
+ .build());
+ menuItem.setSeparator(false);
+ }
+ itemsWithSeparators.add(menuItem);
+ }
+ return itemsWithSeparators;
+ }
- AbstractLink subMenuItemLink = menuItem.getLink();
+ private void addLeafItem(
+ final CssMenuItem menuItem,
+ final ListItem<CssMenuItem> listItem) {
- Label menuItemLabel = new Label("menuLinkLabel", menuItem.getName());
- subMenuItemLink.addOrReplace(menuItemLabel);
+ Fragment leafItem;
+ if (!menuItem.isSeparator()) {
+ leafItem = new Fragment("content", "leafItem", ApplicationActionsPanel.this);
- if (!menuItem.isEnabled()) {
- listItem.add(new CssClassNameAppender("disabled"));
- subMenuItemLink.setEnabled(false);
- TooltipBehavior tooltipBehavior = new TooltipBehavior(Model.of(menuItem.getDisabledReason()));
- listItem.add(tooltipBehavior);
- }
- if (menuItem.isPrototyping()) {
- subMenuItemLink.add(new CssClassNameAppender("btn btn-warning"));
- }
- leafItem.add(subMenuItemLink);
- listItem.add(leafItem);
+ AbstractLink subMenuItemLink = menuItem.getLink();
- String cssClassFa = menuItem.getCssClassFa();
- if (Strings.isNullOrEmpty(cssClassFa)) {
- Components.permanentlyHide(subMenuItemLink, "menuLinkFontAwesome");
- subMenuItemLink.add(new CssClassAppender("menuLinkSpacer"));
+ Label menuItemLabel = new Label("menuLinkLabel", menuItem.getName());
+ subMenuItemLink.addOrReplace(menuItemLabel);
+
+ if (!menuItem.isEnabled()) {
+ listItem.add(new CssClassNameAppender("disabled"));
+ subMenuItemLink.setEnabled(false);
+ TooltipBehavior tooltipBehavior = new TooltipBehavior(Model.of(menuItem.getDisabledReason()));
+ listItem.add(tooltipBehavior);
+ }
+ if (menuItem.isPrototyping()) {
+ subMenuItemLink.add(new CssClassNameAppender("prototype"));
+ }
+ leafItem.add(subMenuItemLink);
+
+ String cssClassFa = menuItem.getCssClassFa();
+ if (Strings.isNullOrEmpty(cssClassFa)) {
+ Components.permanentlyHide(subMenuItemLink, "menuLinkFontAwesome");
+ subMenuItemLink.add(new CssClassAppender("menuLinkSpacer"));
+ } else {
+ Label dummy = new Label("menuLinkFontAwesome", "");
+ dummy.add(new CssClassAppender(cssClassFa));
+ subMenuItemLink.addOrReplace(dummy);
+ }
} else {
- Label dummy = new Label("menuLinkFontAwesome", "");
- dummy.add(new CssClassAppender(cssClassFa));
- subMenuItemLink.addOrReplace(dummy);
+ leafItem = new Fragment("content", "empty", ApplicationActionsPanel.this);
+ listItem.add(new CssClassNameAppender("divider"));
}
+ listItem.add(leafItem);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
index 6b9189f..0b12d23 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
@@ -160,7 +160,7 @@ public class CssMenuBuilder {
final ObjectAdapterMemento targetAdapterMemento = adapterMemento; // determineAdapterFor(action);
if(targetAdapterMemento != null) {
// against an entity or a service (if a contributed action)
- subMenuItemBuilder = parent.newSubMenuItem(targetAdapterMemento, action, cssMenuContext);
+ subMenuItemBuilder = parent.newSubMenuItem(targetAdapterMemento, action, false, cssMenuContext);
} else {
if (action.containsDoOpFacet(BulkFacet.class)) {
// ignore fact have no target action;
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
index bfbb539..05b0184 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
@@ -104,20 +104,16 @@ public class CssMenuItem implements Serializable {
return this;
}
- /**
- * Access the {@link CssMenuItem} before it is attached to its parent.
- *
- * @see #build()
- */
- public CssMenuItem itemBeingBuilt() {
- return cssMenuItem;
- }
-
public Builder prototyping(boolean prototype) {
cssMenuItem.setPrototyping(prototype);
return this;
}
+ public Builder separator(boolean separator) {
+ cssMenuItem.setSeparator(separator);
+ return this;
+ }
+
public Builder withActionIdentifier(String actionIdentifier) {
cssMenuItem.setActionIdentifier(actionIdentifier);
return this;
@@ -169,6 +165,7 @@ public class CssMenuItem implements Serializable {
private String disabledReason;
private boolean blobOrClob = false; // unless set otherwise
private boolean prototype = false; // unless set otherwise
+ private boolean separator = false; // unless set otherwise
static final String ID_MENU_LABEL = "menuLabel";
@@ -202,6 +199,18 @@ public class CssMenuItem implements Serializable {
return prototype;
}
+ public void setSeparator(boolean separator) {
+ this.separator = separator;
+ }
+
+ /**
+ * Requires a separator before it
+ * @return
+ */
+ public boolean isSeparator() {
+ return separator;
+ }
+
private CssMenuItem(final String name) {
this.name = name;
}
@@ -292,6 +301,7 @@ public class CssMenuItem implements Serializable {
public Builder newSubMenuItem(
final ObjectAdapterMemento targetAdapterMemento,
final ObjectAction objectAction,
+ final boolean separator,
final CssMenuBuilder.CssMenuContext cssMenuContext) {
// check visibility
@@ -325,6 +335,7 @@ public class CssMenuItem implements Serializable {
.enabled(reasonDisabledIfAny)
.returnsBlobOrClob(returnsBlobOrClob(objectAction))
.prototyping(isExplorationOrPrototype(objectAction))
+ .separator(separator)
.withActionIdentifier(actionIdentifierFor(objectAction))
.withCssClass(cssClassFor(objectAction))
.withCssClassFa(cssClassFaFor(objectAction));
@@ -388,8 +399,8 @@ public class CssMenuItem implements Serializable {
final String actionLabel = linkAndLabel.getLabel();
Builder builder = this.newSubMenuItem(actionLabel)
.link(link)
- .prototyping(linkAndLabel.isPrototype())
- .returnsBlobOrClob(linkAndLabel.isBlobOrClob())
+ .prototyping(linkAndLabel.isPrototype())
+ .returnsBlobOrClob(linkAndLabel.isBlobOrClob())
.withFacet(objectAction.getFacet(CssClassFacet.class))
.withFacet(objectAction.getFacet(CssClassFaFacet.class));
return builder;
@@ -423,10 +434,13 @@ public class CssMenuItem implements Serializable {
link.add(new CssClassAppender("noVeil"));
}
if(this.prototype) {
- link.add(new CssClassAppender("btn-warning"));
+ link.add(new CssClassAppender("prototype"));
+ link.add(new CssClassAppender("btn-default"));
} else {
link.add(new CssClassAppender("btn-default"));
}
+
+
if(this.cssClass != null) {
link.add(new CssClassAppender(this.cssClass));
}
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
index 1d65257..7d80c8e 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
@@ -23,7 +23,7 @@
<li class="cssMenuItemPanel">
<a wicket:id="menuLink" class="btn">
<span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span>
- <span wicket:id="menuLabel">[menu label]</span>
+ <span class="menuLabel" wicket:id="menuLabel">[menu label]</span>
</a>
<p wicket:id="menuLabel">[menu label]</p>
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
index 9181e76..ad0c75a 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
@@ -19,7 +19,6 @@
package org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu;
-import java.util.Arrays;
import java.util.List;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -27,7 +26,6 @@ import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.util.ListModel;
import org.apache.isis.core.commons.lang.StringExtensions;
import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
@@ -39,7 +37,7 @@ import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
* <p>
* The {@link Style} enum allows the presentation to be altered.
*/
-public class CssMenuPanel extends PanelAbstract<CssMenuPanel.MyModel> {
+public class CssMenuPanel extends PanelAbstract<CssMenuPanel.ListOfCssMenuItemsModel> {
private static final long serialVersionUID = 1L;
@@ -66,26 +64,21 @@ public class CssMenuPanel extends PanelAbstract<CssMenuPanel.MyModel> {
}
}
- static class MyModel extends ListModel<CssMenuItem> {
+ static class ListOfCssMenuItemsModel extends ListModel<CssMenuItem> {
private static final long serialVersionUID = 1L;
- public MyModel(final List<CssMenuItem> cssMenuItems) {
+ public ListOfCssMenuItemsModel(final List<CssMenuItem> cssMenuItems) {
super(cssMenuItems);
}
}
- public static CssMenuItem.Builder newMenuItem(final String name) {
- return CssMenuItem.newMenuItem(name);
- }
-
private final StyleAppender styleAppender;
static final String ID_MENU_ITEMS = "menuItems";
- static final String ID_MENU_ITEM_FONT_AWESOME = "menuItemFontAwesome";
static final String ID_MENU_ITEM = "menuItem";
public CssMenuPanel(final String id, final Style style, final List<CssMenuItem> topLevelMenuItems) {
- super(id, new MyModel(topLevelMenuItems));
+ super(id, new ListOfCssMenuItemsModel(topLevelMenuItems));
this.styleAppender = new StyleAppender(style);
add(styleAppender);
@@ -102,10 +95,6 @@ public class CssMenuPanel extends PanelAbstract<CssMenuPanel.MyModel> {
}
- public CssMenuPanel(final ComponentType componentType, final Style style, final CssMenuItem... topLevelMenuItems) {
- this(componentType.getWicketId(), style, Arrays.asList(topLevelMenuItems));
- }
-
static final class StyleAppender extends CssClassAppender {
private static final long serialVersionUID = 1L;
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
index f4e5fdf..4b4d00d 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
@@ -24,7 +24,7 @@
<li wicket:id="subMenuItems" class="cssSubMenuItem">
<a wicket:id="menuLink" class="btn">
<span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span>
- <span wicket:id="menuLabel">[menu label]</span>
+ <span class="menuLabel" wicket:id="menuLabel">[menu label]</span>
</a>
<p wicket:id="menuLabel">[menu label]</p>
<span wicket:id="subMenuItems">[subMenuItems]</span>
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
index 51c53d3..9e3e23d 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
@@ -172,3 +172,20 @@ div.label-left .choicesPlaceholder {
width: 20px;
height: 20px;
}
+
+.prototype {
+ font-style: italic;
+}
+
+/*
+not sure if this also needed, but it works...
+a.prototype span.menuLabel::before,
+a.prototype span.menuLinkLabel::before {
+ content: "[";
+}
+
+a.prototype span.menuLabel::after,
+a.prototype span.menuLinkLabel::after {
+ content: "]";
+}
+*/
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
index 1b66626..258fa0e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
@@ -22,7 +22,7 @@ import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
-
+import org.apache.isis.applib.annotation.Programmatic;
/**
@@ -60,11 +60,14 @@ public interface ExceptionRecognizer {
*
* @return user-friendly message to render, or <tt>null</tt> otherwise.
*/
+ @Programmatic
public String recognize(Throwable ex);
+ @Programmatic
@PostConstruct
public void init(Map<String, String> properties);
+ @Programmatic
@PreDestroy
public void shutdown();
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
index d69f9d3..89b2ae1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.applib.services.exceprecog;
+import org.apache.isis.applib.annotation.Programmatic;
+
/**
* An extension of the {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer} interface that
* allows recognized exceptions to be {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Category categorize}d.
@@ -77,6 +79,7 @@ public interface ExceptionRecognizer2 extends ExceptionRecognizer {
}
}
+ @Programmatic
public Recognition recognize2(final Throwable ex);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
index 390e797..f3b6a63 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
@@ -28,6 +28,7 @@ import javax.annotation.PreDestroy;
import com.google.common.collect.Lists;
import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.Programmatic;
/**
* Convenience implementation of {@link ExceptionRecognizer} that loops through a list of
@@ -66,6 +67,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
* before the more general ones. See the <i>JDO object store</i> applib for
* an example.
*/
+ @Programmatic
public final void add(ExceptionRecognizer ers) {
services.add(ers);
}
@@ -74,6 +76,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
* Returns the non-<tt>null</tt> message of the first {@link #add(ExceptionRecognizer) add}ed
* {@link ExceptionRecognizer service} that recognizes the exception.
*/
+ @Programmatic
public final String recognize(Throwable ex) {
for (ExceptionRecognizer ers : services) {
String message = ers.recognize(ex);
@@ -95,6 +98,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
* category of {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Category#CLIENT_ERROR}.
* </p>
*/
+ @Programmatic
public final Recognition recognize2(Throwable ex) {
for (ExceptionRecognizer ers : services) {
if(ers instanceof ExceptionRecognizer2) {
@@ -111,6 +115,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
@PostConstruct
@Override
+ @Programmatic
public final void init(Map<String, String> properties) {
for (ExceptionRecognizer ers : services) {
ers.init(properties);
@@ -119,6 +124,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
@PreDestroy
@Override
+ @Programmatic
public final void shutdown() {
for (ExceptionRecognizer ers : services) {
ers.shutdown();