You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/08/16 13:51:39 UTC

[02/15] incubator-tamaya git commit: - Moved UI module into sandbox, including UI parts. - Decoupled accordingly existing modules from UI. - Fixed a few quality issues.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java
new file mode 100644
index 0000000..14af644
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java
@@ -0,0 +1,76 @@
+/*
+ * 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.tamaya.ui.internal;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.ui.User;
+import org.apache.tamaya.ui.services.UserService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User service reading users and credentials from the configuration. Users are configured as follows (e.g. using
+ * properties format):
+ * <pre>
+ * tamaya.users.admin.pwd=admin
+ * tamaya.users.admin.fullName=Administrator
+ * tamaya.users.admin.roles=admin
+ * tamaya.users.john.pwd=meymey
+ * tamaya.users.john.fullName=John Doe
+ * tamaya.users.john.roles=admin,user
+ * </pre>
+ */
+public class ConfiguredUserService implements UserService{
+
+    private Map<String, User> users = new ConcurrentHashMap<>();
+
+    /**
+     * Constructor reading the configuration and initializing the users table.
+     */
+    public ConfiguredUserService(){
+        // read from config
+        Map<String,String> config = ConfigurationProvider.getConfiguration().with(
+                ConfigurationFunctions.section("tamaya.users.", true)).getProperties();
+        for(Map.Entry<String,String> en:config.entrySet()){
+            if(en.getKey().endsWith(".pwd")){
+                String uid = en.getKey().substring(0,en.getKey().length()-4);
+                String pwd = en.getValue();
+                String fullName = config.get(uid+".fullName");
+                String roles = config.get(uid+".roles");
+                if(roles==null){
+                    roles="";
+                }
+                users.put(uid.toLowerCase(), new User(uid, fullName, pwd, roles.split(",")));
+            }
+        }
+
+    }
+
+    @Override
+    public User login(String userId, String credentials) {
+        User user = this.users.get(userId.toLowerCase());
+        if(user!=null && user.login(credentials)){
+            return user;
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
new file mode 100644
index 0000000..193144e
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
@@ -0,0 +1,91 @@
+///*
+// * 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.tamaya.ui.internal;
+//
+//import org.apache.tamaya.ConfigurationProvider;
+//import org.apache.tamaya.ui.services.MessageProvider;
+//
+//import java.util.Locale;
+//import java.util.ResourceBundle;
+//
+///**
+// * Component resolving messages for being shown in the UI, based on the ResourceBundle mechanisms.
+// * The baseName used can optionally be configured by setting {@code tamaya.ui.baseName} either as system property,
+// * environment property or Tamaya configuration. Be aware that the JDK resource bundle mechanism only reads
+// * the first property file on the classpath (or a corresponding class file implementing ResourceBundle).
+// */
+//public class ResourceBundleMessageProvider implements MessageProvider{
+//
+//    private static final String BASENAME = evaluateBaseName();
+//
+//    /**
+//     * The property name for configuring the resource bundle's base name either as
+//     * system property, environment property or configuration entry.
+//     */
+//    private static final String TAMAYA_UI_BASE_NAME = "tamaya.ui.baseName";
+//
+//    /**
+//     * Evaluates the base name to be used for creating the resource bundle used.
+//     * @return
+//     */
+//    private static String evaluateBaseName() {
+//        String baseName = System.getProperty(TAMAYA_UI_BASE_NAME);
+//        if(baseName==null || baseName.isEmpty()){
+//            baseName = System.getenv("tamaya.ui.baseName");
+//        }
+//        if(baseName==null || baseName.isEmpty()){
+//            baseName = ConfigurationProvider.getConfiguration().get("tamaya.ui.baseName");
+//        }
+//        if(baseName==null || baseName.isEmpty()){
+//            baseName = "ui/ui.lang/tamaya";
+//        }
+//        return baseName;
+//    }
+//
+//    /**
+//     * Private singleton constructor.
+//     */
+//    public ResourceBundleMessageProvider(){}
+//
+//    /**
+//     * Get a message using the defaul locale.
+//     * @param bundleID the message bundle key, not null.
+//     * @return the resolved message, or the bundle ID, never null.
+//     */
+//    public String getMessage(String bundleID){
+//        return getMessage(bundleID, Locale.getDefault());
+//    }
+//
+//    /**
+//     * Get a message.
+//     * @param bundleID the message bundle key, not null.
+//     * @param locale the target locale, or null, for the default locale.
+//     * @return the resolved message, or the bundle ID, never null.
+//     */
+//    public String getMessage(String bundleID, Locale locale){
+//        try{
+//            ResourceBundle bundle = ResourceBundle.getBundle(BASENAME, locale);
+//            return bundle.getString(bundleID);
+//        }
+//        catch(Exception e){
+//            return bundleID;
+//        }
+//    }
+//
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
new file mode 100644
index 0000000..83b4af4
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
@@ -0,0 +1,78 @@
+/*
+ * 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.tamaya.ui.internal;
+
+import org.apache.tamaya.spisupport.BasePropertySource;
+import org.apache.tamaya.spisupport.MapPropertySource;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple property source, used for internationalization.
+ */
+final class URLPropertySource extends BasePropertySource{
+
+    private static final Logger LOG = Logger.getLogger(URLPropertySource.class.getName());
+    private URL url;
+    private Map<String, String> properties;
+
+    public URLPropertySource(URL url){
+        this.url = Objects.requireNonNull(url);
+        load();
+    }
+
+    /**
+     * Loads/reloads the properties from the URL. If loading of the properties failed the previus state is preserved,
+     * unless there is no such state. In this case an empty map is assigned.
+     */
+    public void load(){
+        try(InputStream is = url.openStream()) {
+            Properties props = new Properties();
+            if (url.getFile().endsWith(".xml")) {
+                props.loadFromXML(is);
+            } else {
+                props.load(is);
+            }
+            properties = Collections.unmodifiableMap(MapPropertySource.getMap(props));
+        }
+        catch(Exception e){
+            LOG.log(Level.WARNING, "Failed to read config from "+url,e);
+            if(properties==null) {
+                properties = Collections.emptyMap();
+            }
+        }
+    }
+
+    @Override
+    public String getName() {
+        return url.toString();
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java
new file mode 100644
index 0000000..a15ae46
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.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.tamaya.ui.services;
+
+import java.util.Locale;
+
+/**
+ * Component resolving messages for being shown in the UI.
+ */
+public interface MessageProvider {
+
+    /**
+     * Get a message using the default locale.
+     * @param key the message key, not null.
+     * @return the resolved message, or the key, never null.
+     */
+    String getMessage(String key);
+
+    /**
+     * Get a message.
+     * @param key the message key, not null.
+     * @param locale the target locale, or null, for the default locale.
+     * @return the resolved message, or the key, never null.
+     */
+    String getMessage(String key, Locale locale);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/UserService.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/UserService.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/UserService.java
new file mode 100644
index 0000000..71a8a43
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/services/UserService.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.tamaya.ui.services;
+
+import org.apache.tamaya.ui.User;
+
+/**
+ * Created by atsticks on 29.03.16.
+ */
+public interface UserService {
+
+    User login(String userId, String credentials);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ConfigView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ConfigView.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ConfigView.java
new file mode 100644
index 0000000..fb0d41b
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ConfigView.java
@@ -0,0 +1,229 @@
+/*
+ * 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.tamaya.ui.views;
+
+import com.vaadin.data.Property;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.VerticalLayout;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.UIConstants;
+import org.apache.tamaya.ui.ViewProvider;
+import org.apache.tamaya.ui.components.VerticalSpacedLayout;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import javax.annotation.Priority;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * View for evaluating the current convifugration tree.
+ */
+@Priority(10)
+public class ConfigView extends VerticalSpacedLayout implements View {
+
+    /**
+     * Provider to register this view.
+     */
+    @Priority(10)
+    public static final class Provider implements ViewProvider{
+
+        @Override
+        public ViewLifecycle getLifecycle() {
+            return ViewLifecycle.CREATE;
+        }
+
+        @Override
+        public String getName() {
+            return "view.config.name";
+        }
+
+        @Override
+        public String getUrlPattern() {
+            return "/config";
+        }
+
+        @Override
+        public String getDisplayName() {
+            return ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+                    .getMessage("view.config.name");
+        }
+
+        @Override
+        public View createView(Object... params){
+            return new ConfigView();
+        }
+    }
+
+    private TextField keyFilter = new TextField("Key filter");
+    private TextField valueFilter = new TextField("Value filter");
+    private CheckBox showMetaEntries = new CheckBox("Show Metadata", false);
+    private Tree tree = new Tree("Current Configuration");
+
+    public ConfigView() {
+        Label caption = new Label("Raw Configuration");
+        Label description = new Label(
+                "This view shows the overall <b>raw</b> configuration tree. Dependening on your access rights you" +
+                        "may see partial or masked data. Similarly configuration can be <i>read-only</i> or <i>mutable</i>.",
+                ContentMode.HTML);
+
+        TabSheet tabPane = new TabSheet();
+        VerticalLayout configLayout = new VerticalLayout();
+
+        HorizontalLayout filters = new HorizontalLayout();
+
+        Button filterButton = new Button("Filter", new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                fillTree();
+            }
+        });
+        filters.setDefaultComponentAlignment(Alignment.BOTTOM_LEFT);
+        filters.addComponents(keyFilter, valueFilter, filterButton, showMetaEntries);
+        filters.setSpacing(true);
+
+        fillTree();
+        configLayout.addComponents(filters, tree);
+        tabPane.addTab(configLayout, "Configuration");
+        TextArea envProps = new TextArea();
+        StringBuilder b = new StringBuilder();
+        envProps.setHeight("100%");
+        envProps.setWidth("100%");
+        envProps.setSizeFull();
+        envProps.setRows(System.getenv().size());
+        for(Map.Entry<String,String> en:new TreeMap<>(System.getenv()).entrySet()){
+            b.append(en.getKey()).append("=").append(en.getValue()).append('\n');
+        }
+        envProps.setValue(b.toString());
+        envProps.setReadOnly(true);
+        tabPane.addTab(envProps, "Environment Properties");
+        TextArea sysProps = new TextArea();
+        sysProps.setSizeFull();
+        sysProps.setRows(System.getProperties().size());
+        b.setLength(0);
+        for(Map.Entry<Object,Object> en:new TreeMap<>(System.getProperties()).entrySet()){
+            b.append(en.getKey()).append("=").append(en.getValue()).append('\n');
+        }
+        sysProps.setValue(b.toString());
+        sysProps.setReadOnly(true);
+        tabPane.addTab(sysProps, "System Properties");
+        TextArea runtimeProps = new TextArea();
+        runtimeProps.setRows(5);
+        b.setLength(0);
+        b.append("Available Processors : ").append(Runtime.getRuntime().availableProcessors()).append('\n');
+        b.append("Free Memory          : ").append(Runtime.getRuntime().freeMemory()).append('\n');
+        b.append("Max Memory           : ").append(Runtime.getRuntime().maxMemory()).append('\n');
+        b.append("Total Memory         : ").append(Runtime.getRuntime().totalMemory()).append('\n');
+        b.append("Default Locale       : ").append(Locale.getDefault()).append('\n');
+        runtimeProps.setValue(b.toString());
+        runtimeProps.setReadOnly(true);
+        tabPane.addTab(runtimeProps, "Runtime Properties");
+        runtimeProps.setSizeFull();
+        addComponents(caption, description, tabPane);
+        caption.addStyleName(UIConstants.LABEL_HUGE);
+        description.addStyleName(UIConstants.LABEL_LARGE);
+        showMetaEntries.addValueChangeListener(new Property.ValueChangeListener() {
+            @Override
+            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
+                fillTree();
+            }
+        });
+    }
+
+    private void fillTree() {
+        String keyFilterExp = this.keyFilter.getValue();
+        if(keyFilterExp.isEmpty()){
+            keyFilterExp = null;
+        }
+        String valueFilterExp = this.valueFilter.getValue();
+        if(valueFilterExp.isEmpty()){
+            valueFilterExp = null;
+        }
+        tree.removeAllItems();
+        boolean showMetadata = showMetaEntries.getValue();
+        for(Map.Entry<String,String> entry: ConfigurationProvider.getConfiguration().getProperties().entrySet()){
+            String key = entry.getKey();
+            if(keyFilterExp!=null && !key.matches(keyFilterExp)){
+                continue;
+            }
+            if(valueFilterExp!=null && !entry.getValue().matches(valueFilterExp)){
+                continue;
+            }
+            if(!showMetadata && entry.getKey().startsWith("_")){
+                continue;
+            }
+            tree.addItem(key);
+            tree.setItemCaption(key, getCaption(key, entry.getValue()));
+            tree.setChildrenAllowed(key, false);
+            String parent = null;
+            int start = 0;
+            int index = key.indexOf('.', start);
+            while(index>0){
+                String subItem = key.substring(0,index);
+                String caption = key.substring(start, index);
+                tree.addItem(subItem);
+                tree.setItemCaption(subItem, caption);
+                if(parent!=null){
+                    tree.setParent(subItem, parent);
+                }
+                parent = subItem;
+                start = index+1;
+                index = key.indexOf('.', start);
+            }
+            String lastItem = key.substring(start);
+            if(!lastItem.equals(key)){
+                if(parent!=null){
+                    tree.setParent(key, parent);
+                }else{
+                    // should not happen
+                }
+            }else{ // singl root entry
+                if(parent!=null) {
+                    tree.setParent(key, parent);
+                }
+            }
+        }
+    }
+
+    private String getCaption(String key, String value) {
+        int index = key.lastIndexOf('.');
+        if(index<0){
+            return key + " = " + value;
+        }else{
+            return key.substring(index+1) + " = " + value;
+        }
+    }
+
+    @Override
+    public void enter(ViewChangeListener.ViewChangeEvent event) {
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ErrorView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ErrorView.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ErrorView.java
new file mode 100644
index 0000000..eef0db8
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/ErrorView.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.tamaya.ui.views;
+
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+import org.apache.tamaya.ui.UIConstants;
+
+/**
+ * View used for shoiwing unexpected errors.
+ */
+public class ErrorView extends VerticalLayout implements View {
+
+    @Override
+    public void enter(ViewChangeListener.ViewChangeEvent event) {
+        setSizeFull();
+        setMargin(true);
+        Label label = new Label("Could not find a view with that name. You are most likely doing it wrong.");
+        label.addStyleName(UIConstants.LABEL_FAILURE);
+
+        addComponent(label);
+        setComponentAlignment(label, Alignment.MIDDLE_CENTER);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/HomeView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/HomeView.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/HomeView.java
new file mode 100644
index 0000000..9d371d0
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/HomeView.java
@@ -0,0 +1,94 @@
+/*
+ * 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.tamaya.ui.views;
+
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Label;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.CurrentUser;
+import org.apache.tamaya.ui.UIConstants;
+import org.apache.tamaya.ui.ViewProvider;
+import org.apache.tamaya.ui.components.VerticalSpacedLayout;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import javax.annotation.Priority;
+
+/**
+ * Home view containing a title and a description, used as default entry point of the UI after login.
+ */
+public class HomeView extends VerticalSpacedLayout implements View {
+
+    /**
+     * Provider to bew registered providing this view to the UI module.
+     */
+    @Priority(0)
+    public static final class Provider implements ViewProvider{
+
+        @Override
+        public ViewLifecycle getLifecycle() {
+            return ViewLifecycle.LAZY;
+        }
+
+        @Override
+        public String getName() {
+            return "view.home.name";
+        }
+
+        @Override
+        public String getUrlPattern() {
+            return "/home";
+        }
+
+        @Override
+        public String getDisplayName() {
+            return ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+                    .getMessage(getName());
+        }
+
+        @Override
+        public View createView(Object... params) {
+            return new HomeView();
+        }
+
+    }
+
+    /**
+     * Constructor.
+     */
+    public HomeView() {
+        Label caption = new Label("Welcome, " + CurrentUser.get().getUserID());
+        Label description = new Label(
+                "<b>Apache Tamaya</b> is an API and extendable framework for accessing and managing configuration.<br/> \n" +
+                        "Please check the project's home page <a href='http://tamaya.incubator.apache.org'>http://tamaya.incubator.apache.org</a>.",
+                ContentMode.HTML);
+
+        addComponents(caption, description);
+
+        caption.addStyleName(UIConstants.LABEL_HUGE);
+        description.addStyleName(UIConstants.LABEL_LARGE);
+
+    }
+
+    @Override
+    public void enter(ViewChangeListener.ViewChangeEvent event) {
+        // nothing to do
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/SystemView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/SystemView.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/SystemView.java
new file mode 100644
index 0000000..ea3421c
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/SystemView.java
@@ -0,0 +1,117 @@
+/*
+ * 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.tamaya.ui.views;
+
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Tree;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.UIConstants;
+import org.apache.tamaya.ui.ViewProvider;
+import org.apache.tamaya.ui.components.VerticalSpacedLayout;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import javax.annotation.Priority;
+
+/**
+ * View showing the current loaded system components.
+ */
+@Priority(10000)
+public class SystemView extends VerticalSpacedLayout implements View {
+
+
+    /**
+     * Provider to register this view.
+     */
+    @Priority(20)
+    public static final class Provider implements ViewProvider{
+
+        @Override
+        public ViewLifecycle getLifecycle() {
+            return ViewLifecycle.CREATE;
+        }
+
+        @Override
+        public String getName() {
+            return "view.system.name";
+        }
+
+        @Override
+        public String getUrlPattern() {
+            return "/system";
+        }
+
+        @Override
+        public String getDisplayName() {
+            return ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+                    .getMessage("view.system.name");
+        }
+
+        @Override
+        public View createView(Object... params){
+            return new SystemView();
+        }
+    }
+
+
+    private Tree configTree = new Tree(ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+            .getMessage("default.label.system"));
+
+
+    public SystemView() {
+        Label caption = new Label("Tamaya Runtime");
+        Label description = new Label(
+                "This view shows the system components currently active. This information may be useful when checking if an" +
+                        "configuration extension is loaded and for inspection of the configuration and property sources" +
+                        "invovlved.",
+                ContentMode.HTML);
+
+        fillComponentTree();
+
+        addComponents(caption, description, configTree);
+
+        caption.addStyleName(UIConstants.LABEL_HUGE);
+        description.addStyleName(UIConstants.LABEL_LARGE);
+
+    }
+
+    private void fillComponentTree() {
+        configTree.removeAllItems();
+        for(SystemInfoProvider infoProvider:ServiceContextManager.getServiceContext()
+                .getServices(SystemInfoProvider.class)){
+            infoProvider.provideSystemInfo(configTree);
+        }
+    }
+
+    private String getCaption(String key, String value) {
+        int index = key.lastIndexOf('.');
+        if(index<0){
+            return key + " = " + value;
+        }else{
+            return key.substring(index+1) + " = " + value;
+        }
+    }
+
+    @Override
+    public void enter(ViewChangeListener.ViewChangeEvent event) {
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/TamayaGeneralSystemInfoProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/TamayaGeneralSystemInfoProvider.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/TamayaGeneralSystemInfoProvider.java
new file mode 100644
index 0000000..fd37136
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/TamayaGeneralSystemInfoProvider.java
@@ -0,0 +1,56 @@
+/*
+ * 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.tamaya.ui.views;
+
+import com.vaadin.ui.Tree;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+
+import javax.annotation.Priority;
+
+/**
+ * Created by atsticks on 29.06.16.
+ */
+@Priority(0)
+public class TamayaGeneralSystemInfoProvider implements SystemInfoProvider{
+    @Override
+    public void provideSystemInfo(Tree tree) {
+        Configuration config = ConfigurationProvider.getConfiguration();
+        String currentParent = "General";
+        tree.addItem(currentParent);
+        tree.addItem("Configuration.class");
+        tree.setItemCaption("Configuration.class", "Configuration class = " + config.getClass().getName());
+        tree.setParent("Configuration.class", currentParent);
+        tree.setChildrenAllowed("Configuration.class", false);
+
+        tree.addItem("ConfigurationContext.class");
+        tree.setItemCaption("ConfigurationContext.class", "ConfigurationContext class = " +
+                config.getContext().getClass().getName());
+        tree.setParent("ConfigurationContext.class", currentParent);
+        tree.setChildrenAllowed("ConfigurationContext.class", false);
+
+        tree.addItem("PropertyValueCombinationPolicy.class");
+        tree.setItemCaption("PropertyValueCombinationPolicy.class",
+                PropertyValueCombinationPolicy.class.getSimpleName() + " class = " +
+                        config.getContext().getPropertyValueCombinationPolicy().getClass().getName());
+        tree.setParent("PropertyValueCombinationPolicy.class", currentParent);
+        tree.setChildrenAllowed("PropertyValueCombinationPolicy.class", false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginBox.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginBox.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginBox.java
new file mode 100644
index 0000000..73cf018
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginBox.java
@@ -0,0 +1,112 @@
+/*
+ * 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.tamaya.ui.views.login;
+
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.PasswordField;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.UIConstants;
+import org.apache.tamaya.ui.User;
+import org.apache.tamaya.ui.event.EventBus;
+import org.apache.tamaya.ui.services.MessageProvider;
+import org.apache.tamaya.ui.services.UserService;
+
+/**
+ * Login dialog centerd on the screen.
+ */
+public class LoginBox extends VerticalLayout {
+
+    private TextField username;
+    private PasswordField password;
+
+    public LoginBox() {
+        setWidth("400px");
+        addStyleName(UIConstants.LOGIN_BOX);
+        setSpacing(true);
+        setMargin(true);
+
+        addCaption();
+        addForm();
+        addButtons();
+    }
+
+    private void addCaption() {
+        Label caption = new Label("Login to system");
+        addComponent(caption);
+
+        caption.addStyleName(UIConstants.LABEL_H1);
+    }
+
+    private void addForm() {
+        FormLayout loginForm = new FormLayout();
+        MessageProvider mp = ServiceContextManager.getServiceContext().getService(MessageProvider.class);
+        username = new TextField(mp.getMessage("default.label.username"));
+        password = new PasswordField(mp.getMessage("default.label.password"));
+        loginForm.addComponents(username, password);
+        addComponent(loginForm);
+        loginForm.setSpacing(true);
+        for(Component component:loginForm){
+            component.setWidth("100%");
+        }
+        username.focus();
+    }
+
+    private void addButtons() {
+        HorizontalLayout buttonsLayout = new HorizontalLayout();
+        Button forgotButton = new Button("Forgot", new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                Notification.show("Sorry, this feature is not yet implemented.", Notification.Type.TRAY_NOTIFICATION);
+            }
+        });
+        Button loginButton = new Button("Login", new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                login();
+            }
+        });
+        buttonsLayout.addComponents(forgotButton, loginButton);
+        addComponent(buttonsLayout);
+        buttonsLayout.setSpacing(true);
+        forgotButton.addStyleName(UIConstants.BUTTON_LINK);
+        loginButton.addStyleName(UIConstants.BUTTON_PRIMARY);
+        loginButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
+        setComponentAlignment(buttonsLayout, Alignment.BOTTOM_RIGHT);
+    }
+
+    private void login() {
+        User user = ServiceContextManager.getServiceContext().getService(UserService.class)
+                .login(username.getValue(), password.getValue());
+        if(user!=null){
+            EventBus.post(new LoginEvent(user));
+        }else{
+            Notification.show("Login failed.", "Sorry the system could not log you in.", Notification.Type.WARNING_MESSAGE);
+            username.focus();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginEvent.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginEvent.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginEvent.java
new file mode 100644
index 0000000..004c545
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginEvent.java
@@ -0,0 +1,55 @@
+/*
+ * 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.tamaya.ui.views.login;
+
+import org.apache.tamaya.ui.User;
+
+import java.util.Objects;
+
+/**
+ * Event sent when a user has been authenticated.
+ */
+public class LoginEvent {
+    /** The user, not null. */
+    private User user;
+
+    /**
+     * Creates a new event.
+     * @param user the user logged in, not null.
+     */
+    public LoginEvent(User user) {
+        this.user = Objects.requireNonNull(user);
+    }
+
+    /**
+     * Get the user logged in.
+     * @return the user logged in, never null.
+     */
+    public User getUser() {
+        return user;
+    }
+
+    @Override
+    public String toString() {
+        return "LoginEvent{" +
+                "user=" + user +
+                '}';
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginView.java b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginView.java
new file mode 100644
index 0000000..15730d3
--- /dev/null
+++ b/sandbox/ui/base/src/main/java/org/apache/tamaya/ui/views/login/LoginView.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.
+ */
+package org.apache.tamaya.ui.views.login;
+
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * View used for login the users.
+ */
+public class LoginView extends VerticalLayout {
+
+    /**
+     * Creates a new view.
+     */
+    public LoginView() {
+        setSizeFull();
+        setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
+        addComponent(new LoginBox());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/resources/META-INF/javaconfiguration.properties b/sandbox/ui/base/src/main/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..98d7155
--- /dev/null
+++ b/sandbox/ui/base/src/main/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,21 @@
+#
+# 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 current 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.
+#
+tamaya.users.admin.pwd=admin
+tamaya.users.admin.fullName=Administrator
+tamaya.users.admin.roles=admin
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider b/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
new file mode 100644
index 0000000..0ff3225
--- /dev/null
+++ b/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
@@ -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 current 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.
+#
+org.apache.tamaya.ui.views.HomeView$Provider
+org.apache.tamaya.ui.views.ConfigView$Provider
+org.apache.tamaya.ui.views.SystemView$Provider
+
+# Events Module
+org.apache.tamaya.ui.events.EventView$Provider

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider b/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider
new file mode 100644
index 0000000..6ce4a9f
--- /dev/null
+++ b/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.ui.internal.ConfigurationBasedMessageProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.UserService
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.UserService b/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.UserService
new file mode 100644
index 0000000..109865f
--- /dev/null
+++ b/sandbox/ui/base/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.UserService
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.ui.internal.ConfiguredUserService
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/resources/config/application.yml
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/resources/config/application.yml b/sandbox/ui/base/src/main/resources/config/application.yml
new file mode 100644
index 0000000..a22ec36
--- /dev/null
+++ b/sandbox/ui/base/src/main/resources/config/application.yml
@@ -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 current 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.
+#
+
+server:
+  type: default
+  maxThreads: 1024
+  applicationConnectors:
+      - type: http
+        port: 8090
+  adminConnectors:
+      - type: http
+        port: 8091
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/main/resources/ui/lang/tamaya.properties
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/main/resources/ui/lang/tamaya.properties b/sandbox/ui/base/src/main/resources/ui/lang/tamaya.properties
new file mode 100644
index 0000000..ba458de
--- /dev/null
+++ b/sandbox/ui/base/src/main/resources/ui/lang/tamaya.properties
@@ -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 current 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.name=Apache Tamaya
+default.label.logout=Log out
+default.label.unknown=<unknown>
+default.label.username=Username
+default.label.password=Password
+default.label.system=Runtime
+
+view.config.name=Configuration
+view.home.name=Home
+view.system.name=System Runtime

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/base/src/test/resources/config/application.yml
----------------------------------------------------------------------
diff --git a/sandbox/ui/base/src/test/resources/config/application.yml b/sandbox/ui/base/src/test/resources/config/application.yml
new file mode 100644
index 0000000..10ef339
--- /dev/null
+++ b/sandbox/ui/base/src/test/resources/config/application.yml
@@ -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 current 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.
+#
+
+server:
+  type: default
+  maxThreads: 1024
+  applicationConnectors:
+      - type: http
+        port: 8090
+      - type: https
+        port: 8453
+  adminConnectors:
+      - type: http
+        port: 8091
+      - type: https
+        port: 8453
+
+ui:
+  disabled-views:
+    - "view.system.name"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/events/src/main/java/org/apache/tamaya/ui/events/EventView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/events/src/main/java/org/apache/tamaya/ui/events/EventView.java b/sandbox/ui/events/src/main/java/org/apache/tamaya/ui/events/EventView.java
new file mode 100644
index 0000000..ffb59cf
--- /dev/null
+++ b/sandbox/ui/events/src/main/java/org/apache/tamaya/ui/events/EventView.java
@@ -0,0 +1,181 @@
+/*
+ * 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.tamaya.ui.events;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextField;
+import org.apache.tamaya.events.ConfigEvent;
+import org.apache.tamaya.events.ConfigEventListener;
+import org.apache.tamaya.events.ConfigEventManager;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.UIConstants;
+import org.apache.tamaya.ui.ViewProvider;
+import org.apache.tamaya.ui.components.VerticalSpacedLayout;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import javax.annotation.Priority;
+import java.util.Date;
+
+/**
+ * Tamaya View for observing the current event stream.
+ */
+public class EventView extends VerticalSpacedLayout implements View {
+
+    /**
+     * Provider used to register the view.
+     */
+    @Priority(20)
+    public static final class Provider implements ViewProvider{
+
+        @Override
+        public ViewLifecycle getLifecycle() {
+            return ViewLifecycle.EAGER;
+        }
+
+        @Override
+        public String getName() {
+            return "view.events.name";
+        }
+
+        @Override
+        public String getUrlPattern() {
+            return "/events";
+        }
+
+        @Override
+        public String getDisplayName() {
+            return getName();
+        }
+
+        @Override
+        public View createView(Object... params){
+            return new EventView();
+        }
+    }
+
+    private CheckBox changeMonitorEnabled = new CheckBox(ServiceContextManager.getServiceContext()
+            .getService(MessageProvider.class).getMessage("view.events.button.enableMonitoring"));
+    private Button clearViewButton = new Button(ServiceContextManager.getServiceContext()
+            .getService(MessageProvider.class).getMessage("view.events.button.clearView"));
+    private TextField pollingInterval = new TextField(ServiceContextManager.getServiceContext()
+            .getService(MessageProvider.class).getMessage("view.events.field.pollingInterval"));
+    private Table eventsTable = new Table(ServiceContextManager.getServiceContext()
+            .getService(MessageProvider.class).getMessage("view.events.table.name"));
+
+
+    public EventView() {
+        Label caption = new Label(ServiceContextManager.getServiceContext()
+                .getService(MessageProvider.class).getMessage("view.events.name"));
+        Label description = new Label(ServiceContextManager.getServiceContext()
+                .getService(MessageProvider.class).getMessage("view.events.description"),
+                ContentMode.HTML);
+
+        ConfigEventManager.addListener(new ConfigEventListener() {
+            @Override
+            public void onConfigEvent(ConfigEvent<?> event) {
+                addEvent(event);
+            }
+        });
+        changeMonitorEnabled.addValueChangeListener(new Property.ValueChangeListener() {
+            @Override
+            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
+                ConfigEventManager.enableChangeMonitoring(changeMonitorEnabled.getValue());
+                if(changeMonitorEnabled.getValue()) {
+                    Notification.show("Event Monitoring (Polling) active.");
+                }else{
+                    Notification.show("Event Monitoring (Polling) inactive.");
+                }
+            }
+        });
+        clearViewButton.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                eventsTable.removeAllItems();
+                Notification.show("Events cleared.");
+            }
+        });
+
+        HorizontalLayout eventSettings = new HorizontalLayout();
+        eventSettings.addComponents(changeMonitorEnabled, new Label(" Polling Interval"), pollingInterval, clearViewButton);
+        changeMonitorEnabled.setValue(ConfigEventManager.isChangeMonitoring());
+        pollingInterval.setValue(String.valueOf(ConfigEventManager.getChangeMonitoringPeriod()));
+        pollingInterval.setRequired(true);
+        pollingInterval.addValueChangeListener(new Property.ValueChangeListener() {
+            @Override
+            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
+                try{
+                    long millis = Long.parseLong((String)valueChangeEvent.getProperty().getValue());
+                    ConfigEventManager.setChangeMonitoringPeriod(millis);
+                    Notification.show("Updated Event Monitoring Poll Interval to " + millis + " milliseconds.");
+                }catch(Exception e){
+                    Notification.show("Cannot update Event Monitoring Poll Interval to "
+                            + valueChangeEvent.getProperty().getValue(), Notification.Type.ERROR_MESSAGE);
+                }
+            }
+        });
+        eventsTable.addContainerProperty("Timestamp", Date.class, null);
+        eventsTable.addContainerProperty("Type", String.class, "?");
+        eventsTable.addContainerProperty("Payload", String.class, "<empty>");
+        eventsTable.addContainerProperty("Version",  String.class, "?");
+        eventsTable.setPageLength(20);
+        eventsTable.setWidth("100%");
+        eventsTable.setResponsive(true);
+
+
+        caption.addStyleName(UIConstants.LABEL_HUGE);
+        description.addStyleName(UIConstants.LABEL_LARGE);
+        addComponents(caption, description, eventSettings, eventsTable);
+    }
+
+    private void addEvent(ConfigEvent<?> evt){
+        Object newItemId = eventsTable.addItem();
+        Item row = eventsTable.getItem(newItemId);
+        row.getItemProperty("Timestamp").setValue(new Date(evt.getTimestamp()));
+        row.getItemProperty("Type").setValue(evt.getResourceType().getSimpleName());
+        String value = String.valueOf(evt.getResource());
+        String valueShort = value.length()<150?value:value.substring(0,147)+"...";
+        row.getItemProperty("Payload").setValue(valueShort);
+        row.getItemProperty("Version").setValue(evt.getVersion());
+    }
+
+
+    private String getCaption(String key, String value) {
+        int index = key.lastIndexOf('.');
+        if(index<0){
+            return key + " = " + value;
+        }else{
+            return key.substring(index+1) + " = " + value;
+        }
+    }
+
+    @Override
+    public void enter(ViewChangeListener.ViewChangeEvent event) {
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
----------------------------------------------------------------------
diff --git a/sandbox/ui/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider b/sandbox/ui/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
new file mode 100644
index 0000000..d30ddaa
--- /dev/null
+++ b/sandbox/ui/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+events.EventView$Provider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/mutableconfig/pom.xml
----------------------------------------------------------------------
diff --git a/sandbox/ui/mutableconfig/pom.xml b/sandbox/ui/mutableconfig/pom.xml
new file mode 100644
index 0000000..8a94150
--- /dev/null
+++ b/sandbox/ui/mutableconfig/pom.xml
@@ -0,0 +1,36 @@
+<?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 current 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/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <artifactId>tamaya-ui</artifactId>
+        <version>0.3-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <packaging>jar</packaging>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>tamaya-ui-mutableconfig</artifactId>
+    <name>Apache Tamaya Modules - UI (Mutable Config)</name>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigEditorWidget.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigEditorWidget.java b/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigEditorWidget.java
new file mode 100644
index 0000000..09b23a1
--- /dev/null
+++ b/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigEditorWidget.java
@@ -0,0 +1,132 @@
+/*
+ * 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.tamaya.ui.mutableconfig;
+
+import com.vaadin.ui.*;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import java.util.Objects;
+
+/**
+ * Tamaya UI view to change configuration.
+ */
+public class ConfigEditorWidget extends FormLayout {
+
+    private MutableConfiguration mutableConfig;
+
+    private ProtocolWidget logWriter;
+    private TransactionControlWidget taWidget;
+
+    private TextField configKey = new TextField(
+            ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+                    .getMessage("view.edit.text.configKey"));
+    private TextField configValue = new TextField(
+            ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+                    .getMessage("view.edit.text.configValue"));
+    private Button updateButton = new Button(ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+            .getMessage("view.edit.button.updateKey"));
+    private Button removeButton = new Button(ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+            .getMessage("view.edit.button.removeKey"));
+    private Button readButton = new Button(ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+            .getMessage("view.edit.button.readKey"));
+
+    public ConfigEditorWidget(MutableConfiguration mutableConfig, ProtocolWidget logWriter, TransactionControlWidget taWidget) {
+        this.mutableConfig = Objects.requireNonNull(mutableConfig);
+        this.logWriter = Objects.requireNonNull(logWriter);
+        this.taWidget = Objects.requireNonNull(taWidget);
+        configKey.setWidth(50, Unit.PERCENTAGE);
+        configValue.setWidth(50, Unit.PERCENTAGE);
+        addComponents(configKey, configValue);
+        HorizontalLayout buttonLayout = new HorizontalLayout();
+        buttonLayout.addComponents(readButton, new Label("   "), updateButton, removeButton);
+        buttonLayout.setSpacing(true);
+        addComponents(buttonLayout);
+        initActions();
+    }
+
+    private void initActions() {
+        updateButton.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                if(mutableConfig.isWritable(configKey.getValue())){
+                    mutableConfig.put(configKey.getValue(), configValue.getValue());
+                    Notification.show("Added " + configKey.getValue() + " = " + configValue.getValue(),
+                            Notification.Type.TRAY_NOTIFICATION);
+                    logWriter.println(" - PUT " + configKey.getValue() + " = " + configValue.getValue());
+                    configKey.setValue("");
+                    configValue.setValue("");
+                }else{
+                    Notification.show("Could not add " + configKey.getValue() + " = " + configValue.getValue(),
+                            Notification.Type.ERROR_MESSAGE);
+                    logWriter.println(" - PUT " + configKey.getValue() + " rejected - not writable.");
+                }
+                taWidget.update();
+            }
+        });
+        removeButton.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                if(mutableConfig.isRemovable(configKey.getValue())){
+                    mutableConfig.remove(configKey.getValue());
+                    logWriter.println(" - DEL " + configKey.getValue());
+                    Notification.show("Removed " + configKey.getValue(),
+                            Notification.Type.TRAY_NOTIFICATION);
+                    configKey.setValue("");
+                    configValue.setValue("");
+                }else{
+                    Notification.show("Could not remove " + configKey.getValue(),
+                            Notification.Type.ERROR_MESSAGE);
+                    logWriter.println(" - DEL " + configKey.getValue() + " rejected - not removable.");
+                }
+                taWidget.update();
+            }
+        });
+        readButton.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                if(mutableConfig.isExisting(configKey.getValue())){
+                    String key = configKey.getValue();
+                    configValue.setValue(mutableConfig.get(key));
+                    Notification.show("Successfully read " + configKey.getValue(),
+                            Notification.Type.TRAY_NOTIFICATION);
+                    logWriter.println(" - GET " + key + " = " + configValue.getValue());
+                    logWriter.println("   - removable: " + mutableConfig.isRemovable(key));
+                    logWriter.println("   - writable : " + mutableConfig.isWritable(key));
+                }else{
+                    Notification.show("Could not read " + configKey.getValue(),
+                            Notification.Type.ERROR_MESSAGE);
+                    logWriter.println(" - GET " + configKey.getValue() + " rejected - not existing.");
+                }
+                taWidget.update();
+            }
+        });
+    }
+
+    private String getCaption(String key, String value) {
+        int index = key.lastIndexOf('.');
+        if(index<0){
+            return key + " = " + value;
+        }else{
+            return key.substring(index+1) + " = " + value;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigUpdaterView.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigUpdaterView.java b/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigUpdaterView.java
new file mode 100644
index 0000000..7facaeb
--- /dev/null
+++ b/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ConfigUpdaterView.java
@@ -0,0 +1,121 @@
+/*
+ * 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.tamaya.ui.mutableconfig;
+
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.mutableconfig.MutableConfigurationProvider;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.UIConstants;
+import org.apache.tamaya.ui.ViewProvider;
+import org.apache.tamaya.ui.components.VerticalSpacedLayout;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import javax.annotation.Priority;
+
+/**
+ * Tamaya UI view to change configuration.
+ */
+public class ConfigUpdaterView extends VerticalSpacedLayout implements View {
+
+    /**
+     * Provider to register the view.
+     */
+    @Priority(50)
+    public static final class Provider implements ViewProvider{
+
+        @Override
+        public ViewLifecycle getLifecycle() {
+            return ViewLifecycle.LAZY;
+        }
+
+        @Override
+        public String getName() {
+            return "view.edit.name";
+        }
+
+        @Override
+        public String getUrlPattern() {
+            return "/edit";
+        }
+
+        @Override
+        public String getDisplayName() {
+            return ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+                    .getMessage("view.edit.name");
+        }
+
+        @Override
+        public View createView(Object... params){
+            return new ConfigUpdaterView();
+        }
+    }
+
+    private ProtocolWidget logWidget = new ProtocolWidget();
+    private PopupView logPopup = new PopupView("Show log", logWidget);
+
+    private MutableConfiguration mutableConfig = MutableConfigurationProvider.getMutableConfiguration();
+
+    private TransactionControlWidget taControl = new TransactionControlWidget(mutableConfig,
+            logWidget);
+    private PopupView taDetails = new PopupView("Transaction Details", taControl);
+
+    private ConfigEditorWidget editorWidget = new ConfigEditorWidget(mutableConfig, logWidget, taControl);
+
+
+    public ConfigUpdaterView() {
+        Label caption = new Label(ServiceContextManager.getServiceContext()
+                .getService(MessageProvider.class).getMessage("view.edit.name"));
+        Label description = new Label(ServiceContextManager.getServiceContext()
+                .getService(MessageProvider.class).getMessage("view.edit.description"),
+                ContentMode.HTML);
+
+        caption.addStyleName(UIConstants.LABEL_HUGE);
+        description.addStyleName(UIConstants.LABEL_LARGE);
+        logWidget.print("INFO: Writable Property Sources: ");
+        for(MutablePropertySource ps:mutableConfig.getMutablePropertySources()){
+            logWidget.print(ps.getName(), ", ");
+        }
+        logWidget.println();
+        logWidget.setHeight(100, Unit.PERCENTAGE);
+        HorizontalLayout hl = new HorizontalLayout(taDetails, logPopup);
+        hl.setSpacing(true);
+        addComponents(caption, description, editorWidget, hl);
+    }
+
+    private String getCaption(String key, String value) {
+        int index = key.lastIndexOf('.');
+        if(index<0){
+            return key + " = " + value;
+        }else{
+            return key.substring(index+1) + " = " + value;
+        }
+    }
+
+    @Override
+    public void enter(ViewChangeListener.ViewChangeEvent event) {
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0370a240/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ProtocolWidget.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ProtocolWidget.java b/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ProtocolWidget.java
new file mode 100644
index 0000000..2d78aee
--- /dev/null
+++ b/sandbox/ui/mutableconfig/src/main/java/org/apache/tamaya/ui/mutableconfig/ProtocolWidget.java
@@ -0,0 +1,90 @@
+/*
+ * 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.tamaya.ui.mutableconfig;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.VerticalLayout;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Widget showing a text protocol wioth a clear button to clear the widget space.
+ */
+public class ProtocolWidget extends VerticalLayout{
+
+    private TextArea textArea = new TextArea(ServiceContextManager.getServiceContext()
+            .getService(MessageProvider.class).getMessage("view.edit.textArea.protocol"));
+    private Button clearButton = new Button(ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+            .getMessage("view.edit.button.clearProtocol"));
+
+    private StringWriter protocol = new StringWriter();
+    private PrintWriter writer = new PrintWriter(protocol);
+
+    public ProtocolWidget(){
+        textArea.setWidth(600, Unit.PIXELS);
+        textArea.setHeight(400, Unit.PERCENTAGE);
+        textArea.setReadOnly(true);
+        clearButton.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                protocol.getBuffer().setLength(0);
+                flush();
+            }
+        });
+        textArea.setSizeFull();
+        addComponents(textArea, clearButton);
+        setWidth(700, Unit.PIXELS);
+        setHeight(500, Unit.PERCENTAGE);
+    }
+
+    public PrintWriter getWriter(){
+        return writer;
+    }
+
+    public void println(){
+        writer.println();
+    }
+
+    public void println(Object... items){
+        for(int i=0;i<items.length;i++){
+            writer.print(items[i]);
+        }
+        writer.println();
+        flush();
+    }
+
+    public void print(Object... items){
+        for(int i=0;i<items.length;i++){
+            writer.print(items[i]);
+        }
+        flush();
+    }
+
+    private void flush(){
+        writer.flush();
+        textArea.setReadOnly(false);
+        textArea.setValue(protocol.toString());
+        textArea.setReadOnly(true);
+    }
+
+}