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 2012/12/06 11:10:34 UTC
[21/51] [partial] ISIS-188: moving modules into core
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileService.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileService.java b/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileService.java
new file mode 100644
index 0000000..020e538
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileService.java
@@ -0,0 +1,48 @@
+/*
+ * 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.fixtures.userprofile;
+
+import org.apache.isis.applib.fixtures.UserProfileFixture;
+import org.apache.isis.applib.fixtures.switchuser.SwitchUserService;
+import org.apache.isis.applib.profiles.Perspective;
+import org.apache.isis.applib.profiles.Profile;
+
+/**
+ * Not intended to be used directly; decouples the {@link UserProfileFixture},
+ * which needs to persist {@link Perspective}s, from the rest of the framework's
+ * runtime.
+ *
+ * <p>
+ * A suitable implementation is injected into {@link UserProfileFixture} when
+ * installed.
+ *
+ * @see SwitchUserService
+ */
+public interface UserProfileService {
+
+ Profile newUserProfile();
+
+ Profile newUserProfile(Profile profile);
+
+ void saveForUser(String name, Profile profile);
+
+ void saveAsDefault(Profile profile);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileServiceAware.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileServiceAware.java b/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileServiceAware.java
new file mode 100644
index 0000000..c11a45a
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/UserProfileServiceAware.java
@@ -0,0 +1,34 @@
+/*
+ * 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.fixtures.userprofile;
+
+import org.apache.isis.applib.fixtures.UserProfileFixture;
+
+/**
+ * Not intended to be implemented directly; is implemented by
+ * {@link UserProfileFixture}.
+ *
+ * <p>
+ * If using perspectives then subclass from {@link UserProfileFixture}.
+ */
+public interface UserProfileServiceAware {
+
+ public void setService(UserProfileService perspectiveInstaller);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/package-info.java
new file mode 100644
index 0000000..26b413e
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/fixtures/userprofile/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides support for installing a user profile fixture.
+ *
+ * <p>
+ * Not expected to be used by domain objects, but decouples the fixtures from
+ * the framework (which provides the implementation of {@link org.apache.isis.applib.fixtures.userprofile.UserProfileService}).
+ */
+package org.apache.isis.applib.fixtures.userprofile;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/AlwaysImmutable.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/AlwaysImmutable.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/AlwaysImmutable.java
new file mode 100644
index 0000000..701d2c1
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/AlwaysImmutable.java
@@ -0,0 +1,31 @@
+/*
+ * 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.marker;
+
+import org.apache.isis.applib.annotation.Immutable;
+
+/**
+ * Marker interface to show that an object cannot be changed once created.
+ *
+ * Use {@link Immutable} annotation in preference to this marker interface.
+ */
+public interface AlwaysImmutable {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/Bounded.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/Bounded.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/Bounded.java
new file mode 100644
index 0000000..51b9448
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/Bounded.java
@@ -0,0 +1,29 @@
+/*
+ * 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.marker;
+
+/**
+ * Marker interface to indicate that a class has a static set of instances; they
+ * are loaded on first use and are not refreshed.
+ *
+ * Use {@link Bounded} annotation in preference to this marker interface.
+ */
+public interface Bounded {
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableOncePersisted.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableOncePersisted.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableOncePersisted.java
new file mode 100644
index 0000000..f8c4d06
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableOncePersisted.java
@@ -0,0 +1,31 @@
+/*
+ * 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.marker;
+
+import org.apache.isis.applib.annotation.Immutable;
+
+/**
+ * Marker interface to show that an object cannot be changed once persisted.
+ *
+ * Use {@link Immutable} annotation in preference to this marker interface.
+ */
+public interface ImmutableOncePersisted {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableUntilPersisted.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableUntilPersisted.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableUntilPersisted.java
new file mode 100644
index 0000000..e9dd70f
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ImmutableUntilPersisted.java
@@ -0,0 +1,32 @@
+/*
+ * 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.marker;
+
+import org.apache.isis.applib.annotation.Immutable;
+
+/**
+ * Marker interface to show that an object cannot be changed before it is
+ * persisted.
+ *
+ * Use {@link Immutable} annotation in preference to this marker interface.
+ */
+public interface ImmutableUntilPersisted {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NeverImmutable.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NeverImmutable.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NeverImmutable.java
new file mode 100644
index 0000000..cc54581
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NeverImmutable.java
@@ -0,0 +1,32 @@
+/*
+ * 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.marker;
+
+import org.apache.isis.applib.annotation.Immutable;
+
+/**
+ * Marker interface to show that an object can always be changed, even after
+ * persisted.
+ *
+ * Use {@link Immutable} annotation in preference to this marker interface.
+ */
+public interface NeverImmutable {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NonPersistable.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NonPersistable.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NonPersistable.java
new file mode 100644
index 0000000..6895a6d
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/NonPersistable.java
@@ -0,0 +1,31 @@
+/*
+ * 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.marker;
+
+import org.apache.isis.applib.annotation.NotPersisted;
+
+/**
+ * Marker interface to show that an object cannot be persisted.
+ *
+ * Use {@link NotPersisted} annotation in preference to this marker interface.
+ */
+public interface NonPersistable {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ProgramPersistable.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ProgramPersistable.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ProgramPersistable.java
new file mode 100644
index 0000000..90f19f4
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/ProgramPersistable.java
@@ -0,0 +1,31 @@
+/*
+ * 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.marker;
+
+import org.apache.isis.applib.annotation.NotPersisted;
+
+/**
+ * Marker interface to show that an object cannot be persisted.
+ *
+ * Use {@link NotPersisted} annotation in preference to this marker interface.
+ */
+public interface ProgramPersistable {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/marker/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/marker/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/package-info.java
new file mode 100644
index 0000000..28feffe
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/marker/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * Marker interfaces that are used to declare semantics relating to domain
+ * types.
+ *
+ * <p>
+ * All of the interfaces defined in this package have equivalent annotations,
+ * and generally we recommend that annotations are used instead.
+ */
+package org.apache.isis.applib.marker;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/package-info.java
new file mode 100644
index 0000000..b9b33f2
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/package-info.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+/**
+ * The application library defines the annotations, interfaces and
+ * supporting utilities that are part of the overall Apache Isis
+ * Programming Model.
+ *
+ * <p>
+ * This package contains adapter classes which can optionally be used for
+ * {@link org.apache.isis.applib.AbstractDomainObject entities}, for
+ * {@link org.apache.isis.applib.AbstractService domain services} and for
+ * {@link org.apache.isis.applib.AbstractFactoryAndRepository repositories}.
+ *
+ * <p>
+ * In addition, it contains a {@link org.apache.isis.applib.Identifier class}
+ * that represents the identifier of an object or object member, used for
+ * example in the <tt>events</tt> package as well as internally within the
+ * framework.
+ */
+package org.apache.isis.applib;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Localization.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Localization.java b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Localization.java
new file mode 100644
index 0000000..be3137d
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Localization.java
@@ -0,0 +1,30 @@
+/*
+ * 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.profiles;
+
+import java.util.Locale;
+import java.util.TimeZone;
+
+public interface Localization {
+
+ Locale getLocale();
+
+ TimeZone getTimeZone();
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Perspective.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Perspective.java b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Perspective.java
new file mode 100644
index 0000000..cd18bde
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Perspective.java
@@ -0,0 +1,59 @@
+/*
+ * 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.profiles;
+
+import org.apache.isis.applib.fixtures.UserProfileFixture;
+
+/**
+ * Domain object representing a particular perspective on the services or
+ * objects available to a logged-in user.
+ *
+ * <p>
+ * The word "perspective" is used here in a similar sense to the Eclipse IDE,
+ * meaning a configuration of objects. You might also think of it as the user's
+ * desktop (though that metaphor only makes sense with the DnD viewer).
+ *
+ * <p>
+ * Note that this type is an interface, not a class. The actual implementation
+ * is provided by the framework itself.
+ *
+ * <p>
+ * {@link Perspective}s go together with {@link Profile}s: a {@link Profile} is
+ * a container of multiple {@link Perspective}s. As such, {@link Perspective}s
+ * can be created from {@link Profile}s; {@link Profile}s themselves are created
+ * using the {@link UserProfileFixture} can be used. Thereafter the @{link
+ * Profile} and its {@link Perspective}s are stored in a <tt>profilestore</tt>
+ * (analogous to an object store).
+ */
+public interface Perspective {
+
+ Object addToServices(Class<?> serviceClass);
+
+ void removeFromServices(Class<?> serviceClass);
+
+ void addToServices(Class<?>... serviceClasses);
+
+ void removeFromServices(Class<?>... serviceClasses);
+
+ void addGenericRepository(Class<?>... domainClasses);
+
+ void addToObjects(Object... object);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Profile.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Profile.java b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Profile.java
new file mode 100644
index 0000000..8ad67d4
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/Profile.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.applib.profiles;
+
+import org.apache.isis.applib.fixtures.UserProfileFixture;
+
+/**
+ * Domain object representing a collection of options or preferences for a user,
+ * along with a set of {@link Perspective} s for that user.
+ *
+ * <p>
+ * Note that this type is an interface, not a class. The actual implementation
+ * is provided by the framework itself.
+ *
+ * <p>
+ * {@link Perspective}s go together with {@link Profile}s: a {@link Profile} is
+ * a container of multiple {@link Perspective}s. As such, {@link Perspective}s
+ * can be created from {@link Profile}s; {@link Profile}s themselves are created
+ * using the {@link UserProfileFixture} can be used. Thereafter the @{link
+ * Profile} and its {@link Perspective}s are stored in a <tt>profilestore</tt>
+ * (analogous to an object store).
+ */
+public interface Profile {
+
+ void addToOptions(String name, String value);
+
+ Perspective newPerspective(String name);
+
+ void addToPerspectives(Perspective perspective);
+
+ Perspective getPerspective(String name);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/package-info.java
new file mode 100644
index 0000000..baefae8
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/profiles/package-info.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Defines interfaces for domain objects that constitute the framework's
+ * view of a "user profile".
+ *
+ * <p>
+ * Each user can hold a single {@link org.apache.isis.applib.profiles.Profile},
+ * which in turn can hold option settings (eg preferred colour theme) and
+ * {@link org.apache.isis.applib.profiles.Perspective}s (a particular
+ * arrangement of the user interface; the terminology comes from the Eclipse
+ * RCP/IDE platform).
+ *
+ * <p>
+ * The use and surfacing of these capabilities is dependent on the viewer;
+ * most notably the drag-n-drop viewer does support the concept of a user
+ * profile, but many others do not.
+ */
+package org.apache.isis.applib.profiles;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/query/Query.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/query/Query.java b/framework/core/applib/src/main/java/org/apache/isis/applib/query/Query.java
new file mode 100644
index 0000000..d04895a
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/query/Query.java
@@ -0,0 +1,53 @@
+/*
+ * 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.query;
+
+import java.io.Serializable;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.filter.Filter;
+
+/**
+ * For use by repository implementations, representing the values of a query.
+ *
+ * <p>
+ * The implementations of these objects are be provided by the underlying
+ * persistor/object store; consult its documentation.
+ *
+ * <p>
+ * <b>Note:</b> that not every object store will necessarily support this
+ * interface. In particular, the in-memory object store does not. For this, you
+ * can use the {@link Filter} interface to similar effect, for example in
+ * {@link DomainObjectContainer#allMatches(Class, Filter)}). Note that the
+ * filtering is done within the {@link DomainObjectContainer} rather than being
+ * pushed back to the object store.
+ */
+public interface Query<T> extends Serializable {
+
+ /**
+ * The {@link Class} of the objects returned by this query.
+ */
+ public Class<T> getResultType();
+
+ /**
+ * A human-readable representation of this query and its values.
+ */
+ public String getDescription();
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryAbstract.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryAbstract.java b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryAbstract.java
new file mode 100644
index 0000000..57263f6
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryAbstract.java
@@ -0,0 +1,69 @@
+/*
+ * 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.query;
+
+/**
+ * Convenience adapter class for {@link Query}.
+ *
+ * <p>
+ * Handles implementation of {@link #getResultType()}
+ */
+public abstract class QueryAbstract<T> implements Query<T> {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String resultTypeName;
+ /**
+ * Derived from {@link #getResultTypeName()}, with respect to the
+ * {@link Thread#getContextClassLoader() current thread's class loader}.
+ */
+ private transient Class<T> resultType;
+
+ public QueryAbstract(final Class<T> type) {
+ this.resultTypeName = type.getName();
+ }
+
+ public QueryAbstract(final String typeName) {
+ this.resultTypeName = typeName;
+ }
+
+ /**
+ * @throws IllegalStateException
+ * (wrapping a {@link ClassNotFoundException}) if the class
+ * could not be determined.
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public Class<T> getResultType() {
+ if (resultType == null) {
+ try {
+ resultType = (Class<T>) Thread.currentThread().getContextClassLoader().loadClass(resultTypeName);
+ } catch (final ClassNotFoundException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ return resultType;
+ }
+
+ public String getResultTypeName() {
+ return resultTypeName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryBuiltInAbstract.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryBuiltInAbstract.java b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryBuiltInAbstract.java
new file mode 100644
index 0000000..4a973c6
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryBuiltInAbstract.java
@@ -0,0 +1,57 @@
+/*
+ * 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.query;
+
+import java.io.Serializable;
+
+import org.apache.isis.applib.DomainObjectContainer;
+
+/**
+ * Although (through this class) the subclasses implements {@link Query} and
+ * thus are meant to be {@link Serializable}, this isn't actually required of
+ * the built-in queries because they are all converted into corresponding
+ * <tt>PersistenceQuery</tt> in the runtime for remoting purposes.
+ *
+ * <p>
+ * The principle reason for this is to reduce the size of the API from the
+ * {@link DomainObjectContainer} to <tt>RuntimeContext</tt>. It also means that the
+ * requirements for writing an object store are more easily expressed: support
+ * the three built-in queries, plus any others.
+ *
+ * <p>
+ * Note also that the {@link QueryFindByPattern} isn't actually serializable
+ * (because it references an arbitrary pojo).
+ *
+ * <p>
+ * REVIEW: now that we've dropped remoting, could we get rid of the <tt>PersistenceQuery</tt>
+ * classes and just use these classes throughout?
+ */
+public abstract class QueryBuiltInAbstract<T> extends QueryAbstract<T> {
+
+ private static final long serialVersionUID = 1L;
+
+ public QueryBuiltInAbstract(final Class<T> type) {
+ super(type);
+ }
+
+ public QueryBuiltInAbstract(final String typeName) {
+ super(typeName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryDefault.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryDefault.java b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryDefault.java
new file mode 100644
index 0000000..5a855fd
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryDefault.java
@@ -0,0 +1,105 @@
+/*
+ * 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.query;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Default implementation of {@link Query} that supports parameter/argument
+ * values, along with a query name.
+ */
+public class QueryDefault<T> extends QueryAbstract<T> {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Convenience factory method, preferable to
+ * {@link #QueryDefault(Class, String, Object...) constructor} because will
+ * automatically genericize.
+ */
+ public static <Q> QueryDefault<Q> create(final Class<Q> resultType, final String queryName, final Object... paramArgs) {
+ return new QueryDefault<Q>(resultType, queryName, paramArgs);
+ }
+
+ /**
+ * Convenience factory method, preferable to
+ * {@link #QueryDefault(Class, String, Map) constructor} because will
+ * automatically genericize.
+ */
+ public static <Q> QueryDefault<Q> create(final Class<Q> resultType, final String queryName, final Map<String, Object> argumentsByParameterName) {
+ return new QueryDefault<Q>(resultType, queryName, argumentsByParameterName);
+ }
+
+ /**
+ * Converts a list of objects [a, 1, b, 2] into a map {a -> 1; b -> 2}
+ */
+ private static Map<String, Object> asMap(final Object[] paramArgs) {
+ final HashMap<String, Object> map = new HashMap<String, Object>();
+ boolean param = true;
+ String paramStr = null;
+ for (final Object paramArg : paramArgs) {
+ if (param) {
+ if (paramArg instanceof String) {
+ paramStr = (String) paramArg;
+ } else {
+ throw new IllegalArgumentException("Parameter must be a string");
+ }
+ } else {
+ final Object arg = paramArg;
+ map.put(paramStr, arg);
+ paramStr = null;
+ }
+ param = !param;
+ }
+ if (paramStr != null) {
+ throw new IllegalArgumentException("Must have equal number of parameters and arguments");
+ }
+ return map;
+ }
+
+ private final String queryName;
+ private final Map<String, Object> argumentsByParameterName;
+
+ public QueryDefault(final Class<T> resultType, final String queryName, final Object... paramArgs) {
+ this(resultType, queryName, asMap(paramArgs));
+ }
+
+ public QueryDefault(final Class<T> resultType, final String queryName, final Map<String, Object> argumentsByParameterName) {
+ super(resultType);
+ this.queryName = queryName;
+ this.argumentsByParameterName = argumentsByParameterName;
+ }
+
+ public String getQueryName() {
+ return queryName;
+ }
+
+ public Map<String, Object> getArgumentsByParameterName() {
+ return Collections.unmodifiableMap(argumentsByParameterName);
+ }
+
+ @Override
+ public String getDescription() {
+ return getQueryName() + " with " + getArgumentsByParameterName();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryFindAllInstances.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryFindAllInstances.java b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryFindAllInstances.java
new file mode 100644
index 0000000..93c86ea
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/query/QueryFindAllInstances.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.applib.query;
+
+import java.io.Serializable;
+
+/**
+ * Although implements {@link Query} and thus is intended to be (and indeed is)
+ * {@link Serializable}, it will be converted into a <tt>PersistenceQuery</tt>
+ * in the runtime for remoting purposes.
+ *
+ * <p>
+ * See discussion in {@link QueryBuiltInAbstract} for further details.
+ */
+public class QueryFindAllInstances<T> extends QueryBuiltInAbstract<T> {
+
+ private static final long serialVersionUID = 1L;
+
+ public QueryFindAllInstances(final Class<T> type) {
+ super(type);
+ }
+
+ public QueryFindAllInstances(final String typeName) {
+ super(typeName);
+ }
+
+ @Override
+ public String getDescription() {
+ return getResultTypeName() + " (all instances)";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/query/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/query/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/query/package-info.java
new file mode 100644
index 0000000..1d7db70
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/query/package-info.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package defines the {@link org.apache.isis.applib.query.Query} interface
+ * and supporting implementations.
+ *
+ * <p>
+ * The {@link org.apache.isis.applib.query.Query} concept is provided as a
+ * standardized mechanism by which
+ * {@link org.apache.isis.applib.AbstractFactoryAndRepository repositories}
+ * or indeed any {@link org.apache.isis.applib.AbstractDomainObject domain object}
+ * can submit. Object store implementation are generally expected to support
+ * the {@link org.apache.isis.applib.query.QueryBuiltInAbstract built-in queries},
+ * meaning that there may not be any need to provide different implementations
+ * of the repositories. (This provides some of the benefits that .NET has
+ * with its LINQ technology, though it is admittedly nowhere near as
+ * sophisticated).
+ */
+package org.apache.isis.applib.query;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/security/RoleMemento.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/security/RoleMemento.java b/framework/core/applib/src/main/java/org/apache/isis/applib/security/RoleMemento.java
new file mode 100644
index 0000000..21a25f6
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/security/RoleMemento.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.applib.security;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.NotPersistable;
+
+@NotPersistable
+public final class RoleMemento {
+
+ /**
+ * Creates a new role with the specified name. Description is left blank.
+ */
+ public RoleMemento(final String name) {
+ this(name, "");
+ }
+
+ /**
+ * Creates a new role with the specified name and description.
+ */
+ public RoleMemento(final String name, final String description) {
+ if (name == null) {
+ throw new IllegalArgumentException("Name not specified");
+ }
+ this.name = name;
+ if (description == null) {
+ throw new IllegalArgumentException("Description not specified");
+ }
+ this.description = description;
+ }
+
+ // {{ Identification
+ public String title() {
+ return name;
+ }
+
+ // }}
+
+ // {{ Name
+ private final String name;
+
+ @MemberOrder(sequence = "1.1")
+ public String getName() {
+ return name;
+ }
+
+ // }}
+
+ // {{ Description
+ private final String description;
+
+ @MemberOrder(sequence = "1.2")
+ public String getDescription() {
+ return description;
+ }
+ // }}
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/security/UserMemento.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/security/UserMemento.java b/framework/core/applib/src/main/java/org/apache/isis/applib/security/UserMemento.java
new file mode 100644
index 0000000..ccfe1bd
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/security/UserMemento.java
@@ -0,0 +1,137 @@
+/*
+ * 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.security;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.NotPersistable;
+
+/**
+ * Details, obtained from the container, about the user and his roles.
+ * Read-only.
+ */
+@NotPersistable
+public final class UserMemento {
+
+ /**
+ * Creates a new user with the specified name and no roles.
+ */
+ public UserMemento(final String name) {
+ this(name, new RoleMemento[0]);
+ }
+
+ /**
+ * Creates a new user with the specified name and assigned roles.
+ */
+ public UserMemento(final String name, final RoleMemento... roles) {
+ this(name, Arrays.asList(roles));
+ }
+
+ /**
+ * Creates a new user with the specified name and assigned roles.
+ */
+ public UserMemento(final String name, final List<RoleMemento> roles) {
+ if (name == null) {
+ throw new IllegalArgumentException("Name not specified");
+ }
+ this.name = name;
+ this.roles.addAll(roles);
+ }
+
+ // {{ Identification: Title
+ public String title() {
+ return name;
+ }
+
+ // }}
+
+ // {{ (User) Name, isCurrentUser
+ private final String name;
+
+ /**
+ * The user's login name.
+ */
+ @MemberOrder(sequence = "1.1")
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Determine if the specified name is this user.
+ *
+ * <p>
+ *
+ * @return true if the names match (is case sensitive).
+ */
+ public boolean isCurrentUser(final String userName) {
+ if (userName == null) {
+ throw new IllegalArgumentException("no user name provided");
+ }
+ return name.equals(userName);
+ }
+
+ // }}
+
+ // {{ Roles
+ private final List<RoleMemento> roles = new ArrayList<RoleMemento>();
+
+ /**
+ * The roles associated with this user.
+ */
+ @MemberOrder(sequence = "1.1")
+ public List<RoleMemento> getRoles() {
+ return roles;
+ }
+
+ /**
+ * Determines if the user fulfills the specified role.
+ */
+ public boolean hasRole(final RoleMemento role) {
+ return hasRole(role.getName());
+ }
+
+ /**
+ * Determines if the user fulfills the specified role. Roles are compared
+ * lexically by role name.
+ */
+ public boolean hasRole(final String roleName) {
+ for (final RoleMemento role : roles) {
+ if (role.getName().equals(roleName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // }}
+
+ @Override
+ public String toString() {
+ final StringBuilder buf = new StringBuilder();
+ for (final RoleMemento role : roles) {
+ buf.append(role.getName()).append(" ");
+ }
+ return "User [name=" + getName() + ",roles=" + buf.toString() + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/security/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/security/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/security/package-info.java
new file mode 100644
index 0000000..d604694
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/security/package-info.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package defines types that represent the
+ * currently logged-in {@link org.apache.isis.applib.security.UserMemento user}
+ * and their {@link org.apache.isis.applib.security.RoleMemento role}s.
+ *
+ * <p>
+ * Typically domain objects do not need to have any knowledge of <i>who</i>
+ * is using them, because authorization is provided declaratively by the
+ * framework and is type-based. However, there are occasions; for example,
+ * only an <tt>Employee</tt> and his superiors might be allowed to view their salary.
+ *
+ * <p>
+ * The types are suffixed "Memento" because they snapshot the user
+ * and roles at the time that the user logs in, but are not updated after that
+ * point.
+ */
+package org.apache.isis.applib.security;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/Snapshottable.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/Snapshottable.java b/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/Snapshottable.java
new file mode 100644
index 0000000..2445bd4
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/Snapshottable.java
@@ -0,0 +1,28 @@
+/*
+ * 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.snapshot;
+
+/**
+ * Marker interface for domain objects that can be snapshot using
+ * <xx>XmlSnapshot</tt>.
+ */
+public interface Snapshottable {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/SnapshottableWithInclusions.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/SnapshottableWithInclusions.java b/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/SnapshottableWithInclusions.java
new file mode 100644
index 0000000..3091165
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/SnapshottableWithInclusions.java
@@ -0,0 +1,34 @@
+/*
+ * 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.snapshot;
+
+import java.util.List;
+
+/**
+ * Optional subinterface of {@link Snapshottable}s, used by <tt>XmlSnapshot</tt>
+ * to automatically include additional paths within the snapshot.
+ */
+public interface SnapshottableWithInclusions extends Snapshottable {
+
+ /**
+ * Paths to include in the snapshot.
+ */
+ List<String> snapshotInclusions();
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/package-info.java
new file mode 100644
index 0000000..9fd0d91
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/snapshot/package-info.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package defines a marker {@link org.apache.isis.applib.snapshot.Snapshottable interface}
+ * that indicates that the implementing domain object can be "snapshotted"
+ * into an XML format using a utility class provided by the framework.
+ *
+ * <p>
+ * The extent of the data within the XML snapshot can be controlled programmatically,
+ * typically by the object creating the snapshot. If the responsibility for knowing
+ * what should go into the XML is actually in the
+ * {@link org.apache.isis.applib.snapshot.Snapshottable}
+ * domain object itself, then the {@link org.apache.isis.applib.snapshot.SnapshottableWithInclusions}
+ * interface can be used instead.
+ *
+ * <p>
+ * The utility class that is used to create the snapshot is called
+ * <tt>XmlSnapshot</tt>, and resides within the <tt>core.runtime</tt> module.
+ * Best practice is to define a <tt>SnapshotService</tt>
+ * interface as a domain service, and whose implementation will delegate to the
+ * <tt>XmlSnapshot</tt>. This approach ensures that the domain objects do not
+ * have any coupling to the framework.
+ */
+package org.apache.isis.applib.snapshot;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/spec/AbstractSpecification.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/spec/AbstractSpecification.java b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/AbstractSpecification.java
new file mode 100644
index 0000000..f883ee7
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/AbstractSpecification.java
@@ -0,0 +1,107 @@
+/*
+ * 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.spec;
+
+import java.lang.reflect.Method;
+
+/**
+ * Adapter to make it easy to write {@link Specification}s.
+ *
+ * <p>
+ * Provides two main features:
+ * <ul>
+ * <li>first, is type-safe (with invalid type being either ignored or
+ * constituting a failure), and
+ * <li>second, checks for nulls (with a null either being ignore or again
+ * constituting a failure)
+ * </ul>
+ *
+ * <p>
+ * Implementation note: inspired by (borrowed code from) Hamcrest's
+ * <tt>TypeSafeMatcher</tt>.
+ */
+public abstract class AbstractSpecification<T> implements Specification {
+
+ public enum TypeChecking {
+ ENSURE_CORRECT_TYPE, IGNORE_INCORRECT_TYPE,
+ }
+
+ public enum Nullability {
+ ENSURE_NOT_NULL, IGNORE_IF_NULL
+ }
+
+ private static Class<?> findExpectedType(final Class<?> fromClass) {
+ for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
+ for (final Method method : c.getDeclaredMethods()) {
+ if (isSatisfiesSafelyMethod(method)) {
+ return method.getParameterTypes()[0];
+ }
+ }
+ }
+
+ throw new Error("Cannot determine correct type for satisfiesSafely() method.");
+ }
+
+ private static boolean isSatisfiesSafelyMethod(final Method method) {
+ return method.getName().equals("satisfiesSafely") && method.getParameterTypes().length == 1 && !method.isSynthetic();
+ }
+
+ private final Class<?> expectedType;
+ private final Nullability nullability;
+ private final TypeChecking typeChecking;
+
+ protected AbstractSpecification() {
+ this(Nullability.IGNORE_IF_NULL, TypeChecking.IGNORE_INCORRECT_TYPE);
+ }
+
+ protected AbstractSpecification(final Nullability nullability, final TypeChecking typeChecking) {
+ this.expectedType = findExpectedType(getClass());
+ this.nullability = nullability;
+ this.typeChecking = typeChecking;
+ }
+
+ /**
+ * Checks not null and is correct type, and delegates to
+ * {@link #satisfiesSafely(Object)}.
+ */
+ @Override
+ @SuppressWarnings({ "unchecked" })
+ public final String satisfies(final Object obj) {
+ if (obj == null) {
+ return nullability == Nullability.IGNORE_IF_NULL ? null : "Cannot be null";
+ }
+ if (!expectedType.isInstance(obj)) {
+ return typeChecking == TypeChecking.IGNORE_INCORRECT_TYPE ? null : "Incorrect type";
+ }
+ final T objAsT = (T) obj;
+ return satisfiesSafely(objAsT);
+ }
+
+ /**
+ * If <tt>null</tt> then satisfied, otherwise is reason why the
+ * specification is not satisfied.
+ *
+ * <p>
+ * Subclasses should implement this. The item will already have been checked
+ * for the specific type and will never be null.
+ */
+ public abstract String satisfiesSafely(T obj);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/spec/Specification.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/spec/Specification.java b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/Specification.java
new file mode 100644
index 0000000..d52c2c2
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/Specification.java
@@ -0,0 +1,33 @@
+/*
+ * 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.spec;
+
+/**
+ * An implementation of the <i>Specification</i> pattern, as described in Eric
+ * Evans' <i>Domain Driven Design</i>, p224.
+ */
+public interface Specification {
+
+ /**
+ * If <tt>null</tt> then satisfied, otherwise is reason why the
+ * specification is not satisfied.
+ */
+ public String satisfies(Object obj);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationAnd.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationAnd.java b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationAnd.java
new file mode 100644
index 0000000..9c69d52
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationAnd.java
@@ -0,0 +1,64 @@
+/*
+ * 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.spec;
+
+import org.apache.isis.applib.util.ReasonBuffer;
+
+/**
+ * Adapter to make it easy to perform boolean algebra on {@link Specification}s.
+ *
+ * <p>
+ * Subclasses represent the intersection of multiple {@link Specification}s. An
+ * implementation should instantiate the {@link Specification}s to be satisfied
+ * in its constructor.
+ *
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class MilkAndSugarSpec extends SpecificationAnd {
+ * public MilkAndSugarSpec() {
+ * super(new MustBeMilkySpec(), new TwoLumpsOfSugarSpec());
+ * }
+ * }
+ * </pre>
+ *
+ * @see SpecificationOr
+ * @see SpecificationNot
+ */
+public abstract class SpecificationAnd implements Specification {
+
+ private final Specification[] specifications;
+
+ public SpecificationAnd(final Specification... specifications) {
+ this.specifications = specifications;
+ }
+
+ @Override
+ public String satisfies(final Object obj) {
+ final ReasonBuffer buf = new ReasonBuffer();
+ for (final Specification specification : specifications) {
+ final String reasonNotSatisfiedIfAny = specification.satisfies(obj);
+ buf.append(reasonNotSatisfiedIfAny);
+ }
+ return buf.getReason(); // may be null if all were satisfied.
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationNot.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationNot.java b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationNot.java
new file mode 100644
index 0000000..deb725e
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationNot.java
@@ -0,0 +1,60 @@
+/*
+ * 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.spec;
+
+/**
+ * Adapter to make it easy to perform boolean algebra on {@link Specification}s.
+ *
+ * <p>
+ * <p>
+ * Subclasses represent the logical inverse of a {@link Specification}s. An
+ * implementation should instantiate the {@link Specification}s to be satisfied
+ * in its constructor.
+ *
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class NoSugarThanksSpec extends SpecificationNot {
+ * public NoSugarThanksSpec() {
+ * super(
+ * new TwoLumpsOfSugarSpec(),
+ * );
+ * }
+ * }
+ * </pre>
+ *
+ * @see SpecificationAnd
+ * @see SpecificationOr
+ */
+public abstract class SpecificationNot implements Specification {
+
+ private final Specification specification;
+
+ public SpecificationNot(final Specification specification) {
+ this.specification = specification;
+ }
+
+ @Override
+ public String satisfies(final Object obj) {
+ final String satisfies = specification.satisfies(obj);
+ return satisfies != null ? null : "not satisfied";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationOr.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationOr.java b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationOr.java
new file mode 100644
index 0000000..ff14561
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/SpecificationOr.java
@@ -0,0 +1,68 @@
+/*
+ * 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.spec;
+
+import org.apache.isis.applib.util.ReasonBuffer;
+
+/**
+ * Adapter to make it easy to perform boolean algebra on {@link Specification}s.
+ *
+ * <p>
+ * Subclasses represent the conjunction of multiple {@link Specification}s. An
+ * implementation should instantiate the {@link Specification}s to be satisfied
+ * in its constructor.
+ *
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * public class TeaOrCoffeeSpec extends SpecificationOr {
+ * public TeaOrCoffeeSpec() {
+ * super(new MustBeTeaSpec(), new MustBeCoffeeSpec());
+ * }
+ * }
+ * </pre>
+ *
+ * @see SpecificationAnd
+ * @see SpecificationNot
+ */
+public abstract class SpecificationOr implements Specification {
+
+ private final Specification[] specifications;
+
+ public SpecificationOr(final Specification... specifications) {
+ this.specifications = specifications;
+ }
+
+ @Override
+ public String satisfies(final Object obj) {
+ final ReasonBuffer buf = new ReasonBuffer();
+ for (final Specification specification : specifications) {
+ final String reasonNotSatisfiedIfAny = specification.satisfies(obj);
+ if (reasonNotSatisfiedIfAny == null) {
+ // at least one is ok, so all is ok.
+ return null;
+ }
+ buf.append(reasonNotSatisfiedIfAny);
+ }
+ return buf.getReason(); // may be null if all were satisfied.
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/spec/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/spec/package-info.java b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/package-info.java
new file mode 100644
index 0000000..bc9ca20
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/spec/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package defines a {@link org.apache.isis.applib.spec.Specification}
+ * interface (and various implementations), used by the
+ * {@link org.apache.isis.applib.annotation.MustSatisfy} annotation to
+ * declare valid values for properties or parameters.
+ *
+ * <p>
+ * This is an implementation of the DDD "Specification", allowing
+ * validatation that might otherwise be repeated for both properties and
+ * parameters (in the <tt>validateXxx()</tt> methods to be factored out.
+ *
+ * <p>
+ * That said, there is still some repetition in that the {@link org.apache.isis.applib.annotation.MustSatisfy}
+ * annotation must be applied in all appropriate cases. If it is the case that
+ * the validation rules would apply <i>every</i> case, then it is generally
+ * preferable to implement a {@link org.apache.isis.applib.annotation.Value} type
+ * through the {@link org.apache.isis.applib.adapters.ValueSemanticsProvider}
+ * interface.
+ */
+package org.apache.isis.applib.spec;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/util/Enums.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/util/Enums.java b/framework/core/applib/src/main/java/org/apache/isis/applib/util/Enums.java
new file mode 100644
index 0000000..bfc6549
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/util/Enums.java
@@ -0,0 +1,107 @@
+/*
+ * 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.util;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+
+public final class Enums {
+
+ private Enums(){}
+
+ public static String getFriendlyNameOf(Enum<?> anEnum) {
+ return getFriendlyNameOf(anEnum.name());
+ }
+
+ public static String getFriendlyNameOf(String anEnumName) {
+ return Joiner.on(" ").join(Iterables.transform(Splitter.on("_").split(anEnumName), LOWER_CASE_THEN_CAPITALIZE));
+ }
+
+
+ public static String getEnumNameFromFriendly(String anEnumFriendlyName) {
+ return Joiner.on("_").join(Iterables.transform(Splitter.on(" ").split(anEnumFriendlyName), UPPER_CASE));
+ }
+
+
+ public static String enumToHttpHeader(final Enum<?> anEnum) {
+ return enumNameToHttpHeader(anEnum.name());
+ }
+
+ public static String enumNameToHttpHeader(final String name) {
+ final StringBuilder builder = new StringBuilder();
+ boolean nextUpper = true;
+ for (final char c : name.toCharArray()) {
+ if (c == '_') {
+ nextUpper = true;
+ builder.append("-");
+ } else {
+ builder.append(nextUpper ? c : Character.toLowerCase(c));
+ nextUpper = false;
+ }
+ }
+ return builder.toString();
+ }
+
+ public static String enumToCamelCase(final Enum<?> anEnum) {
+ return enumNameToCamelCase(anEnum.name());
+ }
+
+ private static String enumNameToCamelCase(final String name) {
+ final StringBuilder builder = new StringBuilder();
+ boolean nextUpper = false;
+ for (final char c : name.toCharArray()) {
+ if (c == '_') {
+ nextUpper = true;
+ } else {
+ builder.append(nextUpper ? c : Character.toLowerCase(c));
+ nextUpper = false;
+ }
+ }
+ return builder.toString();
+ }
+
+
+ private static Function<String, String> LOWER_CASE_THEN_CAPITALIZE = new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return capitalize(input.toLowerCase());
+ }
+ };
+
+ private static Function<String, String> UPPER_CASE = new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return input.toUpperCase();
+ }
+ };
+
+ private static String capitalize(final String str) {
+ if (str == null || str.length() == 0) {
+ return str;
+ }
+ if (str.length() == 1) {
+ return str.toUpperCase();
+ }
+ return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/util/ReasonBuffer.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/util/ReasonBuffer.java b/framework/core/applib/src/main/java/org/apache/isis/applib/util/ReasonBuffer.java
new file mode 100644
index 0000000..89b59dc
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/util/ReasonBuffer.java
@@ -0,0 +1,67 @@
+/*
+ * 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.util;
+
+/**
+ * Helper class to create properly concatenated reason string for use in method
+ * that return {@link String}s with reasons.
+ *
+ * <p>
+ * If no reasons are specified {@link #getReason()} will return
+ * <code>null</code> , otherwise it will return a {@link String} with all the
+ * valid reasons concatenated with a semi-colon separating each one.
+ *
+ * <p>
+ * An alternative is to use the {@link Reasons} class.
+ */
+public class ReasonBuffer {
+ StringBuffer reasonBuffer = new StringBuffer();
+
+ /**
+ * Append a reason to the list of existing reasons.
+ */
+ public void append(final String reason) {
+ if (reason != null) {
+ if (reasonBuffer.length() > 0) {
+ reasonBuffer.append("; ");
+ }
+ reasonBuffer.append(reason);
+ }
+ }
+
+ /**
+ * Append a reason to the list of existing reasons if the condition flag is
+ * true.
+ */
+ public void appendOnCondition(final boolean condition, final String reason) {
+ if (condition) {
+ append(reason);
+ }
+ }
+
+ /**
+ * Return the combined set of reasons, or <code>null</code> if there are
+ * none.
+ */
+ public String getReason() {
+ return reasonBuffer.length() == 0 ? null : reasonBuffer.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/util/Reasons.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/util/Reasons.java b/framework/core/applib/src/main/java/org/apache/isis/applib/util/Reasons.java
new file mode 100644
index 0000000..750e5c2
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/util/Reasons.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util;
+
+/**
+ * An alternative to {@link ReasonBuffer}.
+ */
+public class Reasons {
+ private Reasons() {
+ }
+
+ public static String coalesce(final String... reasons) {
+ final StringBuilder buf = new StringBuilder();
+ for (final String reason : reasons) {
+ appendIfNotNull(buf, reason);
+ }
+ return asStringElseNull(buf);
+ }
+
+ private static void appendIfNotNull(final StringBuilder buf, final String reason) {
+ if (reason == null) {
+ return;
+ }
+ if (buf.length() > 0) {
+ buf.append("; ");
+ }
+ buf.append(reason);
+ }
+
+ private static String asStringElseNull(final StringBuilder buf) {
+ return buf.length() == 0 ? null : buf.toString();
+ }
+
+}