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/09/25 11:52:22 UTC
[3/7] ISIS-887: mothballed the core/module* modules,
moved to mothballed/core/module*
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
new file mode 100644
index 0000000..fb5fabc
--- /dev/null
+++ b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
@@ -0,0 +1,740 @@
+/**
+ * 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.objectstore.jdo.applib.service.command;
+
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.jdo.annotations.IdentityType;
+import javax.jdo.annotations.NotPersistent;
+
+import com.google.common.collect.Maps;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.Bulk;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.Immutable;
+import org.apache.isis.applib.annotation.Mandatory;
+import org.apache.isis.applib.annotation.MemberGroupLayout;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.MultiLine;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.ObjectType;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.TypicalLength;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.util.ObjectContracts;
+import org.apache.isis.applib.util.TitleBuffer;
+import org.apache.isis.objectstore.jdo.applib.service.DomainChangeJdoAbstract;
+import org.apache.isis.objectstore.jdo.applib.service.JdoColumnLength;
+import org.apache.isis.objectstore.jdo.applib.service.Util;
+import org.apache.isis.objectstore.jdo.applib.service.DomainChangeJdoAbstract.ChangeType;
+
+
+@javax.jdo.annotations.PersistenceCapable(
+ identityType=IdentityType.APPLICATION,
+ table="IsisCommand")
+@javax.jdo.annotations.Queries( {
+ @javax.jdo.annotations.Query(
+ name="findByTransactionId", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
+ + "WHERE transactionId == :transactionId "),
+ @javax.jdo.annotations.Query(
+ name="findBackgroundCommandByTransactionId", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
+ + "WHERE transactionId == :transactionId "
+ + "&& executeIn == 'BACKGROUND'"),
+ @javax.jdo.annotations.Query(
+ name="findBackgroundCommandsByParent", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
+ + "WHERE parent == :parent "
+ + "&& executeIn == 'BACKGROUND'"),
+ @javax.jdo.annotations.Query(
+ name="findBackgroundCommandsNotYetStarted", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
+ + "WHERE executeIn == 'BACKGROUND' "
+ + "&& startedAt == null "
+ + "ORDER BY timestamp ASC "
+ ),
+ @javax.jdo.annotations.Query(
+ name="findCurrent", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
+ + "WHERE completedAt == null "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findCompleted", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
+ + "WHERE completedAt != null "
+ + "&& executeIn == 'FOREGROUND' "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTargetAndTimestampBetween", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE targetStr == :targetStr "
+ + "&& timestamp >= :from "
+ + "&& timestamp <= :to "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTargetAndTimestampAfter", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE targetStr == :targetStr "
+ + "&& timestamp >= :from "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTargetAndTimestampBefore", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE targetStr == :targetStr "
+ + "&& timestamp <= :to "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTarget", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE targetStr == :targetStr "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTimestampBetween", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE timestamp >= :from "
+ + "&& timestamp <= :to "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTimestampAfter", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE timestamp >= :from "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="findByTimestampBefore", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "WHERE timestamp <= :to "
+ + "ORDER BY timestamp DESC"),
+ @javax.jdo.annotations.Query(
+ name="find", language="JDOQL",
+ value="SELECT "
+ + "FROM org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo "
+ + "ORDER BY timestamp DESC")
+})
+@ObjectType("IsisCommand")
+@MemberGroupLayout(
+ columnSpans={6,0,6,12},
+ left={"Identifiers","Target","Notes"},
+ right={"Detail","Timings","Results"})
+@Named("Command")
+@Immutable
+public class CommandJdo extends DomainChangeJdoAbstract implements Command {
+
+ @SuppressWarnings("unused")
+ private static final Logger LOG = LoggerFactory.getLogger(CommandJdo.class);
+
+ public CommandJdo() {
+ super(ChangeType.COMMAND);
+ }
+
+
+
+ // //////////////////////////////////////
+ // Identification
+ // //////////////////////////////////////
+
+ public String title() {
+ final TitleBuffer buf = new TitleBuffer();
+ buf.append(getTargetStr());
+ buf.append(" ").append(getMemberIdentifier());
+ return buf.toString();
+ }
+
+
+
+ // //////////////////////////////////////
+ // user (property)
+ // //////////////////////////////////////
+
+ private String user;
+
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.USER_NAME)
+ @MemberOrder(name="Identifiers", sequence = "10")
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(final String user) {
+ this.user = user;
+ }
+
+
+
+ // //////////////////////////////////////
+ // timestamp (property)
+ // //////////////////////////////////////
+
+ private Timestamp timestamp;
+
+ /**
+ * The date/time at which this action was created.
+ */
+ @javax.jdo.annotations.Persistent
+ @javax.jdo.annotations.Column(allowsNull="false")
+ @MemberOrder(name="Identifiers", sequence = "20")
+ public Timestamp getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * <b>NOT API</b>: intended to be called only by the framework.
+ */
+ public void setTimestamp(final Timestamp timestamp) {
+ this.timestamp = timestamp;
+ }
+
+
+ // //////////////////////////////////////
+ // executor (property)
+ // //////////////////////////////////////
+
+ private Executor executor;
+
+ @Programmatic
+ @javax.jdo.annotations.NotPersistent
+ @Override
+ public Executor getExecutor() {
+ return executor;
+ }
+
+ @Override
+ public void setExecutor(Executor nature) {
+ this.executor = nature;
+ }
+
+ // //////////////////////////////////////
+ // executeIn (property)
+ // //////////////////////////////////////
+
+ private ExecuteIn executeIn;
+
+ /**
+ * Whether the action was invoked explicitly by the user, or scheduled as a background
+ * task, or as for some other reason, eg a side-effect of rendering an object due to
+ * get-after-post).
+ */
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.Command.EXECUTE_IN)
+ @MemberOrder(name="Identifiers", sequence = "32")
+ @Override
+ public ExecuteIn getExecuteIn() {
+ return executeIn;
+ }
+
+ /**
+ * <b>NOT API</b>: intended to be called only by the framework.
+ */
+ @Override
+ public void setExecuteIn(ExecuteIn nature) {
+ this.executeIn = nature;
+ }
+
+
+ // //////////////////////////////////////
+ // parent (property)
+ // //////////////////////////////////////
+
+ private Command parent;
+
+ @Override
+ @javax.jdo.annotations.Persistent
+ @javax.jdo.annotations.Column(name="parentTransactionId", allowsNull="true")
+ @Hidden(where=Where.PARENTED_TABLES)
+ @MemberOrder(name="Identifiers",sequence = "40")
+ public Command getParent() {
+ return parent;
+ }
+
+ @Override
+ public void setParent(Command parent) {
+ this.parent = parent;
+ }
+
+
+ // //////////////////////////////////////
+ // transactionId (property)
+ // //////////////////////////////////////
+
+
+ private UUID transactionId;
+
+ /**
+ * The unique identifier (a GUID) of the transaction in which this command occurred.
+ */
+ @javax.jdo.annotations.PrimaryKey
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TRANSACTION_ID)
+ @TypicalLength(JdoColumnLength.TRANSACTION_ID)
+ @MemberOrder(name="Identifiers",sequence = "50")
+ @Override
+ public UUID getTransactionId() {
+ return transactionId;
+ }
+
+ /**
+ * <b>NOT API</b>: intended to be called only by the framework.
+ *
+ * <p>
+ * Implementation notes: copied over from the Isis transaction when the command is persisted.
+ */
+ @Override
+ public void setTransactionId(final UUID transactionId) {
+ this.transactionId = transactionId;
+ }
+
+
+ // //////////////////////////////////////
+ // targetClass (property)
+ // //////////////////////////////////////
+
+ private String targetClass;
+
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TARGET_CLASS)
+ @TypicalLength(30)
+ @MemberOrder(name="Target", sequence = "10")
+ @Named("Class")
+ public String getTargetClass() {
+ return targetClass;
+ }
+
+ public void setTargetClass(final String targetClass) {
+ this.targetClass = Util.abbreviated(targetClass, JdoColumnLength.TARGET_CLASS);
+ }
+
+
+ // //////////////////////////////////////
+ // targetAction (property)
+ // //////////////////////////////////////
+
+ private String targetAction;
+
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TARGET_ACTION)
+ @Mandatory
+ @Hidden(where=Where.NOWHERE)
+ @TypicalLength(30)
+ @MemberOrder(name="Target", sequence = "20")
+ @Named("Action")
+ public String getTargetAction() {
+ return targetAction;
+ }
+
+ public void setTargetAction(final String targetAction) {
+ this.targetAction = Util.abbreviated(targetAction, JdoColumnLength.TARGET_ACTION);
+ }
+
+
+ // //////////////////////////////////////
+ // target (property)
+ // openTargetObject (action)
+ // //////////////////////////////////////
+
+ private String targetStr;
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.BOOKMARK, name="target")
+ @Hidden(where=Where.ALL_TABLES)
+ @MemberOrder(name="Target", sequence="30")
+ @Named("Object")
+ public String getTargetStr() {
+ return targetStr;
+ }
+
+ public void setTargetStr(final String targetStr) {
+ this.targetStr = targetStr;
+ }
+
+ // //////////////////////////////////////
+ // arguments (property)
+ // //////////////////////////////////////
+
+ private String arguments;
+
+ @javax.jdo.annotations.Column(allowsNull="true", jdbcType="CLOB")
+ @MultiLine(numberOfLines=7)
+ @Hidden(where=Where.ALL_TABLES)
+ @MemberOrder(name="Target",sequence = "40")
+ public String getArguments() {
+ return arguments;
+ }
+
+ public void setArguments(final String arguments) {
+ this.arguments = arguments;
+ }
+
+
+
+ // //////////////////////////////////////
+ // memberIdentifier (property)
+ // //////////////////////////////////////
+
+ private String memberIdentifier;
+
+ @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.MEMBER_IDENTIFIER)
+ @TypicalLength(60)
+ @Hidden(where=Where.ALL_TABLES)
+ @MemberOrder(name="Detail",sequence = "1")
+ public String getMemberIdentifier() {
+ return memberIdentifier;
+ }
+
+ public void setMemberIdentifier(final String memberIdentifier) {
+ this.memberIdentifier = Util.abbreviated(memberIdentifier, JdoColumnLength.MEMBER_IDENTIFIER);
+ }
+
+
+
+ // //////////////////////////////////////
+ // memento (property)
+ // //////////////////////////////////////
+
+ private String memento;
+
+ @javax.jdo.annotations.Column(allowsNull="true", jdbcType="CLOB")
+ @MultiLine(numberOfLines=9)
+ @Hidden(where=Where.ALL_TABLES)
+ @MemberOrder(name="Detail",sequence = "30")
+ public String getMemento() {
+ return memento;
+ }
+
+ public void setMemento(final String memento) {
+ this.memento = memento;
+ }
+
+
+
+ // //////////////////////////////////////
+ // startedAt (derived property)
+ // //////////////////////////////////////
+
+ private Timestamp startedAt;
+
+ @javax.jdo.annotations.Persistent
+ @javax.jdo.annotations.Column(allowsNull="true")
+ @MemberOrder(name="Timings", sequence = "3")
+ public Timestamp getStartedAt() {
+ return startedAt;
+ }
+
+ /**
+ * <b>NOT API</b>: intended to be called only by the framework.
+ */
+ public void setStartedAt(final Timestamp startedAt) {
+ this.startedAt = startedAt;
+ }
+
+
+
+ // //////////////////////////////////////
+ // completedAt (property)
+ // //////////////////////////////////////
+
+ private Timestamp completedAt;
+
+ /**
+ * The date/time at which this interaction completed.
+ */
+ @javax.jdo.annotations.Persistent
+ @javax.jdo.annotations.Column(allowsNull="true")
+ @MemberOrder(name="Timings", sequence = "4")
+ @Override
+ public Timestamp getCompletedAt() {
+ return completedAt;
+ }
+
+ @Override
+ public void setCompletedAt(final Timestamp completed) {
+ this.completedAt = completed;
+ }
+
+
+ // //////////////////////////////////////
+ // duration (derived property)
+ // //////////////////////////////////////
+
+ /**
+ * The number of seconds (to 3 decimal places) that this interaction lasted.
+ *
+ * <p>
+ * Populated only if it has {@link #getCompletedAt() completed}.
+ */
+ @javax.validation.constraints.Digits(integer=5, fraction=3)
+ @Named("Duration")
+ @MemberOrder(name="Timings", sequence = "7")
+ public BigDecimal getDuration() {
+ return Util.durationBetween(getStartedAt(), getCompletedAt());
+ }
+
+
+
+ // //////////////////////////////////////
+ // complete (derived property)
+ // //////////////////////////////////////
+
+
+ @javax.jdo.annotations.NotPersistent
+ @MemberOrder(name="Timings", sequence = "8")
+ @Hidden(where=Where.OBJECT_FORMS)
+ public boolean isComplete() {
+ return getCompletedAt() != null;
+ }
+
+
+
+ // //////////////////////////////////////
+ // state (derived property)
+ // //////////////////////////////////////
+
+ @javax.jdo.annotations.NotPersistent
+ @MemberOrder(name="Results",sequence = "10")
+ @Hidden(where=Where.OBJECT_FORMS)
+ @Named("Result")
+ public String getResultSummary() {
+ if(getCompletedAt() == null) {
+ return "";
+ }
+ if(getException() != null) {
+ return "EXCEPTION";
+ }
+ if(getResultStr() != null) {
+ return "OK";
+ } else {
+ return "OK (VOID)";
+ }
+ }
+
+
+ // //////////////////////////////////////
+ // result (property)
+ // openResultObject (action)
+ // //////////////////////////////////////
+
+ @Programmatic
+ @Override
+ public Bookmark getResult() {
+ return Util.bookmarkFor(getResultStr());
+ }
+
+ @Programmatic
+ @Override
+ public void setResult(Bookmark result) {
+ setResultStr(Util.asString(result));
+ }
+
+ // //////////////////////////////////////
+
+ private String resultStr;
+
+ @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.BOOKMARK, name="result")
+ @Hidden(where=Where.ALL_TABLES)
+ @Named("Result Bookmark")
+ @MemberOrder(name="Results", sequence="25")
+ public String getResultStr() {
+ return resultStr;
+ }
+
+ public void setResultStr(final String resultStr) {
+ this.resultStr = resultStr;
+ }
+
+ // //////////////////////////////////////
+
+ @ActionSemantics(Of.SAFE)
+ @MemberOrder(name="ResultStr", sequence="1")
+ @Named("Open")
+ public Object openResultObject() {
+ return Util.lookupBookmark(getResult(), bookmarkService, container);
+ }
+ public boolean hideOpenResultObject() {
+ return getResult() == null;
+ }
+
+
+ // //////////////////////////////////////
+ // exception (property)
+ // causedException (derived property)
+ // showException (associated action)
+ // //////////////////////////////////////
+
+ private String exception;
+
+ /**
+ * Stack trace of any exception that might have occurred if this interaction/transaction aborted.
+ *
+ * <p>
+ * Not visible in the UI, but accessible
+ * <p>
+ * Not part of the applib API, because the default implementation is not persistent
+ * and so there's no object that can be accessed to be annotated.
+ */
+ @javax.jdo.annotations.Column(allowsNull="true", jdbcType="CLOB")
+ @Hidden
+ @Override
+ public String getException() {
+ return exception;
+ }
+
+ @Override
+ public void setException(final String exception) {
+ this.exception = exception;
+ }
+
+
+ // //////////////////////////////////////
+
+ @javax.jdo.annotations.NotPersistent
+ @MemberOrder(name="Results",sequence = "30")
+ @Hidden(where=Where.ALL_TABLES)
+ public boolean isCausedException() {
+ return getException() != null;
+ }
+
+
+ // //////////////////////////////////////
+
+ @ActionSemantics(Of.SAFE)
+ @MemberOrder(name="causedException", sequence = "1")
+ public String showException() {
+ return getException();
+ }
+ public boolean hideShowException() {
+ return !isCausedException();
+ }
+
+
+ // //////////////////////////////////////
+ // next(...) impl
+ // //////////////////////////////////////
+
+ private final Map<String, AtomicInteger> sequenceByName = Maps.newHashMap();
+
+
+
+ @Programmatic
+ @Override
+ public int next(String sequenceName) {
+ AtomicInteger next = sequenceByName.get(sequenceName);
+ if(next == null) {
+ next = new AtomicInteger(0);
+ sequenceByName.put(sequenceName, next);
+ } else {
+ next.incrementAndGet();
+ }
+ return next.get();
+ }
+
+
+ // //////////////////////////////////////
+ // persistence (programmatic)
+ // //////////////////////////////////////
+
+ private Persistence persistence;
+
+ @javax.jdo.annotations.NotPersistent
+ @Programmatic
+ @Override
+ public Persistence getPersistence() {
+ return persistence;
+ }
+
+ @Override
+ public void setPersistence(Persistence persistence) {
+ this.persistence = persistence;
+ }
+
+
+ // //////////////////////////////////////
+ // setPersistHint (SPI impl)
+ // //////////////////////////////////////
+
+ private boolean persistHint;
+
+ @NotPersistent
+ @Programmatic
+ public boolean isPersistHint() {
+ return persistHint;
+ }
+
+ @Programmatic
+ @Override
+ public void setPersistHint(boolean persistHint) {
+ this.persistHint = persistHint;
+ }
+
+
+ // //////////////////////////////////////
+
+ @Programmatic
+ boolean shouldPersist() {
+ if(Persistence.PERSISTED == getPersistence()) {
+ return true;
+ }
+ if(Persistence.IF_HINTED == getPersistence()) {
+ return isPersistHint();
+ }
+ return false;
+ }
+
+
+
+ // //////////////////////////////////////
+ // toString
+ // //////////////////////////////////////
+
+ @Override
+ public String toString() {
+ return ObjectContracts.toString(this, "targetStr,memberIdentifier,user,startedAt,completedAt,duration,transactionId");
+ }
+
+
+
+ // //////////////////////////////////////
+ // dependencies
+ // //////////////////////////////////////
+
+
+ @javax.inject.Inject
+ private BookmarkService bookmarkService;
+
+ @javax.inject.Inject
+ private DomainObjectContainer container;
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
new file mode 100644
index 0000000..45616c8
--- /dev/null
+++ b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
@@ -0,0 +1,119 @@
+/**
+ * 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.objectstore.jdo.applib.service.command;
+
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command.Executor;
+import org.apache.isis.applib.services.command.spi.CommandService;
+
+/**
+ *
+ */
+@DomainService
+public class CommandServiceJdo extends AbstractService implements CommandService {
+
+ @SuppressWarnings("unused")
+ private static final Logger LOG = LoggerFactory.getLogger(CommandServiceJdo.class);
+
+ /**
+ * Creates an {@link CommandJdo}, initializing its
+ * {@link Command#setExecuteIn(Command.ExecuteIn) nature} to be
+ * {@link Command.ExecuteIn#OTHER rendering}.
+ */
+ @Programmatic
+ @Override
+ public Command create() {
+ CommandJdo command = newTransientInstance(CommandJdo.class);
+ command.setExecutor(Executor.OTHER);
+ command.setPersistence(Persistence.IF_HINTED);
+ return command;
+ }
+
+ @Programmatic
+ @Override
+ public void startTransaction(final Command command, final UUID transactionId) {
+ if(command instanceof CommandJdo) {
+ // should be the case, since this service created the object in the #create() method
+ final CommandJdo commandJdo = (CommandJdo) command;
+ final UUID currentTransactionId = commandJdo.getTransactionId();
+ if(currentTransactionId != null && !currentTransactionId.equals(transactionId)) {
+ // the logic in IsisTransaction means that any subsequent transactions within a given command
+ // should reuse the xactnId of the first transaction created within that interaction.
+ throw new IllegalStateException("Attempting to set a different transactionId on command");
+ }
+ commandJdo.setTransactionId(transactionId);
+ }
+ }
+
+ @Programmatic
+ @Override
+ public void complete(final Command command) {
+ final CommandJdo commandJdo = asUserInitiatedCommandJdo(command);
+ if(commandJdo == null) {
+ return;
+ }
+ if(commandJdo.getCompletedAt() != null) {
+ // already attempted to complete.
+ // chances are, we're here as the result of a redirect following a previous exception
+ // so just ignore.
+ return;
+ }
+
+ commandJdo.setCompletedAt(Clock.getTimeAsJavaSqlTimestamp());
+ persistIfNotAlready(commandJdo);
+ }
+
+ @Override
+ public boolean persistIfPossible(Command command) {
+ if(!(command instanceof CommandJdo)) {
+ // ought not to be the case, since this service created the object in the #create() method
+ return false;
+ }
+ final CommandJdo commandJdo = (CommandJdo)command;
+ persistIfNotAlready(commandJdo);
+ return true;
+ }
+
+
+ /**
+ * Not API, also used by {@link CommandServiceJdoRepository}.
+ */
+ CommandJdo asUserInitiatedCommandJdo(final Command command) {
+ if(!(command instanceof CommandJdo)) {
+ // ought not to be the case, since this service created the object in the #create() method
+ return null;
+ }
+ if(command.getExecuteIn() != ExecuteIn.FOREGROUND) {
+ return null;
+ }
+ final CommandJdo commandJdo = (CommandJdo) command;
+ return commandJdo.shouldPersist()? commandJdo: null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoContributions.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoContributions.java b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoContributions.java
new file mode 100644
index 0000000..6142d30
--- /dev/null
+++ b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoContributions.java
@@ -0,0 +1,70 @@
+/**
+ * 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.objectstore.jdo.applib.service.command;
+
+import java.util.UUID;
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.NotContributed;
+import org.apache.isis.applib.annotation.NotContributed.As;
+import org.apache.isis.applib.annotation.NotInServiceMenu;
+import org.apache.isis.applib.services.HasTransactionId;
+import org.apache.isis.applib.services.command.Command;
+
+
+/**
+ * This service contributes a <tt>command</tt> action to any (non-command) implementation of
+ * {@link org.apache.isis.applib.services.HasTransactionId}; that is: audit entries, and published events. Thus, it
+ * is possible to navigate from the effect back to the cause.
+ *
+ * <p>
+ * Because this service influences the UI, it must be explicitly registered as a service
+ * (eg using <tt>isis.properties</tt>).
+ */
+public class CommandServiceJdoContributions extends AbstractFactoryAndRepository {
+
+ @NotInServiceMenu
+ @NotContributed(As.ASSOCIATION) // ie contributed as an action
+ @MemberOrder(name="transactionId", sequence="1")
+ public CommandJdo command(final HasTransactionId hasTransactionId) {
+ return commandServiceRepository.findByTransactionId(hasTransactionId.getTransactionId());
+ }
+ /**
+ * Hide if the contributee is a {@link Command}, because {@link Command}s already have a
+ * {@link Command#getParent() parent} property.
+ */
+ public boolean hideCommand(final HasTransactionId hasTransactionId) {
+ return (hasTransactionId instanceof Command);
+ }
+ public String disableCommand(final HasTransactionId hasTransactionId) {
+ if(hasTransactionId == null) {
+ return "No transaction Id";
+ }
+ final UUID transactionId = hasTransactionId.getTransactionId();
+ final boolean command = commandServiceRepository.findByTransactionId(transactionId) == null;
+ return command? "No command found for transaction Id": null;
+ }
+
+
+ // //////////////////////////////////////
+
+
+ @javax.inject.Inject
+ private CommandServiceJdoRepository commandServiceRepository;
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoRepository.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoRepository.java b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoRepository.java
new file mode 100644
index 0000000..8d573a2
--- /dev/null
+++ b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdoRepository.java
@@ -0,0 +1,169 @@
+/**
+ * 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.objectstore.jdo.applib.service.command;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.LocalDate;
+
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.CommandContext;
+
+
+/**
+ * Provides supporting functionality for querying and persisting
+ * {@link org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo command} entities.
+ *
+ * <p>
+ * This supporting service with no UI and no side-effects, and is there are no other implementations of the service,
+ * thus has been annotated with {@link org.apache.isis.applib.annotation.DomainService}. This means that there is no
+ * need to explicitly register it as a service (eg in <tt>isis.properties</tt>).
+ */
+@DomainService
+public class CommandServiceJdoRepository extends AbstractFactoryAndRepository {
+
+ @Programmatic
+ public List<CommandJdo> findByFromAndTo(
+ final LocalDate from, final LocalDate to) {
+ final Timestamp fromTs = toTimestampStartOfDayWithOffset(from, 0);
+ final Timestamp toTs = toTimestampStartOfDayWithOffset(to, 1);
+
+ final Query<CommandJdo> query;
+ if(from != null) {
+ if(to != null) {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTimestampBetween",
+ "from", fromTs,
+ "to", toTs);
+ } else {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTimestampAfter",
+ "from", fromTs);
+ }
+ } else {
+ if(to != null) {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTimestampBefore",
+ "to", toTs);
+ } else {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "find");
+ }
+ }
+ return allMatches(query);
+ }
+
+
+ @Programmatic
+ public CommandJdo findByTransactionId(final UUID transactionId) {
+ persistCurrentCommandIfRequired();
+ return firstMatch(
+ new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTransactionId",
+ "transactionId", transactionId));
+ }
+
+ @Programmatic
+ public List<CommandJdo> findCurrent() {
+ persistCurrentCommandIfRequired();
+ return allMatches(
+ new QueryDefault<CommandJdo>(CommandJdo.class, "findCurrent"));
+ }
+
+ @Programmatic
+ public List<CommandJdo> findCompleted() {
+ persistCurrentCommandIfRequired();
+ return allMatches(
+ new QueryDefault<CommandJdo>(CommandJdo.class, "findCompleted"));
+ }
+
+ private void persistCurrentCommandIfRequired() {
+ if(commandContext == null || commandService == null) {
+ return;
+ }
+ final Command command = commandContext.getCommand();
+ final CommandJdo commandJdo = commandService.asUserInitiatedCommandJdo(command);
+ if(commandJdo == null) {
+ return;
+ }
+ persistIfNotAlready(commandJdo);
+ }
+
+ // //////////////////////////////////////
+
+
+ @Programmatic
+ public List<CommandJdo> findByTargetAndFromAndTo(
+ final Bookmark target, final LocalDate from, final LocalDate to) {
+ final String targetStr = target.toString();
+ final Timestamp fromTs = toTimestampStartOfDayWithOffset(from, 0);
+ final Timestamp toTs = toTimestampStartOfDayWithOffset(to, 1);
+
+ final Query<CommandJdo> query;
+ if(from != null) {
+ if(to != null) {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTargetAndTimestampBetween",
+ "targetStr", targetStr,
+ "from", fromTs,
+ "to", toTs);
+ } else {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTargetAndTimestampAfter",
+ "targetStr", targetStr,
+ "from", fromTs);
+ }
+ } else {
+ if(to != null) {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTargetAndTimestampBefore",
+ "targetStr", targetStr,
+ "to", toTs);
+ } else {
+ query = new QueryDefault<CommandJdo>(CommandJdo.class,
+ "findByTarget",
+ "targetStr", targetStr);
+ }
+ }
+ return allMatches(query);
+ }
+
+ private static Timestamp toTimestampStartOfDayWithOffset(final LocalDate dt, int daysOffset) {
+ return dt!=null
+ ?new java.sql.Timestamp(dt.toDateTimeAtStartOfDay().plusDays(daysOffset).getMillis())
+ :null;
+ }
+
+ // //////////////////////////////////////
+
+
+ @javax.inject.Inject
+ private CommandServiceJdo commandService;
+
+ @javax.inject.Inject
+ private CommandContext commandContext;
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/service/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/service/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.java b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/service/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.java
new file mode 100644
index 0000000..9c22561
--- /dev/null
+++ b/mothballed/core/module-command-jdo/src/main/java/org/apache/isis/objectstore/jdo/service/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.java
@@ -0,0 +1,49 @@
+/*
+ * 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.objectstore.jdo.service;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.core.runtime.services.background.BackgroundCommandExecution;
+import org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoRepository;
+import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
+
+/**
+ * If used, ensure that <code>org.apache.isis.module:isis-module-background</code> is also included on classpath.
+ */
+public final class BackgroundCommandExecutionFromBackgroundCommandServiceJdo extends BackgroundCommandExecution {
+
+ @SuppressWarnings("unused")
+ private final static Logger LOG = LoggerFactory.getLogger(BackgroundCommandExecutionFromBackgroundCommandServiceJdo.class);
+
+ @Override
+ protected List<? extends Command> findBackgroundCommandsToExecute() {
+ final List<CommandJdo> commands = backgroundCommandRepository.findBackgroundCommandsNotYetStarted();
+ return commands;
+ }
+
+ // //////////////////////////////////////
+
+ @javax.inject.Inject
+ private BackgroundCommandServiceJdoRepository backgroundCommandRepository;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/main/resources/images/CommandJdo.png
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/main/resources/images/CommandJdo.png b/mothballed/core/module-command-jdo/src/main/resources/images/CommandJdo.png
new file mode 100644
index 0000000..7545614
Binary files /dev/null and b/mothballed/core/module-command-jdo/src/main/resources/images/CommandJdo.png differ
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-command-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdoTest_next.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-command-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdoTest_next.java b/mothballed/core/module-command-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdoTest_next.java
new file mode 100644
index 0000000..b5443e2
--- /dev/null
+++ b/mothballed/core/module-command-jdo/src/test/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdoTest_next.java
@@ -0,0 +1,43 @@
+/*
+ * 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.objectstore.jdo.applib.service.command;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
+
+public class CommandJdoTest_next {
+
+ @Test
+ public void test() {
+ CommandJdo raj = new CommandJdo();
+ assertThat(raj.next("foo"), is(0));
+ assertThat(raj.next("foo"), is(1));
+ assertThat(raj.next("bar"), is(0));
+ assertThat(raj.next("bar"), is(1));
+ assertThat(raj.next("foo"), is(2));
+ assertThat(raj.next("bar"), is(2));
+ assertThat(raj.next("bar"), is(3));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/.gitignore
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/.gitignore b/mothballed/core/module-devutils/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/mothballed/core/module-devutils/.gitignore
@@ -0,0 +1 @@
+/target-ide
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/applib/.gitignore
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/applib/.gitignore b/mothballed/core/module-devutils/applib/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/mothballed/core/module-devutils/applib/.gitignore
@@ -0,0 +1 @@
+/target-ide
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/applib/pom.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/applib/pom.xml b/mothballed/core/module-devutils/applib/pom.xml
new file mode 100644
index 0000000..4e8f8f4
--- /dev/null
+++ b/mothballed/core/module-devutils/applib/pom.xml
@@ -0,0 +1,55 @@
+<?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.module</groupId>
+ <artifactId>isis-module-devutils</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>isis-module-devutils-applib</artifactId>
+
+ <name>Isis Module: Developer Utilities applib</name>
+ <description>
+ API for the Developer Utilities module
+ </description>
+
+ <properties>
+ <siteBaseDir>../..</siteBaseDir>
+ <relativeUrl>module-devutils/applib/</relativeUrl>
+ </properties>
+
+ <url>http://isis.apache.org/${relativeUrl}</url>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-applib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-unittestsupport</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/applib/src/main/java/org/apache/isis/applib/services/devutils/DeveloperUtilitiesService.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/applib/src/main/java/org/apache/isis/applib/services/devutils/DeveloperUtilitiesService.java b/mothballed/core/module-devutils/applib/src/main/java/org/apache/isis/applib/services/devutils/DeveloperUtilitiesService.java
new file mode 100644
index 0000000..6a25cfc
--- /dev/null
+++ b/mothballed/core/module-devutils/applib/src/main/java/org/apache/isis/applib/services/devutils/DeveloperUtilitiesService.java
@@ -0,0 +1,75 @@
+/**
+ * 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.applib.services.devutils;
+
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.NotInServiceMenu;
+import org.apache.isis.applib.annotation.Prototype;
+import org.apache.isis.applib.value.Blob;
+import org.apache.isis.applib.value.Clob;
+
+@Named("Developer Utilities")
+public interface DeveloperUtilitiesService {
+
+ @MemberOrder(sequence="1")
+ @ActionSemantics(Of.SAFE)
+ @Prototype
+ public Clob downloadMetaModel();
+
+
+ /**
+ * Downloads a zip of the layout of all domain classes.
+ */
+ @ActionSemantics(Of.SAFE)
+ @MemberOrder(sequence="3")
+ @Prototype
+ public Blob downloadLayouts();
+
+ /**
+ * Rebuilds the metamodel of all registered domain services.
+ */
+ @ActionSemantics(Of.SAFE)
+ @MemberOrder(sequence="3")
+ @Prototype
+ public void refreshServices();
+
+ /**
+ * Download the JSON layout of the domain object's type.
+ */
+ @NotInServiceMenu
+ @ActionSemantics(Of.SAFE)
+ @MemberOrder(sequence="2")
+ @Prototype
+ public Clob downloadLayout(Object domainObject);
+
+ /**
+ * @deprecated - in prototype mode the Wicket viewer (at least) will automatically invalidate
+ * the Isis metamodel whenever the object is re-rendered.
+ */
+ @Deprecated
+ @Hidden
+ @NotInServiceMenu
+ @ActionSemantics(Of.SAFE)
+ @MemberOrder(sequence="99")
+ @Prototype
+ public Object refreshLayout(Object domainObject);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/impl/.gitignore
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/impl/.gitignore b/mothballed/core/module-devutils/impl/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/mothballed/core/module-devutils/impl/.gitignore
@@ -0,0 +1 @@
+/target-ide
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/impl/pom.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/impl/pom.xml b/mothballed/core/module-devutils/impl/pom.xml
new file mode 100644
index 0000000..6b3c460
--- /dev/null
+++ b/mothballed/core/module-devutils/impl/pom.xml
@@ -0,0 +1,61 @@
+<?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.module</groupId>
+ <artifactId>isis-module-devutils</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>isis-module-devutils-impl</artifactId>
+
+ <name>Isis Module: Developer Utilities implementation</name>
+ <description>
+ Implementation of the Developer Utilities module
+ </description>
+
+ <properties>
+ <siteBaseDir>../..</siteBaseDir>
+ <relativeUrl>module-devutils/impl/</relativeUrl>
+ </properties>
+
+ <url>http://isis.apache.org/${relativeUrl}</url>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-devutils-applib</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-metamodel</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-unittestsupport</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/DeveloperUtilitiesServiceDefault.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/DeveloperUtilitiesServiceDefault.java b/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/DeveloperUtilitiesServiceDefault.java
new file mode 100644
index 0000000..d36746b
--- /dev/null
+++ b/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/DeveloperUtilitiesServiceDefault.java
@@ -0,0 +1,223 @@
+/*
+ * 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.metamodel.services.devutils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import org.apache.isis.applib.FatalException;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.devutils.DeveloperUtilitiesService;
+import org.apache.isis.applib.value.Blob;
+import org.apache.isis.applib.value.Clob;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.layoutmetadata.json.LayoutMetadataReaderFromJson;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpiAware;
+import org.apache.isis.core.metamodel.spec.feature.*;
+
+public class DeveloperUtilitiesServiceDefault implements DeveloperUtilitiesService, SpecificationLoaderSpiAware, AdapterManagerAware {
+
+
+ private final MimeType mimeTypeTextCsv;
+ private final MimeType mimeTypeApplicationZip;
+ private final MimeType mimeTypeApplicationJson;
+
+ public DeveloperUtilitiesServiceDefault() {
+ try {
+ mimeTypeTextCsv = new MimeType("text", "csv");
+ mimeTypeApplicationJson = new MimeType("application", "jzon");
+ mimeTypeApplicationZip = new MimeType("application", "zip");
+ } catch (MimeTypeParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // //////////////////////////////////////
+
+
+ @Override
+ public Clob downloadMetaModel() {
+
+ final Collection<ObjectSpecification> specifications = specificationLoader.allSpecifications();
+
+ final List<MetaModelRow> rows = Lists.newArrayList();
+ for (ObjectSpecification spec : specifications) {
+ if (exclude(spec)) {
+ continue;
+ }
+ final List<ObjectAssociation> properties = spec.getAssociations(Contributed.EXCLUDED, ObjectAssociation.Filters.PROPERTIES);
+ for (ObjectAssociation property : properties) {
+ final OneToOneAssociation otoa = (OneToOneAssociation) property;
+ if (exclude(otoa)) {
+ continue;
+ }
+ rows.add(new MetaModelRow(spec, otoa));
+ }
+ final List<ObjectAssociation> associations = spec.getAssociations(Contributed.EXCLUDED, ObjectAssociation.Filters.COLLECTIONS);
+ for (ObjectAssociation collection : associations) {
+ final OneToManyAssociation otma = (OneToManyAssociation) collection;
+ if (exclude(otma)) {
+ continue;
+ }
+ rows.add(new MetaModelRow(spec, otma));
+ }
+ final List<ObjectAction> actions = spec.getObjectActions(Contributed.INCLUDED);
+ for (ObjectAction action : actions) {
+ if (exclude(action)) {
+ continue;
+ }
+ rows.add(new MetaModelRow(spec, action));
+ }
+ }
+
+ Collections.sort(rows);
+
+ final StringBuilder buf = new StringBuilder();
+ buf.append(MetaModelRow.header()).append("\n");
+ for (MetaModelRow row : rows) {
+ buf.append(row.asTextCsv()).append("\n");
+ }
+ return new Clob("metamodel.csv", mimeTypeTextCsv, buf.toString().toCharArray());
+ }
+
+ protected boolean exclude(OneToOneAssociation property) {
+ return false;
+ }
+
+ protected boolean exclude(OneToManyAssociation collection) {
+ return false;
+ }
+
+ protected boolean exclude(ObjectAction action) {
+ return false;
+ }
+
+ protected boolean exclude(ObjectSpecification spec) {
+ return isBuiltIn(spec) || spec.isAbstract();
+ }
+
+ protected boolean isBuiltIn(ObjectSpecification spec) {
+ final String className = spec.getFullIdentifier();
+ return className.startsWith("java") || className.startsWith("org.joda");
+ }
+
+ // //////////////////////////////////////
+
+ @Override
+ public void refreshServices() {
+ Collection<ObjectSpecification> specifications = Lists.newArrayList(specificationLoader.allSpecifications());
+ for (ObjectSpecification objectSpec : specifications) {
+ if(objectSpec.isService()){
+ specificationLoader.invalidateCache(objectSpec.getCorrespondingClass());
+ }
+ }
+ }
+
+ // //////////////////////////////////////
+
+ @Override
+ public Object refreshLayout(Object domainObject) {
+ specificationLoader.invalidateCacheFor(domainObject);
+ return domainObject;
+ }
+
+ // //////////////////////////////////////
+
+ @Override
+ public Clob downloadLayout(Object domainObject) {
+
+ final ObjectAdapter adapterFor = adapterManager.adapterFor(domainObject);
+ final ObjectSpecification objectSpec = adapterFor.getSpecification();
+
+ final LayoutMetadataReaderFromJson propertiesReader = new LayoutMetadataReaderFromJson();
+ final String json = propertiesReader.asJson(objectSpec);
+
+ return new Clob(objectSpec.getShortIdentifier() +".layout.json", mimeTypeApplicationJson, json);
+ }
+
+ // //////////////////////////////////////
+
+ @Override
+ public Blob downloadLayouts() {
+ final LayoutMetadataReaderFromJson propertiesReader = new LayoutMetadataReaderFromJson();
+ final Collection<ObjectSpecification> allSpecs = specificationLoader.allSpecifications();
+ final Collection<ObjectSpecification> domainObjectSpecs = Collections2.filter(allSpecs, new Predicate<ObjectSpecification>(){
+ @Override
+ public boolean apply(ObjectSpecification input) {
+ return !input.isAbstract() &&
+ !input.isService() &&
+ !input.isValue() &&
+ !input.isParentedOrFreeCollection();
+ }});
+ try {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ZipOutputStream zos = new ZipOutputStream(baos);
+ OutputStreamWriter writer = new OutputStreamWriter(zos);
+ for (ObjectSpecification objectSpec : domainObjectSpecs) {
+ zos.putNextEntry(new ZipEntry(zipEntryNameFor(objectSpec)));
+ writer.write(propertiesReader.asJson(objectSpec));
+ writer.flush();
+ zos.closeEntry();
+ }
+ writer.close();
+ return new Blob("layouts.zip", mimeTypeApplicationZip, baos.toByteArray());
+ } catch (final IOException ex) {
+ throw new FatalException("Unable to create zip of layouts", ex);
+ }
+ }
+
+ private static String zipEntryNameFor(ObjectSpecification objectSpec) {
+ final String fqn = objectSpec.getFullIdentifier();
+ return fqn.replace(".", File.separator)+".layout.json";
+ }
+
+
+ // //////////////////////////////////////
+
+ private SpecificationLoaderSpi specificationLoader;
+ private AdapterManager adapterManager;
+
+ @Programmatic
+ @Override
+ public void setSpecificationLoaderSpi(SpecificationLoaderSpi specificationLoader) {
+ this.specificationLoader = specificationLoader;
+ }
+
+ @Override
+ public void setAdapterManager(AdapterManager adapterManager) {
+ this.adapterManager = adapterManager;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/MetaModelRow.java
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/MetaModelRow.java b/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/MetaModelRow.java
new file mode 100644
index 0000000..a935972
--- /dev/null
+++ b/mothballed/core/module-devutils/impl/src/main/java/org/apache/isis/core/metamodel/services/devutils/MetaModelRow.java
@@ -0,0 +1,234 @@
+/**
+ * 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.metamodel.services.devutils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.SortedSet;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
+
+import org.apache.isis.applib.util.ObjectContracts;
+import org.apache.isis.core.commons.lang.StringExtensions;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionChoicesFacet;
+import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
+import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
+import org.apache.isis.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
+import org.apache.isis.core.metamodel.facets.param.defaults.ActionParameterDefaultsFacet;
+import org.apache.isis.core.metamodel.facets.properties.autocomplete.PropertyAutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.facets.actions.validate.ActionValidationFacet;
+import org.apache.isis.core.metamodel.facets.collections.validate.CollectionValidateAddToFacet;
+import org.apache.isis.core.metamodel.facets.collections.validate.CollectionValidateRemoveFromFacet;
+import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
+import org.apache.isis.core.metamodel.facets.properties.validating.PropertyValidateFacet;
+
+public class MetaModelRow implements Comparable<MetaModelRow>{
+
+ enum MemberType {
+ PROPERTY,
+ COLLECTION,
+ ACTION;
+ }
+
+ private final ObjectSpecification spec;
+ private final MemberType memberType;
+ private final ObjectMember member;
+ private ObjectAction action;
+
+ MetaModelRow(ObjectSpecification spec, OneToOneAssociation property) {
+ this.spec = spec;
+ this.member = property;
+ this.memberType = MemberType.PROPERTY;
+ }
+
+ MetaModelRow(ObjectSpecification spec, OneToManyAssociation collection) {
+ this.spec = spec;
+ this.member = collection;
+ this.memberType = MemberType.COLLECTION;
+ }
+
+ MetaModelRow(ObjectSpecification spec, ObjectAction action) {
+ this.spec = spec;
+ this.member = this.action = action;
+ this.memberType = MemberType.ACTION;
+ }
+
+ public String getClassType() {
+ boolean service = false;
+ for(ObjectSpecification subspecs: spec.subclasses()) {
+ service = service || subspecs.isService();
+ }
+ return service || spec.isService() ?"2 Service":spec.isValue()?"3 Value":spec.isParentedOrFreeCollection()?"4 Collection":"1 Object";
+ }
+ public String getClassName() {
+ final String fullIdentifier = spec.getFullIdentifier();
+ final int lastDot = fullIdentifier.lastIndexOf(".");
+ return lastDot>0 && lastDot < fullIdentifier.length()-1
+ ?fullIdentifier.substring(lastDot+1,fullIdentifier.length())
+ :fullIdentifier;
+ }
+ public String getPackageName() {
+ final String fullIdentifier = spec.getFullIdentifier();
+ final int lastDot = fullIdentifier.lastIndexOf(".");
+ return lastDot>0?fullIdentifier.substring(0,lastDot):fullIdentifier;
+ }
+ public String getType() {
+ return memberType.name().toLowerCase();
+ }
+ public String getMemberName() {
+ return member.getId();
+ }
+ public String getNumParams() {
+ return action!=null?""+action.getParameterCount():"";
+ }
+ String getHidden() {
+ return interpret(HiddenFacet.class);
+ }
+ String getDisabled() {
+ return interpret(DisabledFacet.class);
+ }
+ public String getChoices() {
+ if(memberType == MemberType.PROPERTY) {
+ return interpretRowAndFacet(PropertyChoicesFacet.class);
+ } else if(memberType == MemberType.COLLECTION) {
+ return "";
+ } else {
+ final List<ObjectActionParameter> parameters = this.action.getParameters();
+ final SortedSet<String> interpretations = Sets.newTreeSet();
+ for (ObjectActionParameter param : parameters) {
+ final ActionParameterChoicesFacet facet = param.getFacet(ActionParameterChoicesFacet.class);
+ addIfNotEmpty(interpretFacet(facet), interpretations);
+ }
+ return !interpretations.isEmpty()? Joiner.on(";").join(interpretations) : interpretRowAndFacet(ActionChoicesFacet.class);
+ }
+ }
+ public String getAutoComplete() {
+ if(memberType == MemberType.PROPERTY) {
+ return interpretRowAndFacet(PropertyAutoCompleteFacet.class);
+ } else if(memberType == MemberType.COLLECTION) {
+ return "";
+ } else {
+ final List<ObjectActionParameter> parameters = this.action.getParameters();
+ final SortedSet<String> interpretations = Sets.newTreeSet();
+ for (ObjectActionParameter param : parameters) {
+ final ActionParameterAutoCompleteFacet facet = param.getFacet(ActionParameterAutoCompleteFacet.class);
+ addIfNotEmpty(interpretFacet(facet), interpretations);
+ }
+ return !interpretations.isEmpty()? Joiner.on(";").join(interpretations) : "";
+ }
+ }
+ String getDefault() {
+ if(memberType == MemberType.PROPERTY) {
+ return interpretRowAndFacet(PropertyDefaultFacet.class);
+ } else if(memberType == MemberType.COLLECTION) {
+ return "";
+ } else {
+ final List<ObjectActionParameter> parameters = this.action.getParameters();
+ final SortedSet<String> interpretations = Sets.newTreeSet();
+ for (ObjectActionParameter param : parameters) {
+ final ActionParameterDefaultsFacet facet = param.getFacet(ActionParameterDefaultsFacet.class);
+ addIfNotEmpty(interpretFacet(facet), interpretations);
+ }
+ return !interpretations.isEmpty()? Joiner.on(";").join(interpretations) : interpretRowAndFacet(ActionDefaultsFacet.class);
+ }
+ }
+ String getValidate() {
+ if(memberType == MemberType.PROPERTY) {
+ return interpretRowAndFacet(PropertyValidateFacet.class);
+ } else if(memberType == MemberType.COLLECTION) {
+ final SortedSet<String> interpretations = Sets.newTreeSet();
+ addIfNotEmpty(interpretRowAndFacet(CollectionValidateAddToFacet.class), interpretations);
+ addIfNotEmpty(interpretRowAndFacet(CollectionValidateRemoveFromFacet.class), interpretations);
+ return !interpretations.isEmpty()? Joiner.on(";").join(interpretations) : "";
+ } else {
+ return interpretRowAndFacet(ActionValidationFacet.class);
+ }
+ }
+
+ static Object header() {
+ return "classType,packageName,className,memberType,memberName,numParams,hidden,disabled,choices,autoComplete,default,validate";
+ }
+
+ String asTextCsv() {
+ return Joiner.on(",").join(
+ getClassType(),
+ getPackageName(),
+ getClassName(),
+ getType(),
+ getMemberName(),
+ getNumParams(),
+ getHidden(),
+ getDisabled(),
+ getChoices(),
+ getAutoComplete(),
+ getDefault(),
+ getValidate());
+ }
+
+ private String interpretRowAndFacet(Class<? extends Facet> facetClass) {
+ final Facet facet = member.getFacet(facetClass);
+ return interpretFacet(facet);
+ }
+
+ private static void addIfNotEmpty(final String str, final SortedSet<String> set) {
+ if(!Strings.isNullOrEmpty(str)) {
+ set.add(str);
+ }
+ }
+
+ private String interpret(final Class<? extends Facet> cls) {
+ return interpretFacet(member.getFacet(cls));
+ }
+
+ private static String interpretFacet(final Facet facet) {
+ if (facet == null || facet.isNoop()) {
+ return "";
+ }
+ if (facet instanceof ImperativeFacet) {
+ ImperativeFacet imperativeFacet = (ImperativeFacet) facet;
+ return imperativeFacet.getMethods().get(0).getName();
+ }
+ final String name = facet.getClass().getSimpleName();
+ if (ignore(name)) {
+ return "";
+ }
+ final String abbr = StringExtensions.toAbbreviation(name);
+ return abbr.length()>0 ? abbr : name;
+ }
+
+ protected static boolean ignore(final String name) {
+ return Arrays.asList("PropertyValidateFacetDefault","PropertyDefaultFacetDerivedFromDefaultedFacet").contains(name);
+ }
+
+ @Override
+ public int compareTo(MetaModelRow o) {
+ return ObjectContracts.compare(this, o, "classType,className,type desc,memberName");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-devutils/pom.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-devutils/pom.xml b/mothballed/core/module-devutils/pom.xml
new file mode 100644
index 0000000..bae27b3
--- /dev/null
+++ b/mothballed/core/module-devutils/pom.xml
@@ -0,0 +1,94 @@
+<?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.core</groupId>
+ <artifactId>isis</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-devutils</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Isis Module: Developer Utilities</name>
+ <description>
+ Developer utilities.
+ </description>
+
+ <properties>
+ <siteBaseDir>..</siteBaseDir>
+ <relativeUrl>module-devutils/</relativeUrl>
+ </properties>
+
+ <url>http://isis.apache.org/${relativeUrl}</url>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-devutils-applib</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-devutils-applib</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-devutils-impl</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-devutils-impl</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-applib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-unittestsupport</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <modules>
+ <module>applib</module>
+ <module>impl</module>
+ </modules>
+
+</project>
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/.gitignore
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/.gitignore b/mothballed/core/module-publishing-jdo/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/.gitignore
@@ -0,0 +1 @@
+/target-ide
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/pom.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/pom.xml b/mothballed/core/module-publishing-jdo/pom.xml
new file mode 100644
index 0000000..420125e
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/pom.xml
@@ -0,0 +1,147 @@
+<?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.core</groupId>
+ <artifactId>isis</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.isis.module</groupId>
+ <artifactId>isis-module-publishing-jdo</artifactId>
+
+ <name>Isis Module: Publishing (JDO Implementation)</name>
+ <description>
+ PublishingService implementation that persists published events
+ to the database (using JDO Objectstore).
+ </description>
+
+ <properties>
+ <siteBaseDir>..</siteBaseDir>
+ <relativeUrl>module-publishing/</relativeUrl>
+ </properties>
+
+ <url>http://isis.apache.org/${relativeUrl}</url>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <filtering>false</filtering>
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.datanucleus</groupId>
+ <artifactId>datanucleus-maven-plugin</artifactId>
+ <version>${datanucleus-maven-plugin.version}</version>
+ <configuration>
+ <fork>false</fork>
+ <verbose>true</verbose>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>compile</phase>
+ <goals>
+ <goal>enhance</goal>
+ </goals>
+ </execution>
+ </executions>
+ </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.datanucleus
+ </groupId>
+ <artifactId>
+ datanucleus-maven-plugin
+ </artifactId>
+ <versionRange>
+ [3.2.0-release,)
+ </versionRange>
+ <goals>
+ <goal>enhance</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-applib</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.isis.core</groupId>
+ <artifactId>isis-core-unittestsupport</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <!-- DataNucleus (jdo-api, and for enhancer) -->
+ <dependency>
+ <groupId>org.datanucleus</groupId>
+ <artifactId>datanucleus-accessplatform-jdo-rdbms</artifactId>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>org.datanucleus</groupId>
+ <artifactId>datanucleus-jodatime</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/isis/blob/790e70df/mothballed/core/module-publishing-jdo/src/main/java/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/mothballed/core/module-publishing-jdo/src/main/java/META-INF/persistence.xml b/mothballed/core/module-publishing-jdo/src/main/java/META-INF/persistence.xml
new file mode 100644
index 0000000..1cb71dd
--- /dev/null
+++ b/mothballed/core/module-publishing-jdo/src/main/java/META-INF/persistence.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+ <persistence-unit name="isis-module-publishing-jdo">
+ </persistence-unit>
+</persistence>