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 2015/03/03 21:23:11 UTC
[19/20] isis git commit: Merge commit
'f7284d8fb4fbe58479e819b37e7ee3cc731d57ad' into ISIS-789a
http://git-wip-us.apache.org/repos/asf/isis/blob/e2dffa84/mothballed/example/application/todoapp/integtests/src/test/java/integration/tests/ToDoItemIntegTest.java
----------------------------------------------------------------------
diff --cc mothballed/example/application/todoapp/integtests/src/test/java/integration/tests/ToDoItemIntegTest.java
index 5bb2f0f,0000000..f71b6ea
mode 100644,000000..100644
--- a/mothballed/example/application/todoapp/integtests/src/test/java/integration/tests/ToDoItemIntegTest.java
+++ b/mothballed/example/application/todoapp/integtests/src/test/java/integration/tests/ToDoItemIntegTest.java
@@@ -1,1057 -1,0 +1,1057 @@@
+/*
+ * 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 integration.tests;
+
+import dom.todo.ToDoItem;
+import dom.todo.ToDoItemSubscriptions;
+import dom.todo.ToDoItems;
+import fixture.todo.scenarios.ToDoItemsRecreateAndCompleteSeveral;
+
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.util.EventObject;
+import java.util.List;
+import javax.activation.MimeType;
+import javax.inject.Inject;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.jmock.Expectations;
+import org.jmock.Sequence;
+import org.jmock.auto.Mock;
+import org.joda.time.LocalDate;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.apache.isis.applib.NonRecoverableException;
+import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.applib.fixturescripts.FixtureScripts;
+import org.apache.isis.applib.services.clock.ClockService;
+import org.apache.isis.applib.services.eventbus.AbstractInteractionEvent;
+import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
+import org.apache.isis.applib.services.eventbus.CollectionDomainEvent;
+import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.applib.services.eventbus.PropertyDomainEvent;
+import org.apache.isis.applib.value.Blob;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class ToDoItemIntegTest extends AbstractToDoIntegTest {
+
+ ToDoItemsRecreateAndCompleteSeveral fixtureScript;
+
+ @Before
+ public void setUpData() throws Exception {
- fixtureScript = new ToDoItemsRecreateAndCompleteSeveral();
++ fixtureScript = new ToDoItemsRecreateAndCompleteSeveral();
+ fixtureScripts.runFixtureScript(fixtureScript, null);
+ }
+
+ @Inject
+ FixtureScripts fixtureScripts;
+ @Inject
+ ToDoItems toDoItems;
+ @Inject
+ ToDoItemSubscriptions toDoItemSubscriptions;
+
+ ToDoItem toDoItem;
+
+ @Before
+ public void setUp() throws Exception {
+ final List<ToDoItem> all = toDoItems.notYetComplete();
+ toDoItem = wrap(all.get(0));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ toDoItemSubscriptions.reset();
+ }
+
+
+ public static class Title extends ToDoItemIntegTest {
+
+ private LocalDate dueBy;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ final List<ToDoItem> all = wrap(toDoItems).notYetComplete();
+ toDoItem = wrap(all.get(0));
+
+ toDoItem = wrap(fixtureScript.lookup("to-do-items-recreate-and-complete-several/to-do-item-for-buy-bread/item-1", ToDoItem.class));
+ assertThat(toDoItem, is(not(nullValue())));
+
+ nextTransaction();
+
+ dueBy = toDoItem.getDueBy();
+ }
+
+
+ @Test
+ public void includesDescription() throws Exception {
+
+ // given
+ assertThat(container().titleOf(toDoItem), containsString("Buy bread due by"));
+
+ // when
+ unwrap(toDoItem).setDescription("Buy bread and butter");
+
+ // then
+ assertThat(container().titleOf(toDoItem), containsString("Buy bread and butter due by"));
+ }
+
+ @Test
+ public void includesDueDateIfAny() throws Exception {
+
+ // given
+ assertThat(container().titleOf(toDoItem), containsString("due by " + dueBy.toString("yyyy-MM-dd")));
+
+ // when
+ final LocalDate fiveDaysFromNow = Clock.getTimeAsLocalDate().plusDays(5);
+ unwrap(toDoItem).setDueBy(fiveDaysFromNow);
+
+ // then
+ assertThat(container().titleOf(toDoItem), containsString("due by " + fiveDaysFromNow.toString("yyyy-MM-dd")));
+ }
+
+
+ @Test
+ public void ignoresDueDateIfNone() throws Exception {
+
+ // when
+ // (since wrapped, will call clearDueBy)
+ toDoItem.setDueBy(null);
+
+ // then
+ assertThat(container().titleOf(toDoItem), not(containsString("due by")));
+ }
+
+ @Test
+ public void usesWhetherCompleted() throws Exception {
+
+ // given
+ assertThat(container().titleOf(toDoItem), not(containsString("Completed!")));
+
+ // when
+ toDoItem.completed();
+
+ // then
+ assertThat(container().titleOf(toDoItem), not(containsString("due by")));
+ assertThat(container().titleOf(toDoItem), containsString("Buy bread - Completed!"));
+ }
+ }
+
+ public static class Actions {
+
+ public static class Completed extends ToDoItemIntegTest {
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // given
+ assertThat(toDoItem.isComplete(), is(false));
+
+ // when
+ toDoItem.completed();
+
+ // then
+ assertThat(toDoItem.isComplete(), is(true));
+ }
+
+ @Test
+ public void cannotCompleteIfAlreadyCompleted() throws Exception {
+
+ // given
+ unwrap(toDoItem).setComplete(true);
+
+ // when, then should fail
+ expectedExceptions.expectMessage("Already completed");
+ toDoItem.completed();
+
+ // and then
+ final EventObject ev = toDoItemSubscriptions.mostRecentlyReceivedEvent(EventObject.class);
+ assertThat(ev, is(nullValue()));
+ }
+
+
+ @Test
+ public void cannotSetPropertyDirectly() throws Exception {
+
+ // given
+
+ // when, then should fail
+ expectedExceptions.expectMessage("Always disabled");
+ toDoItem.setComplete(true);
+
+ // and then
+ final EventObject ev = toDoItemSubscriptions.mostRecentlyReceivedEvent(EventObject.class);
+ assertThat(ev, is(nullValue()));
+ }
+
+ @Test
+ public void subscriberReceivesEvents() throws Exception {
+
+ // given
+ toDoItemSubscriptions.reset();
+ assertThat(toDoItemSubscriptions.getSubscriberBehaviour(), is(ToDoItemSubscriptions.Behaviour.AnyExecuteAccept));
+ assertThat(unwrap(toDoItem).isComplete(), is(false));
+
+ // when
+ toDoItem.completed();
+
+ // then
+ assertThat(unwrap(toDoItem).isComplete(), is(true));
+
+ // and then
+ final List<ToDoItem.CompletedEvent> receivedEvents = toDoItemSubscriptions.receivedEvents(ToDoItem.CompletedEvent.class);
+
+ // hide, disable, validate, executing, executed
+ // sent to both the general on(ActionInteractionEvent ev)
+ // and also the specific on(final ToDoItem.CompletedEvent ev)
+ assertThat(receivedEvents.size(), is(5*2));
+ final ToDoItem.CompletedEvent ev = receivedEvents.get(0);
+
+ ToDoItem source = ev.getSource();
+ assertThat(source, is(equalTo(unwrap(toDoItem))));
+ assertThat(ev.getIdentifier().getMemberName(), is("completed"));
+ }
+
+ @Test
+ public void subscriberVetoesEventWithRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithRecoverableException);
+
+ // then
+ expectedExceptions.expect(RecoverableException.class);
+
+ // when
+ toDoItem.completed();
+ }
+
+ @Test
+ public void subscriberVetoesEventWithNonRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithNonRecoverableException);
+
+ // then
+ expectedExceptions.expect(NonRecoverableException.class);
+
+ // when
+ toDoItem.completed();
+ }
+
+ @Test
+ public void subscriberVetoesEventWithAnyOtherException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithOtherException);
+
+ // then
+ expectedExceptions.expect(RuntimeException.class);
+
+ // when
+ toDoItem.completed();
+ }
+
+ }
+
+ /**
+ * This test demonstrates how a single service can be replaced, eg to use a mock.
+ */
+ public static class Completed_withMockService extends ToDoItemIntegTest {
+
+ private EventBusService originalEventBusService;
+ @Mock
+ private EventBusService mockEventBusService;
+
+ @Before
+ public void setUpMockEventBusService() throws Exception {
+ originalEventBusService = scenarioExecution().service(EventBusService.class);
+
+ context.checking(new Expectations() {{
+ ignoring(mockEventBusService).register(with(any(Object.class)));
+ ignoring(mockEventBusService).unregister(with(any(Object.class)));
+ }});
+
+ scenarioExecution().replaceService(originalEventBusService, mockEventBusService);
+ scenarioExecution().closeSession();
+ scenarioExecution().openSession();
+
+ final List<ToDoItem> all = toDoItems.notYetComplete();
+ toDoItem = wrap(all.get(0));
+ }
+
+
+ @After
+ public void reinstateOriginalEventBusService() throws Exception {
+ scenarioExecution().replaceService(mockEventBusService, originalEventBusService);
+ }
+
+ @Test
+ public void raisesEvent() throws Exception {
+
+ final Sequence busRulesThenExec = context.sequence("busRulesThenExec");
+ // then
+ context.checking(new Expectations() {{
+ oneOf(mockEventBusService).post(with(completedEvent(AbstractInteractionEvent.Phase.HIDE)));
+ inSequence(busRulesThenExec);
+ oneOf(mockEventBusService).post(with(completedEvent(AbstractInteractionEvent.Phase.DISABLE)));
+ inSequence(busRulesThenExec);
+ oneOf(mockEventBusService).post(with(completedEvent(AbstractInteractionEvent.Phase.VALIDATE)));
+ inSequence(busRulesThenExec);
+ oneOf(mockEventBusService).post(with(completedEvent(AbstractInteractionEvent.Phase.EXECUTING)));
+ inSequence(busRulesThenExec);
+ oneOf(mockEventBusService).post(with(completedEvent(AbstractInteractionEvent.Phase.EXECUTED)));
+ inSequence(busRulesThenExec);
+ }});
+
+ // when
+ toDoItem.completed();
+ }
+
+ private Matcher<Object> completedEvent(final AbstractInteractionEvent.Phase phase) {
+ return new TypeSafeMatcher<Object>() {
+ @Override
+ protected boolean matchesSafely(Object item) {
+ if (!(item instanceof ToDoItem.CompletedEvent)) {
+ return false;
+ }
+
+ final ToDoItem.CompletedEvent completedEvent = (ToDoItem.CompletedEvent) item;
+ return completedEvent.getPhase() == phase;
+
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(" instance of a ToDoItem.CompletedEvent, " + phase);
+ }
+ };
+ }
+ }
+
+
+ public static class Duplicate extends ToDoItemIntegTest {
+
+ ToDoItem duplicateToDoItem;
+
+ @Inject
+ private ClockService clockService;
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // given
+ final LocalDate todaysDate = clockService.now();
+ toDoItem.setDueBy(todaysDate);
+ toDoItem.updateCost(new BigDecimal("123.45"));
+
+ duplicateToDoItem = toDoItem.duplicate(
+ unwrap(toDoItem).default0Duplicate(),
+ unwrap(toDoItem).default1Duplicate(),
+ unwrap(toDoItem).default2Duplicate(),
+ unwrap(toDoItem).default3Duplicate(),
+ new BigDecimal("987.65"));
+
+ // then
+ assertThat(duplicateToDoItem.getDescription(), is(toDoItem.getDescription() + " - Copy"));
+ assertThat(duplicateToDoItem.getCategory(), is(toDoItem.getCategory()));
+ assertThat(duplicateToDoItem.getDueBy(), is(todaysDate));
+ assertThat(duplicateToDoItem.getCost(), is(new BigDecimal("987.65")));
+ }
+ }
+
+ public static class NotYetCompleted extends ToDoItemIntegTest {
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // given
+ unwrap(toDoItem).setComplete(true);
+
+ // when
+ toDoItem.notYetCompleted();
+
+ // then
+ assertThat(toDoItem.isComplete(), is(false));
+ }
+
+ @Test
+ public void cannotUndoIfNotYetCompleted() throws Exception {
+
+ // given
+ assertThat(toDoItem.isComplete(), is(false));
+
+ // when, then should fail
+ expectedExceptions.expectMessage("Not yet completed");
+ toDoItem.notYetCompleted();
+ }
+
+ /**
+ * Even though {@link dom.todo.ToDoItem#notYetCompleted()} is not annotated with
+ * {@link org.apache.isis.applib.annotation.ActionInteraction}, an event is still raised.
+ */
+ @Test
+ public void subscriberReceivesEvent() throws Exception {
+
+ // given
+ assertThat(toDoItemSubscriptions.getSubscriberBehaviour(), is(ToDoItemSubscriptions.Behaviour.AnyExecuteAccept));
+ unwrap(toDoItem).setComplete(true);
+
+ // when
+ toDoItem.notYetCompleted();
+
+ // then
+ assertThat(unwrap(toDoItem).isComplete(), is(false));
+
+ // and then
+ final ActionDomainEvent<ToDoItem> ev = toDoItemSubscriptions.mostRecentlyReceivedEvent(ActionDomainEvent.class);
+ assertThat(ev, is(not(nullValue())));
+
+ ToDoItem source = ev.getSource();
+ assertThat(source, is(equalTo(unwrap(toDoItem))));
+ assertThat(ev.getIdentifier().getMemberName(), is("notYetCompleted"));
+ }
+ }
+ }
+
+ public static class Collections {
+
+ public static class Dependencies {
+ public static class Add extends ToDoItemIntegTest {
+
+ private ToDoItem otherToDoItem;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ final List<ToDoItem> items = wrap(toDoItems).notYetComplete();
+ otherToDoItem = wrap(items.get(1));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ unwrap(toDoItem).getDependencies().clear();
+ super.tearDown();
+ }
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // given
+ assertThat(toDoItem.getDependencies().size(), is(0));
+
+ // when
+ toDoItem.add(otherToDoItem);
+
+ // then
+ assertThat(toDoItem.getDependencies().size(), is(1));
+ assertThat(toDoItem.getDependencies().iterator().next(), is(unwrap(otherToDoItem)));
+ }
+
+
+ @Test
+ public void cannotDependOnSelf() throws Exception {
+
+ // then
+ expectedExceptions.expectMessage("Can't set up a dependency to self");
+
+ // when
+ toDoItem.add(toDoItem);
+ }
+
+ @Test
+ public void cannotAddIfComplete() throws Exception {
+
+ // given
+ unwrap(toDoItem).setComplete(true);
+
+ // then
+ expectedExceptions.expectMessage("Cannot add dependencies for items that are complete");
+
+ // when
+ toDoItem.add(otherToDoItem);
+ }
+
+
+ @Test
+ public void subscriberReceivesEvent() throws Exception {
+
+ // given
+ toDoItemSubscriptions.reset();
+
+ // when
+ toDoItem.add(otherToDoItem);
+
+ // then received events
+ @SuppressWarnings("unchecked")
+ final List<EventObject> receivedEvents = toDoItemSubscriptions.receivedEvents();
+
+ assertThat(receivedEvents.size(), is(7));
+ assertThat(receivedEvents.get(0) instanceof ActionDomainEvent, is(true)); // ToDoItem#add() executed
+ assertThat(receivedEvents.get(1) instanceof CollectionDomainEvent, is(true)); // ToDoItem#dependencies add, executed
+ assertThat(receivedEvents.get(2) instanceof CollectionDomainEvent, is(true)); // ToDoItem#dependencies add, executing
+ assertThat(receivedEvents.get(3) instanceof ActionDomainEvent, is(true)); // ToDoItem#add executing
+ assertThat(receivedEvents.get(4) instanceof ActionDomainEvent, is(true)); // ToDoItem#add validate
+ assertThat(receivedEvents.get(5) instanceof ActionDomainEvent, is(true)); // ToDoItem#add disable
+ assertThat(receivedEvents.get(6) instanceof ActionDomainEvent, is(true)); // ToDoItem#add hide
+
+ // inspect the collection interaction (posted programmatically in ToDoItem#add)
+ final CollectionDomainEvent<ToDoItem,ToDoItem> ciEv = (CollectionDomainEvent<ToDoItem, ToDoItem>) toDoItemSubscriptions.mostRecentlyReceivedEvent(CollectionDomainEvent.class);
+ assertThat(ciEv, is(notNullValue()));
+
+ assertThat(ciEv.getSource(), is(equalTo(unwrap(toDoItem))));
+ assertThat(ciEv.getIdentifier().getMemberName(), is("dependencies"));
+ assertThat(ciEv.getOf(), is(CollectionDomainEvent.Of.ADD_TO));
+ assertThat(ciEv.getValue(), is(unwrap(otherToDoItem)));
+
+ // inspect the action interaction (posted declaratively by framework)
+ final ActionDomainEvent<ToDoItem> aiEv = (ActionDomainEvent<ToDoItem>) toDoItemSubscriptions.mostRecentlyReceivedEvent(ActionDomainEvent.class);
+ assertThat(aiEv, is(notNullValue()));
+
+ assertThat(aiEv.getSource(), is(equalTo(unwrap(toDoItem))));
+ assertThat(aiEv.getIdentifier().getMemberName(), is("add"));
+ assertThat(aiEv.getArguments().size(), is(1));
+ assertThat(aiEv.getArguments().get(0), is(unwrap((Object)otherToDoItem)));
+ assertThat(aiEv.getCommand(), is(notNullValue()));
+ }
+
+ @Test
+ public void subscriberVetoesEventWithRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithRecoverableException);
+
+ // then
+ expectedExceptions.expect(RecoverableException.class);
+
+ // when
+ toDoItem.add(otherToDoItem);
+ }
+
+ @Test
+ public void subscriberVetoesEventWithNonRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithNonRecoverableException);
+
+ // then
+ expectedExceptions.expect(NonRecoverableException.class);
+
+ // when
+ toDoItem.add(otherToDoItem);
+ }
+
+ @Test
+ public void subscriberVetoesEventWithAnyOtherException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithOtherException);
+
+ // then
+ expectedExceptions.expect(RuntimeException.class);
+
+ // when
+ toDoItem.add(otherToDoItem);
+ }
+ }
+ public static class Remove extends ToDoItemIntegTest {
+
+ private ToDoItem otherToDoItem;
+ private ToDoItem yetAnotherToDoItem;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ final List<ToDoItem> items = wrap(toDoItems).notYetComplete();
+ otherToDoItem = wrap(items.get(1));
+ yetAnotherToDoItem = wrap(items.get(2));
+
+ toDoItem.add(otherToDoItem);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ unwrap(toDoItem).getDependencies().clear();
+ super.tearDown();
+ }
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // given
+ assertThat(toDoItem.getDependencies().size(), is(1));
+
+ // when
+ toDoItem.remove(otherToDoItem);
+
+ // then
+ assertThat(toDoItem.getDependencies().size(), is(0));
+ }
+
+
+ @Test
+ public void cannotRemoveItemIfNotADependency() throws Exception {
+
+ // then
+ expectedExceptions.expectMessage("Not a dependency");
+
+ // when
+ toDoItem.remove(yetAnotherToDoItem);
+ }
+
+ @Test
+ public void cannotRemoveDependencyIfComplete() throws Exception {
+
+ // given
+ unwrap(toDoItem).setComplete(true);
+
+ // then
+ expectedExceptions.expectMessage("Cannot remove dependencies for items that are complete");
+
+ // when
+ toDoItem.remove(otherToDoItem);
+ }
+
+ @Test
+ public void subscriberVetoesEventWithRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithRecoverableException);
+
+ // then
+ expectedExceptions.expect(RecoverableException.class);
+
+ // when
+ toDoItem.remove(otherToDoItem);
+ }
+
+ @Test
+ public void subscriberVetoesEventWithNonRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithNonRecoverableException);
+
+ // then
+ expectedExceptions.expect(NonRecoverableException.class);
+
+ // when
+ toDoItem.remove(otherToDoItem);
+ }
+
+ @Test
+ public void subscriberVetoesEventWithAnyOtherException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithOtherException);
+
+ // then
+ expectedExceptions.expect(RuntimeException.class);
+
+ // when
+ toDoItem.remove(otherToDoItem);
+ }
+ }
+ }
+
+ }
+
+ public static class Properties {
+
+ public static class Attachment extends ToDoItemIntegTest {
+
+ @Test
+ public void happyCase() throws Exception {
+
+ byte[] bytes = "{\"foo\": \"bar\"}".getBytes(Charset.forName("UTF-8"));
+ final Blob newAttachment = new Blob("myfile.json", new MimeType("application/json"), bytes);
+
+ // when
+ toDoItem.setAttachment(newAttachment);
+
+ // then
+ assertThat(toDoItem.getAttachment(), is(newAttachment));
+ }
+
+ @Test
+ public void canBeNull() throws Exception {
+
+ // when
+ toDoItem.setAttachment((Blob)null);
+
+ // then
+ assertThat(toDoItem.getAttachment(), is((Blob)null));
+ }
+ }
+
+ public static class Category extends ToDoItemIntegTest {
+
+ @Test
+ public void cannotModify() throws Exception {
+
+ // when, then
+ expectedExceptions.expectMessage(containsString("Reason: Use action to update both category and subcategory."));
+ toDoItem.setCategory(ToDoItem.Category.Professional);
+ }
+ }
+
+ public static class Cost extends ToDoItemIntegTest {
+
+ private BigDecimal cost;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ cost = toDoItem.getCost();
+ }
+
+ @Test
+ public void happyCaseUsingProperty() throws Exception {
+
+ final BigDecimal newCost = new BigDecimal("123.45");
+
+ // when
+ toDoItem.updateCost(newCost);
+
+ // then
+ assertThat(toDoItem.getCost(), is(newCost));
+ }
+
+ @Test
+ public void happyCaseUsingAction() throws Exception {
+
+ final BigDecimal newCost = new BigDecimal("123.45");
+
+ // when
+ toDoItem.updateCost(newCost);
+
+ // then
+ assertThat(toDoItem.getCost(), is(newCost));
+ }
+
+ @Test
+ public void canBeNull() throws Exception {
+
+ // when
+ toDoItem.updateCost((BigDecimal)null);
+
+ // then
+ assertThat(toDoItem.getCost(), is((BigDecimal)null));
+ }
+
+ @Test
+ public void defaultForAction() throws Exception {
+
+ // then
+ assertThat(unwrap(toDoItem).default0UpdateCost(), is(cost));
+ }
+
+ }
+
+ public static class Description extends ToDoItemIntegTest {
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // given
+ assertThat(toDoItem.getDescription(), is("Buy bread"));
+
+ // when
+ toDoItem.setDescription("Buy bread and butter");
+
+ // then
+ assertThat(toDoItem.getDescription(), is("Buy bread and butter"));
+ }
+
+
+ @Test
+ public void failsRegex() throws Exception {
+
+ // when
+ expectedExceptions.expectMessage("Doesn't match pattern");
+ toDoItem.setDescription("exclamation marks are not allowed!!!");
+ }
+
+ @Test
+ public void cannotBeNull() throws Exception {
+
+ // when, then
+ expectedExceptions.expectMessage("Mandatory");
+ toDoItem.setDescription(null);
+ }
+
+ @Test
+ public void cannotUseModify() throws Exception {
+
+ expectedExceptions.expectMessage("Cannot invoke supporting method for 'Description'; use only property accessor/mutator");
+
+ // given
+ assertThat(toDoItem.getDescription(), is("Buy bread"));
+
+ // when
+ toDoItem.modifyDescription("Buy bread and butter");
+
+ // then
+ assertThat(toDoItem.getDescription(), is("Buy bread"));
+ }
+
+ @Test
+ public void cannotUseClear() throws Exception {
+
+ expectedExceptions.expectMessage("Cannot invoke supporting method for 'Description'; use only property accessor/mutator");
+
+ // given
+ assertThat(toDoItem.getDescription(), is("Buy bread"));
+
+ // when
+ toDoItem.clearDescription();
+
+ // then
+ assertThat(toDoItem.getDescription(), is("Buy bread"));
+ }
+
+
+ @Test
+ public void onlyJustShortEnough() throws Exception {
+
+ // when, then
+ toDoItem.setDescription(characters(100));
+ }
+
+ @Test
+ public void tooLong() throws Exception {
+
+ // then
+ expectedExceptions.expectMessage("The value proposed exceeds the maximum length of 100");
+
+ // when
+ toDoItem.setDescription(characters(101));
+ }
+
+
+ @Test
+ public void subscriberReceivesEvent() throws Exception {
+
+ // given
+ assertThat(toDoItemSubscriptions.getSubscriberBehaviour(), is(ToDoItemSubscriptions.Behaviour.AnyExecuteAccept));
+ assertThat(toDoItem.getDescription(), is("Buy bread"));
+
+ // when
+ toDoItem.setDescription("Buy bread and butter");
+
+ // then published and received
+ @SuppressWarnings("unchecked")
+ final PropertyDomainEvent<ToDoItem,String> ev = toDoItemSubscriptions.mostRecentlyReceivedEvent(PropertyDomainEvent.class);
+ assertThat(ev, is(not(nullValue())));
+
+ ToDoItem source = ev.getSource();
+ assertThat(source, is(equalTo(unwrap(toDoItem))));
+ assertThat(ev.getIdentifier().getMemberName(), is("description"));
+ assertThat(ev.getOldValue(), is("Buy bread"));
+ assertThat(ev.getNewValue(), is("Buy bread and butter"));
+ }
+
+ @Test
+ public void subscriberVetoesEventWithRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithRecoverableException);
+
+ // then
+ expectedExceptions.expect(RecoverableException.class);
+
+ // when
+ toDoItem.setDescription("Buy bread and butter");
+ }
+
+
+ @Test
+ public void subscriberVetoesEventWithNonRecoverableException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithNonRecoverableException);
+
+ // then
+ expectedExceptions.expect(NonRecoverableException.class);
+
+ // when
+ toDoItem.setDescription("Buy bread and butter");
+ }
+
+
+ @Test
+ public void subscriberVetoesEventWithAnyOtherException() throws Exception {
+
+ // given
+ toDoItemSubscriptions.subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AnyExecuteVetoWithOtherException);
+
+ // then
+ expectedExceptions.expect(RuntimeException.class);
+
+ // when
+ toDoItem.setDescription("Buy bread and butter");
+ }
+
+
+ private static String characters(final int n) {
+ StringBuffer buf = new StringBuffer();
+ for(int i=0; i<n; i++) {
+ buf.append("a");
+ }
+ return buf.toString();
+ }
+ }
+
+ public static class DueBy extends ToDoItemIntegTest {
+
+ @Inject
+ private ClockService clockService;
+
+ @Test
+ public void happyCase() throws Exception {
+
+ // when
+ final LocalDate fiveDaysFromNow = clockService.now().plusDays(5);
+ toDoItem.setDueBy(fiveDaysFromNow);
+
+ // then
+ assertThat(toDoItem.getDueBy(), is(fiveDaysFromNow));
+ }
+
+
+ @Test
+ public void canBeNull() throws Exception {
+
+ // when
+ toDoItem.setDueBy((LocalDate)null);
+
+ // then
+ assertThat(toDoItem.getDueBy(), is((LocalDate)null));
+ }
+
+ @Test
+ public void canBeUpToSixDaysInPast() throws Exception {
+
+ final LocalDate nowAsLocalDate = clockService.now();
+ final LocalDate sixDaysAgo = nowAsLocalDate.plusDays(-5);
+
+ // when
+ toDoItem.setDueBy(sixDaysAgo);
+
+ // then
+ assertThat(toDoItem.getDueBy(), is(sixDaysAgo));
+ }
+
+
+ @Test
+ public void cannotBeMoreThanSixDaysInPast() throws Exception {
+
+ final LocalDate sevenDaysAgo = Clock.getTimeAsLocalDate().plusDays(-7);
+
+ // when, then
+ expectedExceptions.expectMessage("Due by date cannot be more than one week old");
+ toDoItem.setDueBy(sevenDaysAgo);
+ }
+ }
+
+ public static class Notes extends ToDoItemIntegTest {
+
+ @Test
+ public void happyCase() throws Exception {
+
+ final String newNotes = "Lorem ipsum yada yada";
+
+ // when
+ toDoItem.setNotes(newNotes);
+
+ // then
+ assertThat(toDoItem.getNotes(), is(newNotes));
+ }
+
+ @Test
+ public void canBeNull() throws Exception {
+
+ // when
+ toDoItem.setNotes((String)null);
+
+ // then
+ assertThat(toDoItem.getNotes(), is((String)null));
+ }
+
+ @Test
+ public void suscriberReceivedDefaultEvent() throws Exception {
+
+ final String newNotes = "Lorem ipsum yada yada";
+
+ // when
+ toDoItem.setNotes(newNotes);
+
+ // then
+ assertThat(unwrap(toDoItem).getNotes(), is(newNotes));
+
+ // and then receive the default event.
+ @SuppressWarnings("unchecked")
+ final PropertyDomainEvent.Default ev = toDoItemSubscriptions.mostRecentlyReceivedEvent(PropertyDomainEvent.Default.class);
+ assertThat(ev, is(notNullValue()));
+
+ assertThat(ev.getSource(), is((Object)unwrap(toDoItem)));
+ assertThat(ev.getNewValue(), is((Object)newNotes));
+ }
+
+
+ }
+
+ public static class OwnedBy extends ToDoItemIntegTest {
+
+ @Test
+ public void cannotModify() throws Exception {
+
+ // when, then
+ expectedExceptions.expectMessage("Reason: Hidden on Everywhere. Identifier: dom.todo.ToDoItem#ownedBy()");
+ toDoItem.setOwnedBy("other");
+ }
+
+
+ }
+
+ public static class Subcategory extends ToDoItemIntegTest {
+
+ @Test
+ public void cannotModify() throws Exception {
+
+ // when, then
+ expectedExceptions.expectMessage(containsString("Reason: Use action to update both category and subcategory."));
+ toDoItem.setSubcategory(ToDoItem.Subcategory.Chores);
+ }
+ }
+
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/e2dffa84/mothballed/example/application/todoapp/webapp/pom.xml
----------------------------------------------------------------------
diff --cc mothballed/example/application/todoapp/webapp/pom.xml
index 785d17e,0000000..1dca6f3
mode 100644,000000..100644
--- a/mothballed/example/application/todoapp/webapp/pom.xml
+++ b/mothballed/example/application/todoapp/webapp/pom.xml
@@@ -1,352 -1,0 +1,352 @@@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.isis.example.application</groupId>
+ <artifactId>todoapp</artifactId>
+ <version>1.9.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>todoapp-webapp</artifactId>
+ <name>ToDo App Webapp</name>
+
+ <description>This module runs both the Wicket viewer and the Restfulobjects viewer in a single webapp configured to run using the datanucleus object store.</description>
+
+ <packaging>war</packaging>
+
+ <properties>
+ <siteBaseDir>..</siteBaseDir>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>maven-jetty-plugin</artifactId>
+ </plugin>
+
+ <!-- mvn package -->
+ <plugin>
+ <groupId>org.simplericity.jettyconsole</groupId>
+ <artifactId>jetty-console-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>createconsole</goal>
+ </goals>
+ <configuration>
+ <backgroundImage>${basedir}/src/main/jettyconsole/isis-banner.png</backgroundImage>
+ <destinationFile>${project.build.directory}/${project.build.finalName}-jetty-console.jar</destinationFile>
+ </configuration>
+ <phase>package</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>maven-version</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <warName>todoapp</warName>
+ <archive>
+ <manifest>
+ <addClasspath>false</addClasspath>
+ </manifest>
+ <manifestEntries>
+ <Build-Time>${maven.build.timestamp}</Build-Time>
+ <Build-Host>${agent.name}</Build-Host>
+ <Build-User>${user.name}</Build-User>
+ <Build-Maven>Maven ${maven.version}</Build-Maven>
+ <Build-Java>${java.version}</Build-Java>
+ <Build-OS>${os.name}</Build-OS>
+ <Build-Label>${project.version}</Build-Label>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>
+ org.codehaus.mojo
+ </groupId>
+ <artifactId>
+ build-helper-maven-plugin
+ </artifactId>
+ <versionRange>
+ [1.5,)
+ </versionRange>
+ <goals>
+ <goal>maven-version</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore></ignore>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <dependencies>
+
+ <!-- other modules in this project -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>todoapp-dom</artifactId>
+ <exclusions>
+ <exclusion>
+ <!-- so don't pick up transitive dependency to asm 4.0.0 -->
+ <groupId>org.datanucleus</groupId>
+ <artifactId>datanucleus-enhancer</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>todoapp-fixture</artifactId>
+ <exclusions>
+ <exclusion>
+ <!-- so don't pick up transitive dependency to asm 4.0.0 -->
+ <groupId>org.datanucleus</groupId>
+ <artifactId>datanucleus-enhancer</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- other isis components -->
+ <dependency>
+ <groupId>org.apache.isis.viewer</groupId>
+ <artifactId>isis-viewer-wicket-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-viewer-restfulobjects-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-security-shiro</artifactId>
+ </dependency>
+
+
+ <!-- isis core -->
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-wrapper</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-security</artifactId>
+ </dependency>
+
+
+ <!-- to run using WebServer (optional) -->
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-webserver</artifactId>
+ <scope>runtime</scope>
+ <optional>true</optional>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-servlet_2.5_spec</artifactId>
+ <!--
+ removed so can run o.a.i.WebServer from within IntelliJ;
+ can rely on servlet container to ignore this in war file
+ <scope>provided</scope>
+ -->
+ </dependency>
+
+ <!--
+ JDBC drivers
+ (for jdo objectstore)
+ -->
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ </dependency>
+
+ <!--
+ <dependency>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ <version>9.1-901.jdbc4</version>
+ </dependency>
+ -->
+
+ <!--
+ mvn install:install-file -Dfile=sqljdbc4.jar \
+ -DgroupId=com.microsoft.sqlserver \
+ -DartifactId=jdbc \
+ -Dversion=4.0 \
+ -Dpackaging=jar
+ -->
+ <!--
+ <dependency>
+ <groupId>com.microsoft.sqlserver</groupId>
+ <artifactId>sqljdbc4</artifactId>
+ <version>4.0</version>
+ </dependency>
+ -->
+
+ <dependency>
+ <groupId>org.lazyluke</groupId>
+ <artifactId>log4jdbc-remix</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>self-host</id>
+ <build>
+ <plugins>
+ <!--
+ mvn -P self-host antrun:run
+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks>
+ <exec executable="java" failonerror="true">
+ <arg value="-jar" />
+ <arg value="${project.build.directory}/${project.build.finalName}-jetty-console.jar" />
+ </exec>
+ </tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>jrebel</id>
+ <properties>
+ <!-- as used in the rebel.xml in the dom project -->
+ <target.dir>target</target.dir>
+ <isis-jrebel-plugin.packagePrefix>dom.todo,org.apache.isis.objectstore.jdo.applib</isis-jrebel-plugin.packagePrefix>
+ <isis-jrebel-plugin.loggingLevel>warn</isis-jrebel-plugin.loggingLevel>
+ </properties>
+ <build>
+ <plugins>
+ <!--
+ mvn -P jrebel antrun:run \
+ -Djrebel.jar="C:/Users/Dan/.IdeaIC13/config/plugins/jr-ide-idea/lib/jrebel/jrebel.jar" \
+ -Disis_jrebel_plugin.jar="C:/github/danhaywood/isis-jrebel-plugin/target/danhaywood-isis-jrebel-plugin-1.0.0-SNAPSHOT.jar"
+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <target>
+ <property name="compile_classpath" refid="maven.compile.classpath"/>
+ <property name="runtime_classpath" refid="maven.runtime.classpath"/>
+ <property name="test_classpath" refid="maven.test.classpath"/>
+ <property name="plugin_classpath" refid="maven.plugin.classpath"/>
+
+ <echo message=""/>
+ <echo message=""/>
+ <echo message="jrebel.jar = ${jrebel.jar}"/>
+ <echo message="isis_jrebel_plugin.jar = ${isis_jrebel_plugin.jar}"/>
+ <echo message="target.dir = ${target.dir}"/>
+ <echo message=""/>
+ <echo message=""/>
+
+ <exec executable="java" failonerror="true">
+ <arg value="-javaagent:${jrebel.jar}"/>
+ <arg value="-Drebel.log=false"/>
+ <arg value="-Drebel.check_class_hash=true"/>
+ <arg value="-Drebel.packages_exclude=org.apache.isis"/>
+
+ <!-- as used in the rebel.xml in the dom project -->
+ <arg value="-Dproject.root=${project.basedir}/.."/>
+ <arg value="-Dtarget.dir=${target.dir}"/>
+
+ <arg value="-Drebel.plugins=${isis_jrebel_plugin.jar}"/>
+ <arg value="-Disis-jrebel-plugin.packagePrefix=${isis-jrebel-plugin.packagePrefix}"/>
+ <arg value="-Disis-jrebel-plugin.loggingLevel=${isis-jrebel-plugin.loggingLevel}"/>
+ <arg value="-XX:MaxPermSize=128m"/>
+ <arg value="-classpath"/>
+ <arg value="${runtime_classpath}"/>
+ <arg value="org.apache.isis.WebServer"/>
+ </exec>
+ </target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
- <id>neo4j</id>
- <dependencies>
- <dependency>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-neo4j</artifactId>
- <version>3.2.3</version>
- </dependency>
- </dependencies>
++ <id>neo4j</id>
++ <dependencies>
++ <dependency>
++ <groupId>org.datanucleus</groupId>
++ <artifactId>datanucleus-neo4j</artifactId>
++ <version>4.0.4</version>
++ </dependency>
++ </dependencies>
+ </profile>
+ </profiles>
+
+
+
+</project>
http://git-wip-us.apache.org/repos/asf/isis/blob/e2dffa84/mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --cc mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/isis.properties
index f3366a7,0000000..e22a282
mode 100644,000000..100644
--- a/mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/isis.properties
+++ b/mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/isis.properties
@@@ -1,290 -1,0 +1,290 @@@
+# 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.
+
+
+#################################################################################
+#
+# specify system components.
+#
+# The values correspond to the named components in the installer-registry.properties file
+# in the org.apache.isis.core:isis-core-runtime JAR (in the org.apache.isis.core.runtime package)
+#
+# Although all configuration could reside in isis.properties, the recommendation is
+# to split out into component specific files:
+#
+# xxx_yyy.properties files
+#
+# where
+# * xxx is the component type, and
+# * yyy is the component name.
+#
+# For example, viewer_wicket.properties holds configuration information specific to the Wicket viewer.
+#
+#################################################################################
+
+
+#
+# configure the persistor (object store) to use
+#
+
+# JDO/DataNucleus objectstore
+isis.persistor=datanucleus
+
+
+
+#
+# configure authentication mechanism to use (to logon to the system)
+#
+
+#isis.authentication=bypass
+isis.authentication=shiro
+
+
+#
+# configure authorization mechanism to use
+#
+
+#isis.authorization=bypass
+isis.authorization=shiro
+
+
+
+
+
+#################################################################################
+#
+# MetaModel
+#
+# The metamodel typically does not require additional configuration, although
+# the system components (defined above) may refine the metamodel for their needs.
+#
+#################################################################################
+
+
+#
+# Additional programming model facet factories, or remove standard facet factories.
+# Comma separated list of fully qualified class names.
+#
+#isis.reflector.facets.include=
+#isis.reflector.facets.exclude=
+
+
+#
+# Metamodel validation (in addition to that automatically performed by the programming model facet factories)
+# Default implementation does nothing.
+#
+# Use a custom implementation to enforce additional constraints specific to your app/project/company.
+#
+#isis.reflector.validator=org.apache.isis.core.metamodel.metamodelvalidator.dflt.MetaModelValidatorDefault
+
+
+
+#
+# Whether to allow deprecated annotations/method prefixes (otherwise raise metamodel validation errors).
+# If not specified, default is to allow.
+#
+#isis.reflector.validator.allowDeprecated=false
+
+
+
+#
+# Implementation to use for reading dynamic layout. Default implementation reads Xxx.layout.json files from classpath.
+#
+#isis.reflector.layoutMetadataReaders=org.apache.isis.core.metamodel.layoutmetadata.json.LayoutMetadataReaderFromJson
+
+
+
+#
+# patterns for applying CssClassFa facet (font-awesome icons), matching on action names
+#
+isis.reflector.facet.cssClassFa.patterns=\
+ new.*:fa-plus,\
+ add.*:fa-plus-square,\
+ create.*:fa-plus,\
+ update.*:fa-edit,\
+ change.*:fa-edit,\
+ remove.*:fa-minus-square,\
+ move.*:fa-exchange,\
+ first.*:fa-star,\
+ find.*:fa-search,\
+ lookup.*:fa-search,\
+ clear.*:fa-remove,\
+ previous.*:fa-step-backward,\
+ next.*:fa-step-forward,\
+ list.*:fa-list, \
+ all.*:fa-list, \
+ download.*:fa-download, \
+ upload.*:fa-upload, \
+ execute.*:fa-bolt, \
+ run.*:fa-bolt, \
+ calculate.*:fa-calculator, \
+ verify.*:fa-check-circle, \
+ refresh.*:fa-refresh, \
+ install.*:fa-wrench
+
+
+#
+# patterns for applying CssClass facet (CSS styles), matching on member names
+#
+isis.reflector.facet.cssClass.patterns=\
+ delete.*:btn-warning,\
+ .*:btn-default
+
+
+#################################################################################
+#
+# Value facet defaults
+#
+# (see also viewer-specific config files, eg viewer_wicket.properties)
+#
+#################################################################################
+
+# as used by @Title of a date
+isis.value.format.date=dd-MM-yyyy
+
+
+
+#################################################################################
+#
+# Facet Decorators
+#
+#################################################################################
+
+#
+# Providing such capabilities as i18n
+#
+
+isis.reflector.facet-decorators=org.apache.isis.core.metamodel.facetdecorator.i18n.resourcebundle.I18nDecoratorUsingResourceBundleInstaller
+
+
+#################################################################################
+#
+# Application Services and fixtures
+#
+#################################################################################
+
+#
+# Specify the domain services.
+#
+# These are the most important configuration properties in the system, as they define
+# the set of the classes for Isis to instantiate as domain service singletons.
+# From these domain service instances the rest of the metamodel is discovered, while the
+# end-user gains access to other domain objects by invoking the actions of the domain services.
+#
+isis.services-installer=configuration-and-annotation
- isis.services.ServicesInstallerFromAnnotation.packagePrefix=app,\
++isis.services.ServicesInstallerFromAnnotation.packagePrefix=app,dom.todo,fixture.todo,webapp.admin,webapp.prototyping, \
+ dom.todo,\
+ fixture.todo,\
+ webapp.userprof,\
+ webapp.prototyping
+
- isis.services = \
++isis.services = org.apache.isis.applib.services.bookmark.BookmarkHolderActionContributions,\# customizable exception handling, org.apache.isis.objectstore.jdo.applib.service.exceprecog.ExceptionRecognizerCompositeForJdoObjectStore,\#,1\:webapp.CustomMementoService,1\:webapp.CustomRepresentationService
+ org.apache.isis.applib.services.bookmark.BookmarkHolderActionContributions,\
+ \
+ # customizable exception handling, \
+ org.apache.isis.objectstore.jdo.applib.service.exceprecog.ExceptionRecognizerCompositeForJdoObjectStore,\
+ #,\
+ 1:webapp.CustomMementoService,\
+ 1:webapp.CustomRepresentationService
+
+
+# Specify the (optional) test fixtures
+#
+# Fixtures are used to seed the object store with an initial set of data. For the
+# in-memory object store, the fixtures are installed on every run. For other
+# object stores, they are used only when the object store is first initialized.
+#
+#isis.fixtures=fixture.todo.scenarios.ToDoItemsRecreateForSven
+
+
+#
+# required by EmailServiceDefault
+#
+#isis.service.email.sender.address=some.valid@email.address
+#isis.service.email.sender.password=the.password.for-isis.notification.email.sender.address
+
+
+#
+# whether ExceptionRecognizers should also log any recognized exceptions
+# (default false; enable for diagnostics/debugging)
+#
+#isis.services.exceprecog.logRecognizedExceptions=true
+
+
+################################################################################
+#
+# Auditing, Publishing, Command
+#
+################################################################################
+
+#
+# Whether changes to objects should be audited; if not set, defaults to "none"
+# - if not set or set to "none", can explicitly enable using @DomainObject(auditing=Auditing.ENABLED)
+# - if set to "all", can explicitly disable using @Object(auditing=Auditing.DISABLED)
+#
+#isis.services.audit.objects=all|none
+
+#
+# Whether changes to objects should be published; if not set, defaults to "none"
+# - if not set or set to "none", can explicitly enable using @DomainObject(publishing=Publishing.ENABLED)
+# - if set to "all", can explicitly disable using @Object(publishing=Publishing.DISABLED)
+#
+#isis.services.publish.objects=all|none
+
+#
+# Whether all (or all non-query only) actions should be published; if not set, defaults to "none"
+# - if not set or set to "none", can explicitly enable using @Action(publishing=Publishing.ENABLED)
+# - if set to "all", can explicitly disable using @Action(publishing=Publishing.DISABLED)
+#
+#isis.services.publish.actions=all|none|ignoreQueryOnly
+
+
+#
+# Whether all (or all non-query only) actions should be reified as commands; if not set, defaults to "none"
+# - if not set or set to "none", can explicitly enable using @Action(command=CommandReification.ENABLED)
+# - if set to "all", can explicitly disable using @Action(command=CommandReification.DISABLED)
+#
+#isis.services.command.actions=all|none|ignoreQueryOnly
+
+
+
+################################################################################
+#
+# Policies
+#
+#################################################################################
+
+#
+# Whether editing of object properties is allowed; if not set, defaults to "true"
+# - if not set or set to "true", can explicitly disable using @DomainObject(editing=Editing.DISABLED)
+# - if set to "false", can explicitly enable using @DomainObject(editing=Editing.ENABLED)
+#
+#isis.objects.editing=true|false
+
+
+
+################################################################################
+#
+# Viewer defaults
+#
+#################################################################################
+
+#isis.viewers.paged.standalone=30
+#isis.viewers.paged.parented=10
+
+#isis.viewers.propertyLayout.labelPosition=LEFT
+#isis.viewers.parameterLayout.labelPosition=LEFT
http://git-wip-us.apache.org/repos/asf/isis/blob/e2dffa84/mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/persistor_datanucleus.properties
----------------------------------------------------------------------
diff --cc mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/persistor_datanucleus.properties
index a60a733,0000000..051d1dc
mode 100644,000000..100644
--- a/mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/persistor_datanucleus.properties
+++ b/mothballed/example/application/todoapp/webapp/src/main/webapp/WEB-INF/persistor_datanucleus.properties
@@@ -1,88 -1,0 +1,88 @@@
+# 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.
+
+#
+# configuration file for the JDO/DataNucleus objectstore
+#
+
+# identifies @PersistenceCapable entities to be eagerly registered
+# if move class to other package (eg com.mycompany.myapp.dom) then update
+isis.persistor.datanucleus.RegisterEntities.packagePrefix=dom
+
+# whether to persist the event data as a "clob" or as a "zipped" byte[]
+# default is "zipped"
+#isis.persistor.datanucleus.PublishingService.serializedForm=zipped
+
+
+
+#####################################################################
+#
+# DataNucleus' configuration
+#
+# The 'isis.persistor.datanucleus.impl' prefix is stripped off,
+# remainder is passed through to DataNucleus
+#
+#####################################################################
+
- isis.persistor.datanucleus.impl.datanucleus.autoCreateSchema=true
- isis.persistor.datanucleus.impl.datanucleus.validateTables=true
- isis.persistor.datanucleus.impl.datanucleus.validateConstraints=true
++isis.persistor.datanucleus.impl.datanucleus.schema.autoCreateAll=true
++isis.persistor.datanucleus.impl.datanucleus.schema.validateTables=true
++isis.persistor.datanucleus.impl.datanucleus.schema.validateConstraints=true
+
+
+#
+# Require explicit persistence (since entities are Comparable and using ObjectContracts#compareTo).
+# see http://www.datanucleus.org/products/accessplatform_3_0/jdo/transaction_types.html
+#
+isis.persistor.datanucleus.impl.datanucleus.persistenceByReachabilityAtCommit=false
+
+
+#
+# How column names are identified
+# (http://www.datanucleus.org/products/datanucleus/jdo/orm/datastore_identifiers.html)
+#
- isis.persistor.datanucleus.impl.datanucleus.identifier.case=PreserveCase
++isis.persistor.datanucleus.impl.datanucleus.identifier.case=MixedCase
+
+
+#
+# L2 cache
+# off except if explicitly marked as cacheable
+# http://www.datanucleus.org/products/datanucleus/jdo/cache.html
+#
+isis.persistor.datanucleus.impl.datanucleus.cache.level2.type=none
+isis.persistor.datanucleus.impl.datanucleus.cache.level2.mode=ENABLE_SELECTIVE
+
+
+
+#
+# uncomment to use JNDI rather than direct JDBC
+#
+#isis.persistor.datanucleus.impl.datanucleus.ConnectionFactoryName=java:comp/env/jdbc/quickstart
+
+#
+# uncomment to use JTA resource
+#
+#isis.persistor.datanucleus.impl.datanucleus.ConnectionFactory2Name=java:comp/env/jdbc/quickstart-nontx
+#isis.persistor.datanucleus.impl.javax.jdo.option.TransactionType=JTA
+
+
+
+#
+#
+# JDBC connection details
+# ... are in persistor.properties
+#
+#
http://git-wip-us.apache.org/repos/asf/isis/blob/e2dffa84/pom.xml
----------------------------------------------------------------------