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 18:42:17 UTC

[27/52] [partial] ISIS-188: moving framework/ subdirs up to parent

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.java
new file mode 100644
index 0000000..c92c0e8
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/IProxyFactory.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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+
+public interface IProxyFactory<T> {
+    T createProxy(Class<T> toProxyClass, InvocationHandler handler);
+
+    T createProxy(T toProxy, InvocationHandler handler);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.java
new file mode 100644
index 0000000..0515501
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcher.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.progmodel.wrapper.metamodel.internal;
+
+import org.apache.isis.applib.events.InteractionEvent;
+
+public interface InteractionEventDispatcher {
+
+    void dispatch(InteractionEvent interactionEvent);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.java
new file mode 100644
index 0000000..5ae80f6
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InteractionEventDispatcherTypeSafe.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.progmodel.wrapper.metamodel.internal;
+
+import org.apache.isis.applib.events.InteractionEvent;
+
+public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> implements InteractionEventDispatcher {
+
+    public abstract void dispatchTypeSafe(T interactionEvent);
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void dispatch(final InteractionEvent interactionEvent) {
+        dispatchTypeSafe((T) interactionEvent);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.java
new file mode 100644
index 0000000..ebdcb52
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/InvocationHandlerMethodInterceptor.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.
+ */
+
+package org.apache.isis.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+public class InvocationHandlerMethodInterceptor implements MethodInterceptor {
+    private final InvocationHandler handler;
+
+    InvocationHandlerMethodInterceptor(final InvocationHandler handler) {
+        this.handler = handler;
+    }
+
+    @Override
+    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
+        return handler.invoke(obj, method, args);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
new file mode 100644
index 0000000..173d777
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/JavaProxyFactory.java
@@ -0,0 +1,40 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+
+import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
+
+public class JavaProxyFactory<T> implements IProxyFactory<T> {
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final T toProxy, final InvocationHandler handler) {
+        final Class<T> proxyClass = (Class<T>) toProxy.getClass();
+        return (T) Proxy.newProxyInstance(proxyClass.getClassLoader(), new Class[] { proxyClass }, handler);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T createProxy(final Class<T> toProxy, final InvocationHandler handler) {
+        return (T) Proxy.newProxyInstance(toProxy.getClassLoader(), new Class[] { toProxy, WrapperObject.class }, handler);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.java
new file mode 100644
index 0000000..779afac
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/MapInvocationHandler.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.progmodel.wrapper.metamodel.internal;
+
+import static org.apache.isis.core.commons.lang.MethodUtils.getMethod;
+
+import java.util.Map;
+
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+class MapInvocationHandler<T, C> extends AbstractCollectionInvocationHandler<T, C> {
+
+    public MapInvocationHandler(final C collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+        super(collectionToProxy, collectionName, handler, otma);
+
+        try {
+            intercept(getMethod(collectionToProxy, "containsKey", Object.class));
+            intercept(getMethod(collectionToProxy, "containsValue", Object.class));
+            intercept(getMethod(collectionToProxy, "size"));
+            intercept(getMethod(collectionToProxy, "isEmpty"));
+            veto(getMethod(collectionToProxy, "put", Object.class, Object.class));
+            veto(getMethod(collectionToProxy, "remove", Object.class));
+            veto(getMethod(collectionToProxy, "putAll", Map.class));
+            veto(getMethod(collectionToProxy, "clear"));
+        } catch (final NoSuchMethodException e) {
+            // ///CLOVER:OFF
+            throw new RuntimeException("A Collection method could not be found: " + e.getMessage());
+            // ///CLOVER:ON
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.java
new file mode 100644
index 0000000..00028f1
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/ObjenesisClassInstantiatorCE.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.progmodel.wrapper.metamodel.internal;
+
+import org.objenesis.ObjenesisHelper;
+
+class ObjenesisClassInstantiatorCE implements IClassInstantiatorCE {
+
+    @Override
+    public Object newInstance(final Class<?> clazz) throws InstantiationException {
+        return ObjenesisHelper.newInstance(clazz);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
new file mode 100644
index 0000000..dbcf4bb
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/Proxy.java
@@ -0,0 +1,80 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.ensure.Ensure;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
+import org.apache.isis.progmodel.wrapper.applib.WrapperFactory.ExecutionMode;
+
+public class Proxy {
+
+    public static <T> T proxy(final T domainObject, final WrapperFactory wrapperFactory, final ExecutionMode mode, final AuthenticationSessionProvider authenticationSessionProvider, final SpecificationLoader specificationLookup, final AdapterManager adapterManager, final ObjectPersistor objectPersistor) {
+
+        Ensure.ensureThatArg(wrapperFactory, is(not(nullValue())));
+        Ensure.ensureThatArg(authenticationSessionProvider, is(not(nullValue())));
+        Ensure.ensureThatArg(specificationLookup, is(not(nullValue())));
+        Ensure.ensureThatArg(adapterManager, is(not(nullValue())));
+        Ensure.ensureThatArg(objectPersistor, is(not(nullValue())));
+
+        final DomainObjectInvocationHandler<T> invocationHandler = new DomainObjectInvocationHandler<T>(domainObject, wrapperFactory, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
+
+        final CgLibProxy<T> cglibProxy = new CgLibProxy<T>(invocationHandler);
+        return cglibProxy.proxy();
+    }
+
+    /**
+     * Whether to execute or not will be picked up from the supplied parent
+     * handler.
+     */
+    public static <T, E> Collection<E> proxy(final Collection<E> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+
+        final CollectionInvocationHandler<T, Collection<E>> collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(collectionToProxy, collectionName, handler, otma);
+        collectionInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+
+        final CgLibProxy<Collection<E>> cglibProxy = new CgLibProxy<Collection<E>>(collectionInvocationHandler);
+        return cglibProxy.proxy();
+    }
+
+    /**
+     * Whether to execute or not will be picked up from the supplied parent
+     * handler.
+     */
+    public static <T, P, Q> Map<P, Q> proxy(final Map<P, Q> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+
+        final MapInvocationHandler<T, Map<P, Q>> mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(collectionToProxy, collectionName, handler, otma);
+        mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+
+        final CgLibProxy<Map<P, Q>> cglibProxy = new CgLibProxy<Map<P, Q>>(mapInvocationHandler);
+        return cglibProxy.proxy();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.java
new file mode 100644
index 0000000..b6eae03
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/RuntimeExceptionWrapper.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.progmodel.wrapper.metamodel.internal;
+
+public class RuntimeExceptionWrapper extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private final RuntimeException runtimeException;
+
+    public RuntimeExceptionWrapper(final RuntimeException runtimeException) {
+        this.runtimeException = runtimeException;
+    }
+
+    public RuntimeException getRuntimeException() {
+        return runtimeException;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
new file mode 100644
index 0000000..ad22797
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/WrapperFactoryDefault.java
@@ -0,0 +1,271 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.events.ActionArgumentEvent;
+import org.apache.isis.applib.events.ActionInvocationEvent;
+import org.apache.isis.applib.events.ActionUsabilityEvent;
+import org.apache.isis.applib.events.ActionVisibilityEvent;
+import org.apache.isis.applib.events.CollectionAccessEvent;
+import org.apache.isis.applib.events.CollectionAddToEvent;
+import org.apache.isis.applib.events.CollectionMethodEvent;
+import org.apache.isis.applib.events.CollectionRemoveFromEvent;
+import org.apache.isis.applib.events.CollectionUsabilityEvent;
+import org.apache.isis.applib.events.CollectionVisibilityEvent;
+import org.apache.isis.applib.events.InteractionEvent;
+import org.apache.isis.applib.events.ObjectTitleEvent;
+import org.apache.isis.applib.events.ObjectValidityEvent;
+import org.apache.isis.applib.events.PropertyAccessEvent;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistorAware;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
+import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
+import org.apache.isis.progmodel.wrapper.applib.WrapperObject;
+import org.apache.isis.progmodel.wrapper.applib.listeners.InteractionListener;
+
+public class WrapperFactoryDefault implements WrapperFactory, AuthenticationSessionProviderAware, SpecificationLoaderAware, AdapterManagerAware, ObjectPersistorAware {
+
+    private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
+    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> dispatchersByEventClass = new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
+
+    private AuthenticationSessionProvider authenticationSessionProvider;
+    private SpecificationLoader specificationLookup;
+    private AdapterManager adapterManager;
+    private ObjectPersistor objectPersistor;
+
+    public WrapperFactoryDefault() {
+        dispatchersByEventClass.put(ObjectTitleEvent.class, new InteractionEventDispatcherTypeSafe<ObjectTitleEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ObjectTitleEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.objectTitleRead(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyAccessEvent.class, new InteractionEventDispatcherTypeSafe<PropertyAccessEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyAccessEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyAccessed(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(PropertyModifyEvent.class, new InteractionEventDispatcherTypeSafe<PropertyModifyEvent>() {
+            @Override
+            public void dispatchTypeSafe(final PropertyModifyEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.propertyModified(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionAccessEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAccessEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionAccessEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionAccessed(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionAddToEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAddToEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionAddToEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionAddedTo(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionRemoveFromEvent.class, new InteractionEventDispatcherTypeSafe<CollectionRemoveFromEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionRemoveFromEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionRemovedFrom(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionVisibilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionVisibilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionVisible(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionUsabilityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionUsabilityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionUsable(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionArgumentEvent.class, new InteractionEventDispatcherTypeSafe<ActionArgumentEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionArgumentEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionArgument(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ActionInvocationEvent.class, new InteractionEventDispatcherTypeSafe<ActionInvocationEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ActionInvocationEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.actionInvoked(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(ObjectValidityEvent.class, new InteractionEventDispatcherTypeSafe<ObjectValidityEvent>() {
+            @Override
+            public void dispatchTypeSafe(final ObjectValidityEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.objectPersisted(interactionEvent);
+                }
+            }
+        });
+        dispatchersByEventClass.put(CollectionMethodEvent.class, new InteractionEventDispatcherTypeSafe<CollectionMethodEvent>() {
+            @Override
+            public void dispatchTypeSafe(final CollectionMethodEvent interactionEvent) {
+                for (final InteractionListener l : getListeners()) {
+                    l.collectionMethodInvoked(interactionEvent);
+                }
+            }
+        });
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Views
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public <T> T wrap(final T domainObject) {
+        return wrap(domainObject, ExecutionMode.EXECUTE);
+    }
+
+    @Override
+    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
+        if (isWrapper(domainObject)) {
+            return domainObject;
+        }
+        return Proxy.proxy(domainObject, this, mode, authenticationSessionProvider, specificationLookup, adapterManager, objectPersistor);
+    }
+
+    @Override
+    public boolean isWrapper(final Object possibleWrapper) {
+        return possibleWrapper instanceof WrapperObject;
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public List<InteractionListener> getListeners() {
+        return listeners;
+    }
+
+    @Override
+    public boolean addInteractionListener(final InteractionListener listener) {
+        return listeners.add(listener);
+    }
+
+    @Override
+    public boolean removeInteractionListener(final InteractionListener listener) {
+        return listeners.remove(listener);
+    }
+
+    @Override
+    public void notifyListeners(final InteractionEvent interactionEvent) {
+        final InteractionEventDispatcher dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
+        if (dispatcher == null) {
+            throw new RuntimeException("Unknown InteractionEvent - register into dispatchers map");
+        }
+        dispatcher.dispatch(interactionEvent);
+    }
+
+    // /////////////////////////////////////////////////////////////
+    // Listeners
+    // /////////////////////////////////////////////////////////////
+
+    @Override
+    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
+        this.authenticationSessionProvider = authenticationSessionProvider;
+    }
+
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    @Override
+    public void setSpecificationLookup(final SpecificationLoader specificationLookup) {
+        this.specificationLookup = specificationLookup;
+    }
+
+    @Override
+    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
+        this.objectPersistor = objectPersistor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
new file mode 100644
index 0000000..2b743c5
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/Constants.java
@@ -0,0 +1,52 @@
+/*
+ *  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.progmodel.wrapper.metamodel.internal.util;
+
+public final class Constants {
+    private Constants() {
+    }
+
+    public static final String PREFIX_CHOICES = "choices";
+    public static final String PREFIX_DEFAULT = "default";
+    public static final String PREFIX_HIDE = "hide";
+    public static final String PREFIX_DISABLE = "disable";
+    public static final String PREFIX_VALIDATE_REMOVE_FROM = "validateRemoveFrom";
+    public static final String PREFIX_VALIDATE_ADD_TO = "validateAddTo";
+    public static final String PREFIX_VALIDATE = "validate";
+    public static final String PREFIX_REMOVE_FROM = "removeFrom";
+    public static final String PREFIX_ADD_TO = "addTo";
+    public static final String PREFIX_MODIFY = "modify";
+    public static final String PREFIX_CLEAR = "clear";
+    public static final String PREFIX_SET = "set";
+    public static final String PREFIX_GET = "get";
+
+    public final static String TITLE_METHOD_NAME = "title";
+    public final static String TO_STRING_METHOD_NAME = "toString";
+
+    /**
+     * Cannot invoke methods with these prefixes.
+     */
+    public final static String[] INVALID_PREFIXES = { PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, };
+
+    public final static String[] PROPERTY_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_MODIFY, PREFIX_CLEAR, PREFIX_DISABLE, PREFIX_VALIDATE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
+    public final static String[] COLLECTION_PREFIXES = { PREFIX_GET, PREFIX_SET, PREFIX_ADD_TO, PREFIX_REMOVE_FROM, PREFIX_DISABLE, PREFIX_VALIDATE_ADD_TO, PREFIX_VALIDATE_REMOVE_FROM, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES };
+    public final static String[] ACTION_PREFIXES = { PREFIX_VALIDATE, PREFIX_DISABLE, PREFIX_HIDE, PREFIX_DEFAULT, PREFIX_CHOICES, };
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.java
new file mode 100644
index 0000000..b2de21c
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/main/java/org/apache/isis/progmodel/wrapper/metamodel/internal/util/MethodPrefixFinder.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.progmodel.wrapper.metamodel.internal.util;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+
+public final class MethodPrefixFinder {
+
+    // a Linked Hash Set is used to ensure that the ordering is preserved.
+    public final static LinkedHashSet<String> ALL_PREFIXES = new LinkedHashSet<String>() {
+        private static final long serialVersionUID = 1L;
+        {
+            // collection prefixes are added first because we want to
+            // test validateAddTo and validateRemoveFrom before validate
+            addAll(Arrays.asList(Constants.COLLECTION_PREFIXES));
+            addAll(Arrays.asList(Constants.PROPERTY_PREFIXES));
+            addAll(Arrays.asList(Constants.ACTION_PREFIXES));
+        }
+    };
+
+    public String findPrefix(final String methodName) {
+        for (final String prefix : ALL_PREFIXES) {
+            if (methodName.startsWith(prefix)) {
+                return prefix;
+            }
+        }
+        return "";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt b/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt
new file mode 100644
index 0000000..1a1f4fa
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/index.apt
@@ -0,0 +1,22 @@
+~~  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.
+
+
+
+Headless Viewer
+ 
+ The <headless viewer> module provides the main implementation of the headless viewer functionality.

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt b/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt
new file mode 100644
index 0000000..c5d1200
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/site/apt/jottings.apt
@@ -0,0 +1,24 @@
+~~  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.
+
+
+
+Jottings
+ 
+  This page is to capture any random jottings relating to this module prior 
+  to being moved into formal documentation. 
+ 

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml b/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml
new file mode 100644
index 0000000..6def7c8
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/site/site.xml
@@ -0,0 +1,39 @@
+<?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>
+
+	<body>
+		<breadcrumbs>
+			<item name="Metamodel" href="index.html" />
+		</breadcrumbs>
+
+		<menu name="Wrapper Metamodel">
+			<item name="About" href="index.html" />
+            <item name="Jottings" href="jottings.html" />
+		</menu>
+
+        <menu name="Wrapper Modules">
+            <item name="Applib" href="../wrapper-applib/index.html" />
+            <item name="Metamodel" href="../wrapper-metamodel/index.html" />
+        </menu>
+
+        <menu name="Maven Reports" ref="reports" />
+	</body>
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java b/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
new file mode 100644
index 0000000..ba2c219
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject.java
@@ -0,0 +1,153 @@
+/*
+ *  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.progmodel.wrapper;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2.Mode;
+import org.apache.isis.progmodel.wrapper.applib.DisabledException;
+import org.apache.isis.progmodel.wrapper.applib.HiddenException;
+import org.apache.isis.progmodel.wrapper.applib.InvalidException;
+import org.apache.isis.progmodel.wrapper.applib.WrapperFactory;
+import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+import org.apache.isis.tck.dom.claimapp.employees.Employee;
+import org.apache.isis.tck.dom.claimapp.employees.EmployeeRepository;
+import org.apache.isis.tck.dom.claimapp.employees.EmployeeRepositoryImpl;
+
+public class WrappedFactoryDefaultTest_wrappedObject {
+
+    @Rule
+    public JUnitRuleMockery2 mockery = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY);
+
+    private EmployeeRepository employeeRepository;
+    // private ClaimRepository claimRepository;
+
+    private Employee employeeDO;
+    private Employee employeeWO;
+
+    private WrapperFactory wrapperFactory;
+
+    @Before
+    public void setUp() {
+
+        employeeRepository = new EmployeeRepositoryImpl();
+        // claimRepository = new ClaimRepositoryImpl();
+
+        employeeDO = new Employee();
+        employeeDO.setName("Smith");
+        employeeDO.setEmployeeRepository(employeeRepository); // would be done
+                                                              // by the
+                                                              // EmbeddedContext
+                                                              // impl
+
+        wrapperFactory = new WrapperFactoryDefault();
+        employeeWO = wrapperFactory.wrap(employeeDO);
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldWrapDomainObject() {
+        // then
+        assertThat(employeeWO, is(notNullValue()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldBeAbleToInjectIntoDomainObjects() {
+
+        // given
+        assertThat(employeeDO.getEmployeeRepository(), is(notNullValue()));
+
+        // then
+        assertThat(employeeWO.getEmployeeRepository(), is(notNullValue()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldBeAbleToReadVisibleProperty() {
+        // then
+        assertThat(employeeWO.getName(), is(employeeDO.getName()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = HiddenException.class)
+    public void shouldNotBeAbleToViewHiddenProperty() {
+        // given
+        employeeDO.whetherHideName = true;
+        // when
+        employeeWO.getName();
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test
+    public void shouldBeAbleToModifyEnabledPropertyUsingSetter() {
+        // when
+        employeeWO.setName("Jones");
+        // then
+        assertThat(employeeDO.getName(), is("Jones"));
+        assertThat(employeeWO.getName(), is(employeeDO.getName()));
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = DisabledException.class)
+    public void shouldNotBeAbleToModifyDisabledProperty() {
+        // given
+        employeeDO.reasonDisableName = "sorry, no change allowed";
+        // when
+        employeeWO.setName("Jones");
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = UnsupportedOperationException.class)
+    public void shouldNotBeAbleToModifyPropertyUsingModify() {
+        // when
+        employeeWO.modifyName("Jones");
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = UnsupportedOperationException.class)
+    public void shouldNotBeAbleToModifyPropertyUsingClear() {
+        // when
+        employeeWO.clearName();
+        // then should throw exception
+    }
+
+    @Ignore("TODO - moved from embedded runtime, need to re-enable")
+    @Test(expected = InvalidException.class)
+    public void shouldNotBeAbleToModifyPropertyIfInvalid() {
+        // given
+        employeeDO.reasonValidateName = "sorry, invalid data";
+        // when
+        employeeWO.setName("Jones");
+        // then should throw exception
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
----------------------------------------------------------------------
diff --git a/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java b/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
new file mode 100644
index 0000000..3d1a1e4
--- /dev/null
+++ b/component/progmodel/wrapper/wrapper-metamodel/src/test/java/org/apache/isis/progmodel/wrapper/WrappedFactoryDefaultTest_wrappedObject_transient.java
@@ -0,0 +1,251 @@
+/*
+ *  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.progmodel.wrapper;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.events.PropertyModifyEvent;
+import org.apache.isis.applib.events.PropertyUsabilityEvent;
+import org.apache.isis.applib.events.PropertyVisibilityEvent;
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.consent.Allow;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionResult;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
+import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacet;
+import org.apache.isis.core.progmodel.facets.members.disabled.staticmethod.DisabledFacetAlwaysEverywhere;
+import org.apache.isis.core.progmodel.facets.properties.accessor.PropertyAccessorFacetViaAccessor;
+import org.apache.isis.core.progmodel.facets.properties.modify.PropertySetterFacetViaSetterMethod;
+import org.apache.isis.core.runtime.authentication.standard.SimpleSession;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2.Mode;
+import org.apache.isis.progmodel.wrapper.applib.DisabledException;
+import org.apache.isis.progmodel.wrapper.metamodel.internal.WrapperFactoryDefault;
+import org.apache.isis.tck.dom.claimapp.employees.Employee;
+
+public class WrappedFactoryDefaultTest_wrappedObject_transient {
+
+    @Rule
+    public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private AdapterManager mockAdapterManager;
+    @Mock
+    private AuthenticationSessionProvider mockAuthenticationSessionProvider;
+    @Mock
+    private ObjectPersistor mockObjectPersistor;
+    @Mock
+    private SpecificationLoader mockSpecificationLookup;
+
+    private Employee employeeDO;
+    @Mock
+    private ObjectAdapter mockEmployeeAdapter;
+    @Mock
+    private ObjectSpecificationDefault mockEmployeeSpec;
+    @Mock
+    private OneToOneAssociation mockPasswordMember;
+    @Mock
+    private Identifier mockPasswordIdentifier;
+
+    @Mock
+    protected ObjectAdapter mockPasswordAdapter;
+    
+    private final String passwordValue = "12345678";
+
+    private final SimpleSession session = new SimpleSession("tester", Collections.<String>emptyList());
+
+    private List<Facet> facets;
+    private Method getPasswordMethod;
+    private Method setPasswordMethod;
+
+
+    private WrapperFactoryDefault wrapperFactory;
+    private Employee employeeWO;
+
+
+    @Before
+    public void setUp() throws Exception {
+
+        // employeeRepository = new EmployeeRepositoryImpl();
+        // claimRepository = new ClaimRepositoryImpl();
+
+        employeeDO = new Employee();
+        employeeDO.setName("Smith");
+        
+        getPasswordMethod = Employee.class.getMethod("getPassword");
+        setPasswordMethod = Employee.class.getMethod("setPassword", String.class);
+
+        wrapperFactory = new WrapperFactoryDefault();
+        wrapperFactory.setAdapterManager(mockAdapterManager);
+        wrapperFactory.setAuthenticationSessionProvider(mockAuthenticationSessionProvider);
+        wrapperFactory.setObjectPersistor(mockObjectPersistor);
+        wrapperFactory.setSpecificationLookup(mockSpecificationLookup);
+        
+        context.checking(new Expectations() {
+            {
+                allowing(mockAdapterManager).getAdapterFor(employeeDO);
+                will(returnValue(mockEmployeeAdapter));
+
+                allowing(mockAdapterManager).adapterFor(passwordValue);
+                will(returnValue(mockPasswordAdapter));
+
+                allowing(mockEmployeeAdapter).getSpecification();
+                will(returnValue(mockEmployeeSpec));
+
+                allowing(mockEmployeeAdapter).getObject();
+                will(returnValue(employeeDO));
+
+                allowing(mockPasswordAdapter).getObject();
+                will(returnValue(passwordValue));
+
+                allowing(mockPasswordMember).getIdentifier();
+                will(returnValue(mockPasswordIdentifier));
+
+                allowing(mockSpecificationLookup).loadSpecification(Employee.class);
+                will(returnValue(mockEmployeeSpec));
+                
+                allowing(mockEmployeeSpec).getMember(with(setPasswordMethod));
+                will(returnValue(mockPasswordMember));
+
+                allowing(mockEmployeeSpec).getMember(with(getPasswordMethod));
+                will(returnValue(mockPasswordMember));
+
+                allowing(mockPasswordMember).getName();
+                will(returnValue("password"));
+
+                allowing(mockAuthenticationSessionProvider).getAuthenticationSession();
+                will(returnValue(session));
+                
+                allowing(mockPasswordMember).isOneToOneAssociation();
+                will(returnValue(true));
+
+                allowing(mockPasswordMember).isOneToManyAssociation();
+                will(returnValue(false));
+            }
+        });
+
+        employeeWO = wrapperFactory.wrap(employeeDO);
+    }
+
+    @Test(expected = DisabledException.class)
+    public void shouldNotBeAbleToModifyProperty() {
+
+        // given
+        final DisabledFacet disabledFacet = new DisabledFacetAlwaysEverywhere(mockPasswordMember);
+        facets = Arrays.asList((Facet)disabledFacet, new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
+
+        final Consent visibilityConsent = new Allow(new InteractionResult(new PropertyVisibilityEvent(employeeDO, null)));
+
+        final InteractionResult usabilityInteractionResult = new InteractionResult(new PropertyUsabilityEvent(employeeDO, null));
+        usabilityInteractionResult.advise("disabled", disabledFacet);
+        final Consent usabilityConsent = new Veto(usabilityInteractionResult);
+
+        context.checking(new Expectations() {
+            {
+                allowing(mockPasswordMember).getFacets(with(any(Filter.class)));
+                will(returnValue(facets));
+                
+                allowing(mockPasswordMember).isVisible(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(visibilityConsent));
+                
+                allowing(mockPasswordMember).isUsable(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(usabilityConsent));
+            }
+        });
+        
+        // when
+        employeeWO.setPassword(passwordValue);
+        
+        // then should throw exception
+    }
+
+    @Test
+    public void canModifyProperty() {
+        // given
+
+        final Consent visibilityConsent = new Allow(new InteractionResult(new PropertyVisibilityEvent(employeeDO, mockPasswordIdentifier)));
+        final Consent usabilityConsent = new Allow(new InteractionResult(new PropertyUsabilityEvent(employeeDO, mockPasswordIdentifier)));
+        final Consent validityConsent = new Allow(new InteractionResult(new PropertyModifyEvent(employeeDO, mockPasswordIdentifier, passwordValue)));
+
+        context.checking(new Expectations() {
+            {
+                allowing(mockPasswordMember).isVisible(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(visibilityConsent));
+                
+                allowing(mockPasswordMember).isUsable(session, mockEmployeeAdapter, Where.ANYWHERE);
+                will(returnValue(usabilityConsent));
+                
+                allowing(mockPasswordMember).isAssociationValid(mockEmployeeAdapter, mockPasswordAdapter);
+                will(returnValue(validityConsent));
+            }
+        });
+
+        facets = Arrays.asList((Facet)new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
+        context.checking(new Expectations() {
+            {
+                one(mockPasswordMember).getFacets(with(any(Filter.class)));
+                will(returnValue(facets));
+                
+                one(mockPasswordMember).set(mockEmployeeAdapter, mockPasswordAdapter);
+            }
+        });
+
+        // when
+        employeeWO.setPassword(passwordValue);
+
+
+        // and given
+        facets = Arrays.asList((Facet)new PropertyAccessorFacetViaAccessor(getPasswordMethod, mockPasswordMember));
+        context.checking(new Expectations() {
+            {
+                one(mockPasswordMember).getFacets(with(any(Filter.class)));
+                will(returnValue(facets));
+                
+                one(mockPasswordMember).get(mockEmployeeAdapter);
+                will(returnValue(mockPasswordAdapter));
+            }
+        });
+
+        // then be allowed
+        assertThat(employeeWO.getPassword(), is(passwordValue));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/NOTICE
----------------------------------------------------------------------
diff --git a/component/security/NOTICE b/component/security/NOTICE
new file mode 100644
index 0000000..d391f54
--- /dev/null
+++ b/component/security/NOTICE
@@ -0,0 +1,7 @@
+Apache Isis
+Copyright 2010-2011 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/NOTICE
----------------------------------------------------------------------
diff --git a/component/security/file/NOTICE b/component/security/file/NOTICE
new file mode 100644
index 0000000..d391f54
--- /dev/null
+++ b/component/security/file/NOTICE
@@ -0,0 +1,7 @@
+Apache Isis
+Copyright 2010-2011 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/pom.xml
----------------------------------------------------------------------
diff --git a/component/security/file/pom.xml b/component/security/file/pom.xml
new file mode 100644
index 0000000..2c7dc1b
--- /dev/null
+++ b/component/security/file/pom.xml
@@ -0,0 +1,82 @@
+<?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</groupId>
+		<artifactId>isis-parent</artifactId>
+		<version>0.3.1-SNAPSHOT</version>
+		<relativePath>../../../isis-parent/pom.xml</relativePath>
+	</parent>
+
+	<groupId>org.apache.isis.security</groupId>
+	<artifactId>file</artifactId>
+
+	<name>File Security Implementation</name>
+
+	<properties>
+        <siteBaseDir>.</siteBaseDir>
+		<relativeUrl/>
+	</properties>
+
+    <!-- used in Site generation for relative references. -->
+    <url>http://incubator.apache.org/isis/${relativeUrl}</url>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+				<version>${maven-project-info-reports-plugin}</version>
+                <inherited>false</inherited>
+                <configuration>
+                	<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                </configuration>
+                <reportSets>
+                    <reportSet>
+                        <inherited>false</inherited>
+                        <reports>
+                            <report>dependencies</report>
+                            <report>dependency-convergence</report>
+                            <report>plugins</report>
+                            <report>summary</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+
+	<dependencies>
+		<dependency>
+		    <groupId>org.apache.isis.runtimes.dflt</groupId>
+		    <artifactId>runtime</artifactId>
+		<version>0.3.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+		    <groupId>org.apache.isis.runtimes.dflt</groupId>
+		    <artifactId>runtime</artifactId>
+		<version>0.3.1-SNAPSHOT</version>
+		    <type>test-jar</type>
+		    <scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationConstants.java
----------------------------------------------------------------------
diff --git a/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationConstants.java b/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationConstants.java
new file mode 100644
index 0000000..0155005
--- /dev/null
+++ b/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationConstants.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.security.file.authentication;
+
+public class FileAuthenticationConstants {
+
+    public static final String PASSWORDS_FILE = "authentication_file.passwords";
+
+    private FileAuthenticationConstants() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationManagerInstaller.java
----------------------------------------------------------------------
diff --git a/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationManagerInstaller.java b/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationManagerInstaller.java
new file mode 100644
index 0000000..356af52
--- /dev/null
+++ b/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticationManagerInstaller.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.security.file.authentication;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.runtime.authentication.standard.Authenticator;
+import org.apache.isis.runtimes.dflt.runtime.authentication.AuthenticationManagerStandardInstallerAbstractForDfltRuntime;
+
+public class FileAuthenticationManagerInstaller extends AuthenticationManagerStandardInstallerAbstractForDfltRuntime {
+
+    public static final String NAME = "file";
+
+    public FileAuthenticationManagerInstaller() {
+        super(NAME);
+    }
+
+    @Override
+    protected List<Authenticator> createAuthenticators(final IsisConfiguration configuration) {
+        return Lists.<Authenticator> newArrayList(new FileAuthenticator(configuration));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticator.java
----------------------------------------------------------------------
diff --git a/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticator.java b/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticator.java
new file mode 100644
index 0000000..642c073
--- /dev/null
+++ b/component/security/file/src/main/java/org/apache/isis/security/file/authentication/FileAuthenticator.java
@@ -0,0 +1,123 @@
+/*
+ *  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.security.file.authentication;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+import com.google.common.base.Strings;
+import com.google.inject.Inject;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.commons.lang.IoUtils;
+import org.apache.isis.core.commons.resource.ResourceStreamSource;
+import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
+import org.apache.isis.core.runtime.authentication.AuthenticationRequestPassword;
+import org.apache.isis.core.runtime.authentication.standard.PasswordRequestAuthenticatorAbstract;
+
+public class FileAuthenticator extends PasswordRequestAuthenticatorAbstract {
+
+    private final ResourceStreamSource resourceStreamSource;
+
+    @Inject
+    public FileAuthenticator(final IsisConfiguration configuration) {
+        super(configuration);
+        this.resourceStreamSource = configuration.getResourceStreamSource();
+    }
+
+    @Override
+    public final boolean isValid(final AuthenticationRequest request) {
+        final AuthenticationRequestPassword passwordRequest = (AuthenticationRequestPassword) request;
+        final String username = passwordRequest.getName();
+        if (Strings.isNullOrEmpty(username)) {
+            return false;
+        }
+        final String password = passwordRequest.getPassword();
+        Assert.assertNotNull(password);
+
+        BufferedReader reader = null;
+        try {
+            final InputStream readStream = resourceStreamSource.readResource(FileAuthenticationConstants.PASSWORDS_FILE);
+            if (readStream == null) {
+                throw new IsisException("Failed to open password file: " + FileAuthenticationConstants.PASSWORDS_FILE + " from " + resourceStreamSource.getName());
+            }
+            reader = new BufferedReader(new InputStreamReader(readStream));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (commentedOutOrEmpty(line)) {
+                    continue;
+                }
+                if (line.indexOf(':') == -1) {
+                    throw new IsisException("Invalid entry in password file - no colon (:) found on line: " + line);
+                }
+                final String name = line.substring(0, line.indexOf(':'));
+                if (!name.equals(username)) {
+                    continue;
+                }
+
+                return isPasswordValidForUser(request, password, line);
+            }
+            return false;
+        } catch (final IOException e) {
+            throw new IsisException("Failed to read password file: " + FileAuthenticationConstants.PASSWORDS_FILE + " from " + resourceStreamSource.getName());
+        } finally {
+            IoUtils.closeSafely(reader);
+        }
+
+    }
+
+    private boolean commentedOutOrEmpty(final String line) {
+        return line.startsWith("#") || line.trim().length() == 0;
+    }
+
+    private boolean isPasswordValidForUser(final AuthenticationRequest request, final String password, final String line) {
+        final int posFirstColon = line.indexOf(':');
+        final int posPasswordStart = posFirstColon + 1;
+
+        final int posSecondColonIfAny = line.indexOf(':', posPasswordStart);
+        final int posPasswordEnd = posSecondColonIfAny == -1 ? line.length() : posSecondColonIfAny;
+
+        final String parsedPassword = line.substring(posPasswordStart, posPasswordEnd);
+        if (parsedPassword.equals(password)) {
+            if (posSecondColonIfAny != -1) {
+                setRoles(request, line.substring(posSecondColonIfAny + 1));
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private final void setRoles(final AuthenticationRequest request, final String line) {
+        final StringTokenizer tokens = new StringTokenizer(line, "|", false);
+        final String[] roles = new String[tokens.countTokens()];
+        for (int i = 0; tokens.hasMoreTokens(); i++) {
+            roles[i] = tokens.nextToken();
+        }
+        request.setRoles(Arrays.asList(roles));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationConstants.java
----------------------------------------------------------------------
diff --git a/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationConstants.java b/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationConstants.java
new file mode 100644
index 0000000..972a84c
--- /dev/null
+++ b/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationConstants.java
@@ -0,0 +1,46 @@
+/*
+ *  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.security.file.authorization;
+
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.runtime.authorization.AuthorizationManagerInstaller;
+import org.apache.isis.core.runtime.authorization.standard.AuthorizationConstants;
+
+public final class FileAuthorizationConstants {
+
+    private static final String ROOT = ConfigurationConstants.ROOT + AuthorizationManagerInstaller.TYPE + "."
+        + FileAuthorizationManagerInstaller.NAME + ".";
+
+    public static final String WHITELIST_RESOURCE_KEY = ROOT + "whitelist";
+    public static final String WHITELIST_RESOURCE_DEFAULT = "authorization_file.allow";
+
+    public static final String BLACKLIST_RESOURCE_KEY = ROOT + "blacklist";
+    public static final String BLACKLIST_RESOURCE_DEFAULT = "";
+
+    public static final String LEARN = AuthorizationConstants.LEARN;
+    public static final boolean LEARN_DEFAULT = AuthorizationConstants.LEARN_DEFAULT;
+
+    public static final String WHITELIST_EMPTY = ROOT + "whitelist.empty.isallowed";
+    public static final boolean WHITELIST_EMPTY_DEFAULT = false;
+
+    private FileAuthorizationConstants() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationManagerInstaller.java
----------------------------------------------------------------------
diff --git a/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationManagerInstaller.java b/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationManagerInstaller.java
new file mode 100644
index 0000000..ebcc9fa
--- /dev/null
+++ b/component/security/file/src/main/java/org/apache/isis/security/file/authorization/FileAuthorizationManagerInstaller.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.
+ */
+
+package org.apache.isis.security.file.authorization;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.runtime.authorization.standard.AuthorizationManagerStandardInstallerAbstract;
+import org.apache.isis.core.runtime.authorization.standard.Authorizor;
+
+public class FileAuthorizationManagerInstaller extends AuthorizationManagerStandardInstallerAbstract {
+
+    public static final String NAME = "file";
+
+    public FileAuthorizationManagerInstaller() {
+        super(NAME);
+    }
+
+    @Override
+    protected Authorizor createAuthorizor(final IsisConfiguration configuration) {
+        return new FileAuthorizor(configuration);
+    }
+
+}