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/04/19 13:54:39 UTC

[06/15] incubator-tamaya git commit: Modulularized UI module, added multi file based i18n, using config mechanisms.

Modulularized UI module, added multi file based i18n, using config mechanisms.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/6411646c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/6411646c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/6411646c

Branch: refs/heads/master
Commit: 6411646cdb2b964716472442b01e597141f6bd20
Parents: 692ce55
Author: anatole <an...@apache.org>
Authored: Sat Apr 16 08:25:46 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Apr 19 13:53:44 2016 +0200

----------------------------------------------------------------------
 .../org/apache/tamaya/events/ui/EventView.java  | 134 ++++++++++++++
 .../services/org.apache.tamaya.ui.ViewProvider  |  19 ++
 .../main/resources/ui/lang/tamaya.properties    |   5 +
 .../tamaya/events/RandomPropertySource.java     |  48 +++++
 .../org.apache.tamaya.spi.PropertySource        |  19 ++
 .../services/org.apache.tamaya.ui.ViewProvider  |  19 ++
 .../src/test/resources/config/application.yml   |  13 ++
 .../java/org/apache/tamaya/ui/ViewProvider.java |  66 +++++++
 .../ConfigurationBasedMessageProvider.java      | 174 +++++++++++++++++++
 .../ui/internal/ConfiguredMessageProvider.java  |  61 +++++++
 .../internal/ResourceBundleMessageProvider.java |  91 ++++++++++
 .../tamaya/ui/internal/URLPropertySource.java   |  60 +++++++
 .../tamaya/ui/services/MessageProvider.java     |  43 +++++
 .../apache/tamaya/ui/services/UserService.java  |  30 ++++
 .../services/org.apache.tamaya.ui.ViewProvider  |  21 +++
 ...rg.apache.tamaya.ui.services.MessageProvider |  19 ++
 .../main/resources/ui/lang/tamaya.properties    |  28 +++
 17 files changed, 850 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/modules/events/src/main/java/org/apache/tamaya/events/ui/EventView.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ui/EventView.java b/modules/events/src/main/java/org/apache/tamaya/events/ui/EventView.java
new file mode 100644
index 0000000..a69b04c
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ui/EventView.java
@@ -0,0 +1,134 @@
+/*
+ * 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.events.ui;
+
+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.*;
+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;
+
+
+public class EventView extends VerticalSpacedLayout implements View {
+
+    @Priority(20)
+    public static final class Provider implements ViewProvider{
+
+        @Override
+        public ViewLifecycle getLifecycle() {
+            return ViewLifecycle.EAGER;
+        }
+
+        @Override
+        public String getUrlPattern() {
+            return "/events";
+        }
+
+        @Override
+        public String getDisplayName() {
+            return "view.events.name";
+        }
+
+        @Override
+        public View createView(){
+            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 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());
+            }
+        });
+        clearViewButton.addClickListener(new Button.ClickListener() {
+            @Override
+            public void buttonClick(Button.ClickEvent clickEvent) {
+                eventsTable.removeAllItems();
+            }
+        });
+
+        changeMonitorEnabled.setData(ConfigEventManager.isChangeMonitoring());
+        eventsTable.addContainerProperty("Timestamp", Long.class, null);
+        eventsTable.addContainerProperty("Type", Class.class, null);
+        eventsTable.addContainerProperty("Payload", String.class, null);
+        eventsTable.addContainerProperty("Version",  String.class, null);
+        eventsTable.setPageLength(20);
+        eventsTable.setWidth("100%");
+        eventsTable.setResponsive(true);
+
+        HorizontalLayout hl = new HorizontalLayout();
+        hl.addComponents(changeMonitorEnabled, clearViewButton);
+        caption.addStyleName(UIConstants.LABEL_HUGE);
+        description.addStyleName(UIConstants.LABEL_LARGE);
+        addComponents(caption, description, hl, eventsTable);
+    }
+
+    private void addEvent(ConfigEvent<?> evt){
+        eventsTable.addItem(new Object[]{evt.getTimestamp(), evt.getResourceType().getSimpleName(),
+                String.valueOf(evt.getResource()),evt.getVersion()});
+        this.markAsDirty();
+    }
+
+
+    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/6411646c/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
----------------------------------------------------------------------
diff --git a/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider b/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
new file mode 100644
index 0000000..f779d5c
--- /dev/null
+++ b/modules/events/src/main/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.
+#
+org.apache.tamaya.events.ui.EventView$Provider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/modules/events/src/main/resources/ui/lang/tamaya.properties
----------------------------------------------------------------------
diff --git a/modules/events/src/main/resources/ui/lang/tamaya.properties b/modules/events/src/main/resources/ui/lang/tamaya.properties
new file mode 100644
index 0000000..37ca420
--- /dev/null
+++ b/modules/events/src/main/resources/ui/lang/tamaya.properties
@@ -0,0 +1,5 @@
+view.events.name=Configuration Events
+view.events.table.name=Observed Events
+view.events.button.enableMonitoring=Change Monitor active
+view.events.button.clearView=Clear View
+view.events.description=This view shows the configuration events triggered in the system.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/modules/events/src/test/java/org/apache/tamaya/events/RandomPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/RandomPropertySource.java b/modules/events/src/test/java/org/apache/tamaya/events/RandomPropertySource.java
new file mode 100644
index 0000000..f32ead7
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/RandomPropertySource.java
@@ -0,0 +1,48 @@
+package org.apache.tamaya.events;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * PropertySource that provides a randome entry, different on each access!
+ */
+public class RandomPropertySource implements PropertySource{
+
+    private Map<String, String> data = new HashMap<>();
+
+    @Override
+    public int getOrdinal() {
+        return 0;
+    }
+
+    @Override
+    public String getName() {
+        return "random";
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        if(key.equals("random.new")){
+            return PropertyValue.of(key, String.valueOf(Math.random()),getName());
+        }
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        synchronized(data) {
+            data.put("random.new", String.valueOf(Math.random()));
+            data.put("_random.new.source", getName());
+            data.put("_random.new.timestamp", String.valueOf(System.currentTimeMillis()));
+            return new HashMap<>(data);
+        }
+    }
+
+    @Override
+    public boolean isScannable() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
new file mode 100644
index 0000000..9c2b9f6
--- /dev/null
+++ b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
@@ -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.events.RandomPropertySource

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
----------------------------------------------------------------------
diff --git a/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
new file mode 100644
index 0000000..f779d5c
--- /dev/null
+++ b/modules/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.
+#
+org.apache.tamaya.events.ui.EventView$Provider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/modules/events/src/test/resources/config/application.yml
----------------------------------------------------------------------
diff --git a/modules/events/src/test/resources/config/application.yml b/modules/events/src/test/resources/config/application.yml
new file mode 100644
index 0000000..9ec8d5b
--- /dev/null
+++ b/modules/events/src/test/resources/config/application.yml
@@ -0,0 +1,13 @@
+server:
+  type: default
+  maxThreads: 1024
+  applicationConnectors:
+      - type: http
+        port: 8090
+      - type: https
+        port: 8453
+  adminConnectors:
+      - type: http
+        port: 8091
+      - type: https
+        port: 8453
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/ViewProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/ViewProvider.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/ViewProvider.java
new file mode 100644
index 0000000..35990ab
--- /dev/null
+++ b/sandbox/ui/src/main/java/org/apache/tamaya/ui/ViewProvider.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import com.vaadin.navigator.View;
+
+/**
+ * Interface to register Tamaya UI parts. For priorization also use the @Priority annotations.
+ */
+public interface ViewProvider {
+
+    /**
+     * View lifecycle options that determine when a view is created and how long an instance is used.
+     */
+    enum ViewLifecycle {
+        /** Creates a new view instance whenever the view is showed. */
+        CREATE,
+        /** Loads the view on first access. */
+        LAZY,
+        /** Eagerly preloads the view. */
+        EAGER
+    }
+
+    /**
+     * Get the view lifecycle model.
+     * @return the lifecycle model, not null.
+     */
+    ViewLifecycle getLifecycle();
+
+    /**
+     * Get the url pattern where this view should be accessible.
+     * @return the url pattern, not null.
+     */
+    String getUrlPattern();
+
+    /**
+     * Get the name to be displayed for this view. This value will also be used to lookup a name from the {@code /ui/lang/tamaya}
+     *                                   bundle. If not found the value returned will be used for display.
+     *
+     * @return the name to be displayed, or its resource bundle key, not null.
+     */
+    String getDisplayName();
+
+    /**
+     * Method that is called to create a new view instance.
+     * @see #getLifecycle()
+     * @return a new view instance, not null.
+     */
+    View createView();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java
new file mode 100644
index 0000000..99521c4
--- /dev/null
+++ b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java
@@ -0,0 +1,174 @@
+/*
+ * 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.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spisupport.BasePropertySource;
+import org.apache.tamaya.spisupport.DefaultConfiguration;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 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 final class ConfigurationBasedMessageProvider implements MessageProvider{
+
+    /**
+     * 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";
+
+    private final String baseName = evaluateBaseName();
+
+    private Map<String, Map<String,String>> propertiesCache = new ConcurrentHashMap<>();
+
+
+    /**
+     * Private singleton constructor.
+     */
+    public ConfigurationBasedMessageProvider(){
+
+    }
+
+    /**
+     * Get a message using the defaul locale.
+     * @param key the message key, not null.
+     * @return the resolved message, or the bundle ID, never null.
+     */
+    public String getMessage(String key){
+        return getMessage(key, Locale.getDefault());
+    }
+
+    /**
+     * 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.
+     */
+    public String getMessage(String key, Locale locale){
+        List<String> bundleIds = evaluateBundleIds(locale);
+        for(String bundleID:bundleIds){
+            Map<String,String> entries = this.propertiesCache.get(bundleID);
+            if(entries==null){
+                entries = loadEntries(bundleID);
+            }
+            String value = entries.get(key);
+            if(value!=null){
+                return value;
+            }
+        }
+        return null;
+    }
+
+    private Map<String, String> loadEntries(String bundleID) {
+        ConfigurationContextBuilder ctxBuilder = ConfigurationProvider.getConfigurationContextBuilder();
+        for(String format:new String[]{"xml", "properties"}) {
+            try {
+                Enumeration<URL> urls = getClass().getClassLoader().getResources(bundleID+"."+format);
+                while(urls.hasMoreElements()){
+                    URL url = urls.nextElement();
+                    ctxBuilder.addPropertySources(new URLPropertySource(url));
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        Map<String, String>  entries = new DefaultConfiguration(ctxBuilder.build()).getProperties();
+        this.propertiesCache.put(bundleID, entries);
+        return entries;
+    }
+
+    private List<String> evaluateBundleIds(Locale locale) {
+        List<String> bundleIds = new ArrayList<>();
+        String country = locale.getCountry();
+        if(country==null){
+            country="";
+        }
+        String lang = locale.getLanguage();
+        if(lang==null){
+            lang="";
+        }
+        String variant = locale.getVariant();
+        if(variant==null){
+            variant="";
+        }
+        String key = baseName + "_"+country+"_"+lang+"_"+variant;
+        key = reduceKey(key);
+        if(!bundleIds.contains(key)){
+            bundleIds.add(key);
+        }
+        key = baseName + "_"+country+"_"+lang;
+        key = reduceKey(key);
+        if(!bundleIds.contains(key)){
+            bundleIds.add(key);
+        }
+        key = baseName + "_"+country;
+        key = reduceKey(key);
+        if(!bundleIds.contains(key)){
+            bundleIds.add(key);
+        }
+        key = baseName;
+        if(!bundleIds.contains(key)){
+            bundleIds.add(key);
+        }
+        return bundleIds;
+    }
+
+    /**
+     * Remove all doubled '_' hereby normalizing the bundle key.
+     * @param key the key, not null.
+     * @return the normaliuzed key, not null.
+     */
+    private String reduceKey(String key) {
+        String reduced = key.replace("___","_").replace("__","_");
+        if(reduced.endsWith("_")){
+            reduced = reduced.substring(0,reduced.length()-1);
+        }
+        return reduced;
+    }
+
+    /**
+     * Evaluates the base name to be used for creating the resource bundle used.
+     * @return
+     */
+    private 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/lang/tamaya";
+        }
+        return baseName.replace('.', '/');
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java
new file mode 100644
index 0000000..e2a761c
--- /dev/null
+++ b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java
@@ -0,0 +1,61 @@
+///*
+// * 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.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.
+// */
+//public class ConfiguredMessageProvider implements MessageProvider{
+//
+//    /**
+//     * Private singleton constructor.
+//     */
+//    public ConfiguredMessageProvider(){}
+//
+//    /**
+//     * 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("ui/lang/tamaya", locale);
+//            return bundle.getString(bundleID);
+//        }
+//        catch(Exception e){
+//            return bundleID;
+//        }
+//    }
+//
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
new file mode 100644
index 0000000..c0aa092
--- /dev/null
+++ b/sandbox/ui/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/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/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
new file mode 100644
index 0000000..0727515
--- /dev/null
+++ b/sandbox/ui/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
@@ -0,0 +1,60 @@
+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/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java
new file mode 100644
index 0000000..a15ae46
--- /dev/null
+++ b/sandbox/ui/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/6411646c/sandbox/ui/src/main/java/org/apache/tamaya/ui/services/UserService.java
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/java/org/apache/tamaya/ui/services/UserService.java b/sandbox/ui/src/main/java/org/apache/tamaya/ui/services/UserService.java
new file mode 100644
index 0000000..71a8a43
--- /dev/null
+++ b/sandbox/ui/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/6411646c/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider b/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
new file mode 100644
index 0000000..eeb467b
--- /dev/null
+++ b/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.ViewProvider
@@ -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.
+#
+org.apache.tamaya.ui.views.HomeView$Provider
+org.apache.tamaya.ui.views.ConfigView$Provider
+org.apache.tamaya.ui.views.ComponentView$Provider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6411646c/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider b/sandbox/ui/src/main/resources/META-INF/services/org.apache.tamaya.ui.services.MessageProvider
new file mode 100644
index 0000000..6ce4a9f
--- /dev/null
+++ b/sandbox/ui/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/6411646c/sandbox/ui/src/main/resources/ui/lang/tamaya.properties
----------------------------------------------------------------------
diff --git a/sandbox/ui/src/main/resources/ui/lang/tamaya.properties b/sandbox/ui/src/main/resources/ui/lang/tamaya.properties
new file mode 100644
index 0000000..16880d4
--- /dev/null
+++ b/sandbox/ui/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.components=Components
+
+view.config.name=Configuration
+view.home.name=Home
+view.components.name=Components