You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by pl...@apache.org on 2016/09/06 17:18:46 UTC
[50/50] [abbrv] incubator-tamaya-sandbox git commit: - Moved UI
module into sandbox,
including UI parts. - Decoupled accordingly existing modules from UI. - Fixed
a few quality issues.
- Moved UI module into sandbox, including UI parts.
- Decoupled accordingly existing modules from UI.
- Fixed a few quality issues.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/e4b68dfb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/e4b68dfb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/e4b68dfb
Branch: refs/heads/master
Commit: e4b68dfb9e48a5f477e726f09698e2770303f5de
Parents: 97b5f43
Author: anatole <an...@apache.org>
Authored: Tue Aug 16 15:50:17 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Aug 16 15:51:30 2016 +0200
----------------------------------------------------------------------
.../staged/src/test/resources/tamaya-TEST.yaml | 27 +++
.../src/test/resources/tamaya-config.yaml | 91 ++------
pom.xml | 1 +
ui/base/pom.xml | 156 +++++++++++++
.../org/apache/tamaya/ui/ApplicationLayout.java | 72 ++++++
.../java/org/apache/tamaya/ui/CurrentUser.java | 58 +++++
.../main/java/org/apache/tamaya/ui/NavBar.java | 127 ++++++++++
.../java/org/apache/tamaya/ui/TamayaUI.java | 77 +++++++
.../java/org/apache/tamaya/ui/UIConstants.java | 36 +++
.../main/java/org/apache/tamaya/ui/User.java | 154 +++++++++++++
.../java/org/apache/tamaya/ui/VadiinApp.java | 97 ++++++++
.../java/org/apache/tamaya/ui/ViewProvider.java | 73 ++++++
.../tamaya/ui/components/LazyProvider.java | 81 +++++++
.../tamaya/ui/components/PageTitleUpdater.java | 47 ++++
.../ui/components/VerticalSpacedLayout.java | 32 +++
.../org/apache/tamaya/ui/event/EventBus.java | 52 +++++
.../org/apache/tamaya/ui/event/LogoutEvent.java | 48 ++++
.../apache/tamaya/ui/event/NavigationEvent.java | 53 +++++
.../org/apache/tamaya/ui/events/EventView.java | 181 +++++++++++++++
.../ConfigurationBasedMessageProvider.java | 176 ++++++++++++++
.../ui/internal/ConfiguredMessageProvider.java | 61 +++++
.../ui/internal/ConfiguredUserService.java | 76 ++++++
.../internal/ResourceBundleMessageProvider.java | 91 ++++++++
.../tamaya/ui/internal/URLPropertySource.java | 78 +++++++
.../tamaya/ui/services/MessageProvider.java | 43 ++++
.../apache/tamaya/ui/services/UserService.java | 30 +++
.../org/apache/tamaya/ui/views/ConfigView.java | 229 +++++++++++++++++++
.../org/apache/tamaya/ui/views/ErrorView.java | 43 ++++
.../org/apache/tamaya/ui/views/HomeView.java | 94 ++++++++
.../org/apache/tamaya/ui/views/SystemView.java | 117 ++++++++++
.../views/TamayaGeneralSystemInfoProvider.java | 56 +++++
.../apache/tamaya/ui/views/login/LoginBox.java | 112 +++++++++
.../tamaya/ui/views/login/LoginEvent.java | 55 +++++
.../apache/tamaya/ui/views/login/LoginView.java | 37 +++
.../META-INF/javaconfiguration.properties | 21 ++
.../services/org.apache.tamaya.ui.ViewProvider | 24 ++
...rg.apache.tamaya.ui.services.MessageProvider | 19 ++
.../org.apache.tamaya.ui.services.UserService | 19 ++
.../src/main/resources/config/application.yml | 28 +++
.../main/resources/ui/lang/tamaya.properties | 28 +++
.../src/test/resources/config/application.yml | 36 +++
.../org/apache/tamaya/ui/events/EventView.java | 181 +++++++++++++++
.../services/org.apache.tamaya.ui.ViewProvider | 19 ++
ui/mutableconfig/pom.xml | 36 +++
.../ui/mutableconfig/ConfigEditorWidget.java | 132 +++++++++++
.../ui/mutableconfig/ConfigUpdaterView.java | 121 ++++++++++
.../tamaya/ui/mutableconfig/ProtocolWidget.java | 90 ++++++++
.../mutableconfig/TransactionControlWidget.java | 229 +++++++++++++++++++
.../services/org.apache.tamaya.ui.ViewProvider | 19 ++
49 files changed, 3691 insertions(+), 72 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/metamodels/staged/src/test/resources/tamaya-TEST.yaml
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/test/resources/tamaya-TEST.yaml b/metamodels/staged/src/test/resources/tamaya-TEST.yaml
new file mode 100644
index 0000000..3e56656
--- /dev/null
+++ b/metamodels/staged/src/test/resources/tamaya-TEST.yaml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy 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-configuration:
+ includes:
+ tamaya-DEFAULT.yaml
+
+ property-sources:
+ - class: org.apache.tamaya.resources.ResourceProvider
+ resource: classpath:META-INF/config/test/**/*.*"
+ - class: org.apache.tamaya.resources.ResourceProvider
+ resource: classpath://META-INF/config/test/**/*.*"
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/metamodels/staged/src/test/resources/tamaya-config.yaml
----------------------------------------------------------------------
diff --git a/metamodels/staged/src/test/resources/tamaya-config.yaml b/metamodels/staged/src/test/resources/tamaya-config.yaml
index c9de1c8..a2980f6 100644
--- a/metamodels/staged/src/test/resources/tamaya-config.yaml
+++ b/metamodels/staged/src/test/resources/tamaya-config.yaml
@@ -16,75 +16,22 @@
# specific language governing permissions and limitations
# under the License.
#
-TAMAYA:
- PROFILES-DEF:
- - selectable: DEFAULT,DEV,TEST,PTA,PROD
- - supports-multi: false
- - defaults: DEFAULT
- - default-active: DEV
- - defined-by: sys-property:ENV, env-property:ENV
-
- FORMATS:
- - formats: yaml, properties, xml-properties
- - suffixes: yaml, yml, properties, xml
-
- PROFILES:
- <COMMON>:
- - sources:
- - "named:env-properties" # provider name, or class name
- - "named:main-args"
- - "named:sys-properties"
- - "resource:classpath:META-INF/config/**/*.SUFFIX"
- DEFAULT:
- - prio: 0 # optional
- - sources:
- - "resource:classpath:META-INF/defaults/**/*.SUFFIX"
- - "resource:file:${config.dir}/defaults/**/*.SUFFIX"
- - filters:
- - "section:DEFAULTS\\.*"
- - "section:defaults\\.*"
- - "exclude:_\\.*" # removes all meta-entries
- TEST:
- - prio: 100 # optional
- - filters:
- - "section:TEST\\.*"
- - "section:test\\.*"
- PROD:
- - prio: 1000 # optional
- - filters:
- - "section:PROD\\.*"
- - "section:prod\\.*"
-
- MODEL:
- - a.b.c:
- - type: "Section"
- - owner: "Test Model"
- - children: false
- - required: true
- - validation: "my.abc.ValidatorClass"
-
- - java.version:
- - type: "Parameter"
- - owner: "Expression Test"
- - expression: ".*v1.7.*"
- - required: true
-
- - ch.trivadis:
- - type: "Section" # Declaration only
-
- USAGE:
- track: true
-
-# FORMAT-DEF:
-# - formats: yaml, properties, xml-properties
-# - mappings:
-# yaml -> CustomMapping1Classname,
-# xml-properties -> Mapping2Classname
-# - suffixes:
-# yml, yaml, xml, properties
-
-# FUNCTIONS:
-# - default-map: map(DEFAULTS,.)
-# - env-map: map(${ENV},.)
-# - omit: omit(!DEFAULTS,!${ENV})
-# - config-map: omit,default-map,env-map
\ No newline at end of file
+tamaya-config:
+ source-selectors:
+ - DEFAULT:
+ source: tamaya-DEFAULT.yml
+ labels: env=TEST env=PTA env=PROD
+ - TEST:
+ source: tamaya-TEST.yml
+ labels: env=TEST
+ - PTA:
+ source: tamaya-PTA.yml
+ labels: env=PTA
+ - PROD:
+ source: tamaya-PROD.yml
+ labels: env=PROD
+
+ default-labels: env=DEV
+
+ expressions:
+ - env: ${sys-property:ENV}, ${env-property:ENV}, "DEV"
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a5831c7..2f01840 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,6 +40,7 @@ under the License.
<module>jodatime</module>
<module>sysprops</module>
<module>remote</module>
+ <module>ui</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/pom.xml
----------------------------------------------------------------------
diff --git a/ui/base/pom.xml b/ui/base/pom.xml
new file mode 100644
index 0000000..588e8b9
--- /dev/null
+++ b/ui/base/pom.xml
@@ -0,0 +1,156 @@
+<?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-base</artifactId>
+ <name>Apache Tamaya Modules - UI (Base)</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>src/main/webapp/VAADIN/themes/mytheme/addons.scss</exclude>
+ <exclude>src/main/webapp/VAADIN/themes/mytheme/styles.css</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ <!-- Exclude some unnecessary files generated by the GWT compiler. -->
+ <packagingExcludes>WEB-INF/classes/VAADIN/gwt-unitCache/**,
+ WEB-INF/classes/VAADIN/widgetsets/WEB-INF/**</packagingExcludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>com.vaadin</groupId>
+ <artifactId>vaadin-maven-plugin</artifactId>
+ <version>${vaadin.plugin.version}</version>
+ <configuration>
+ <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
+ <webappDirectory>${basedir}/target/classes/VAADIN/widgetsets</webappDirectory>
+ <draftCompile>false</draftCompile>
+ <compileReport>false</compileReport>
+ <style>OBF</style>
+ <strict>true</strict>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>update-theme</goal>
+ <goal>update-widgetset</goal>
+ <goal>compile</goal>
+ <!-- Comment out compile-theme goal to use on-the-fly theme compilation -->
+ <goal>compile-theme</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <!--<version>2.6.1</version>-->
+ <!-- Clean up also any pre-compiled themes -->
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>src/main/webapp/VAADIN/themes</directory>
+ <includes>
+ <include>**/styles.css</include>
+ <include>**/styles.scss.cache</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.4.1</version>
+ <configuration>
+ <createDependencyReducedPom>true</createDependencyReducedPom>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>${mainClass}</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+
+ <repositories>
+ <repository>
+ <id>vaadin-addons</id>
+ <url>http://maven.vaadin.com/vaadin-addons</url>
+ </repository>
+ <repository>
+ <id>vaadin-snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/ApplicationLayout.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/ApplicationLayout.java b/ui/base/src/main/java/org/apache/tamaya/ui/ApplicationLayout.java
new file mode 100644
index 0000000..20190be
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/ApplicationLayout.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ui.HorizontalLayout;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.UI;
+import org.apache.tamaya.ui.components.PageTitleUpdater;
+import org.apache.tamaya.ui.views.ErrorView;
+
+
+/**
+ * UI main layout.
+ */
+public class ApplicationLayout extends HorizontalLayout {
+
+ private NavBar navBar;
+ private Panel content;
+ private NavigationBar navigator;
+
+ public ApplicationLayout(UI ui) {
+ addStyleName(UIConstants.MAIN_LAYOUT);
+ setSizeFull();
+ initLayouts();
+ setupNavigator(ui);
+ }
+
+ public NavigationBar getNavigationBar(){
+ return navigator;
+ }
+
+ private void initLayouts() {
+ navBar = new NavBar(this);
+ // Use panel as main content container to allow it's content to scroll
+ content = new Panel();
+ content.setSizeFull();
+ content.addStyleName(UIConstants.PANEL_BORDERLESS);
+
+ addComponents(navBar, content);
+ setExpandRatio(content, 1);
+ }
+
+
+ private void setupNavigator(UI ui) {
+ navigator = new NavigationBar(ui, content, navBar);
+
+ // Add view change listeners so we can do things like select the correct menu item and update the page title
+ navigator.addViewChangeListener(navBar);
+ navigator.addViewChangeListener(new PageTitleUpdater());
+
+ navigator.navigateTo("/home");
+ navigator.setErrorView(ErrorView.class);
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/CurrentUser.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/CurrentUser.java b/ui/base/src/main/java/org/apache/tamaya/ui/CurrentUser.java
new file mode 100644
index 0000000..09fcf57
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/CurrentUser.java
@@ -0,0 +1,58 @@
+/*
+ * 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.server.VaadinSession;
+
+/**
+ * Convenience wrapper for storing and retrieving a user from the VaadinSession
+ */
+public final class CurrentUser {
+ /** The key used. */
+ private static final String KEY = "currentUser";
+
+ /**
+ * Singleton constructor.
+ */
+ private CurrentUser(){}
+
+ /**
+ * Set the current users.
+ * @param user the current user, not null.
+ */
+ public static void set(User user) {
+ VaadinSession.getCurrent().setAttribute(KEY, user);
+ }
+
+ /**
+ * Get the current user.
+ * @return the current user, or null.
+ */
+ public static User get() {
+ return (User) VaadinSession.getCurrent().getAttribute(KEY);
+ }
+
+ /**
+ * Checks if the current user is present and logged in.
+ * @return {@code true} if user is present and logged in.
+ */
+ public static boolean isLoggedIn() {
+ return get() != null && get().isLoggedin();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/NavBar.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/NavBar.java b/ui/base/src/main/java/org/apache/tamaya/ui/NavBar.java
new file mode 100644
index 0000000..9020cd8
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/NavBar.java
@@ -0,0 +1,127 @@
+/*
+ * 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.ViewChangeListener;
+import com.vaadin.server.FontAwesome;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.event.EventBus;
+import org.apache.tamaya.ui.event.LogoutEvent;
+import org.apache.tamaya.ui.event.NavigationEvent;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Left side navigation bar.
+ */
+public class NavBar extends VerticalLayout implements ViewChangeListener {
+
+ private Map<String, Button> buttonMap = new HashMap<>();
+
+ public NavBar(ApplicationLayout appLayout) {
+ // setHeight("100%");
+ setWidth(200, Unit.PIXELS);
+ addStyleName(UIConstants.MENU_ROOT);
+ addStyleName(UIConstants.NAVBAR);
+ setDefaultComponentAlignment(Alignment.TOP_LEFT);
+ MessageProvider messages = ServiceContextManager.getServiceContext().getService(MessageProvider.class);
+ Label logo = new Label("<strong>"+ messages.getMessage("project.name")+"</strong>", ContentMode.HTML);
+ logo.addStyleName(UIConstants.MENU_TITLE);
+ addComponent(logo);
+ addLogoutAndSettingsButton(appLayout);
+ }
+
+
+ private void addLogoutAndSettingsButton(final ApplicationLayout appLayout) {
+ MessageProvider messages = ServiceContextManager.getServiceContext().getService(MessageProvider.class);
+ Button logout = new Button(messages.getMessage("default.label.logout"), new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent clickEvent) {
+ User user = CurrentUser.get();
+ if(user!=null){
+ user.logout();
+ EventBus.post(new LogoutEvent(user));
+ }
+ CurrentUser.set(null);
+ }
+ });
+ logout.addStyleName(UIConstants.BUTTON_LOGOUT);
+ logout.addStyleName(UIConstants.BUTTON_BORDERLESS);
+ logout.setIcon(FontAwesome.SIGN_OUT);
+ Button settings = new Button("...", new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent clickEvent) {
+ UISettingsDialog dlog = new UISettingsDialog(appLayout.getNavigationBar());
+ dlog.show();
+ }
+ });
+ settings.addStyleName(UIConstants.BUTTON_SETTINGS);
+ settings.addStyleName(UIConstants.BUTTON_BORDERLESS);
+ VerticalLayout buttons = new VerticalLayout(logout, settings);
+ addComponent(buttons);
+ }
+
+ public void addViewButton(final String uri, String displayName) {
+ Button viewButton = new Button(displayName, new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent clickEvent) {
+ EventBus.post(new NavigationEvent(uri));
+ }
+ });
+ viewButton.addStyleName(UIConstants.BUTTON_LOGOUT);
+ // viewButton.addStyleName(UIConstants.MENU_ITEM);
+ viewButton.addStyleName(UIConstants.BUTTON_BORDERLESS);
+ addComponent(viewButton, components.size() - 1);
+ viewButton.setHeight(20, Unit.PIXELS);
+
+ buttonMap.put(uri, viewButton);
+ }
+
+ public void removeViewButton(String uri) {
+ Button button = buttonMap.remove(uri);
+ if(button!=null) {
+ removeComponent(button);
+ }
+ }
+
+ @Override
+ public boolean beforeViewChange(ViewChangeEvent event) {
+ return true; // false blocks navigation, always return true here
+ }
+
+ @Override
+ public void afterViewChange(ViewChangeEvent event) {
+ for(Button button: buttonMap.values()){
+ button.removeStyleName(UIConstants.SELECTED);
+ }
+ Button button = buttonMap.get(event.getViewName());
+ if (button != null) {
+ button.addStyleName(UIConstants.SELECTED);
+ }
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/TamayaUI.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/TamayaUI.java b/ui/base/src/main/java/org/apache/tamaya/ui/TamayaUI.java
new file mode 100644
index 0000000..f446d6f
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/TamayaUI.java
@@ -0,0 +1,77 @@
+/*
+ * 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.server.VaadinServlet;
+import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+
+import java.io.File;
+import java.util.logging.Logger;
+
+/**
+ * Tamaya UI Main class.
+ */
+public class TamayaUI {
+
+ private static final Logger LOG = Logger.getLogger(TamayaUI.class.getName());
+
+ /**
+ * Not an instantiable class.
+ */
+ private TamayaUI(){}
+
+ /**
+ * The main entry point, use configuration as follows:
+ * <pre>
+ * tamaya.server.contextPath: the context path, default=/tamaya
+ * tamaya.server.port: the port, default=8090
+ * tamaya.server.productionMode: vadiin production mode setting, default=false.
+ * </pre>
+ * @param args the args
+ * @throws Exception if startup fails.
+ */
+ public static void main(String[] args) throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ String contextPath = config.getOrDefault("tamaya.server.contextPath", "/tamaya");
+ String appBase = ".";
+ Tomcat tomcat = new Tomcat();
+ tomcat.setPort(Integer.valueOf(config.getOrDefault("tamaya.server.port", Integer.class, 8090) ));
+
+ // Define a web application context.
+ Context context = tomcat.addWebapp(contextPath, new File(
+ appBase).getAbsolutePath());
+ // Add Vadiin servlet
+ Wrapper wrapper = tomcat.addServlet(context, "vadiin-servlet",
+ VaadinServlet.class.getName());
+ wrapper.addInitParameter("ui",
+ VadiinApp.class.getName());
+ wrapper.addInitParameter("productionMode",config.getOrDefault("tamaya.server.productionMode", String.class,
+ "false"));
+ wrapper.addInitParameter("asyncSupported", "true");
+ context.addServletMapping("/*", "vadiin-servlet");
+ // bootstrap.addBundle(new AssetsBundle("/VAADIN", "/VAADIN", null, "vaadin"));
+ tomcat.start();
+ tomcat.getServer().await();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/UIConstants.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/UIConstants.java b/ui/base/src/main/java/org/apache/tamaya/ui/UIConstants.java
new file mode 100644
index 0000000..ecf90ff
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/UIConstants.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.ui;
+
+import com.vaadin.ui.themes.ValoTheme;
+
+/**
+ * Helper for theme. Less typos in CSS style names and easier to find usages in project.
+ */
+public class UIConstants extends ValoTheme {
+
+ public static final String MAIN_LAYOUT = "main-layout";
+ public static final String NAVBAR = "navbar";
+ public static final String SELECTED = "selected";
+ public static final String LOGIN_BOX = "login-box";
+
+
+ public static final String BUTTON_LOGOUT = "logout";
+ public static final String BUTTON_SETTINGS = BUTTON_TINY;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/User.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/User.java b/ui/base/src/main/java/org/apache/tamaya/ui/User.java
new file mode 100644
index 0000000..ae5b34a
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/User.java
@@ -0,0 +1,154 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A simple User object.
+ */
+public class User {
+ /** The user ID. */
+ private final String userID;
+ /** The full name. */
+ private String fulLName;
+ /** The credentials. */
+ private String credentials;
+ /** The user's roles. */
+ private Set<String> roles = new HashSet<>();
+ /** The user's last login date. */
+ private Date loginDate = new Date();
+ /** The user's last logout date. */
+ private Date logoutDate = new Date();
+
+ /**
+ * Constructor.
+ * @param uid the user ID, not null.
+ * @param fullName the full name.
+ * @param credentials the credentials.
+ * @param roles its roles.
+ */
+ public User(String uid, String fullName, String credentials, String... roles){
+ this.userID = Objects.requireNonNull(uid);
+ this.fulLName = fullName!=null?fullName:userID;
+ if(fullName==null){
+ this.fulLName = userID;
+ }
+ this.roles.addAll(Arrays.asList(roles));
+ this.credentials = credentials;
+ }
+
+ /**
+ * �Performs a login, checking the credentials.
+ * @param credentials the credentials.
+ * @return true, if the user could be logged in.
+ */
+ public boolean login(String credentials){
+ if(this.credentials!=null){
+ this.loginDate = new Date();
+ return this.credentials.equals(credentials);
+ }
+ return credentials==null || credentials.isEmpty();
+ }
+
+ /**
+ * Checks if the user is currently logged in.
+ * @return true, if the user is currently logged in.
+ */
+ public boolean isLoggedin(){
+ long now = System.currentTimeMillis();
+ if(this.logoutDate!=null && this.logoutDate.getTime() < now){
+ return false;
+ }
+ return this.loginDate!=null && this.loginDate.getTime() < now;
+ }
+
+ /**
+ * Logs the user out.
+ */
+ public void logout(){
+ this.logoutDate = new Date();
+ }
+
+ /**
+ * Get the user ID.
+ * @return the user ID, never null.
+ */
+ public String getUserID() {
+ return userID;
+ }
+
+ /**
+ * Get the full name.
+ * @return the full name, never null.
+ */
+ public String getFullName() {
+ return fulLName;
+ }
+
+ /**
+ * Checks if the user has the given role.
+ * @param role the role to be checked, not null.
+ * @return true, if the user has the required role.
+ */
+ public boolean hasRole(String role){
+ return this.roles.contains(role);
+ }
+
+ /**
+ * Get the user's roles.
+ * @return the roles, never null.
+ */
+ public Set<String> getRoles(){
+ return Collections.unmodifiableSet(roles);
+ }
+
+ /**
+ * Get the last login timestamp.
+ * @return the last login date, or null.
+ */
+ public Date getLoginDate(){
+ return loginDate;
+ }
+
+ /**
+ * Get the last login timestamp.
+ * @return the last login date, or null.
+ */
+ public Date getLogoutDate(){
+ return logoutDate;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "fulLName='" + fulLName + '\'' +
+ ", userID='" + userID + '\'' +
+ ", roles=" + roles +
+ ", loginDate=" + loginDate +
+ ", logoutDate=" + logoutDate +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/VadiinApp.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/VadiinApp.java b/ui/base/src/main/java/org/apache/tamaya/ui/VadiinApp.java
new file mode 100644
index 0000000..9e2510d
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/VadiinApp.java
@@ -0,0 +1,97 @@
+/*
+ * 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.google.common.eventbus.Subscribe;
+import com.vaadin.annotations.Theme;
+import com.vaadin.annotations.Title;
+import com.vaadin.server.Page;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.UI;
+import org.apache.tamaya.ui.event.LogoutEvent;
+import org.apache.tamaya.ui.event.NavigationEvent;
+import org.apache.tamaya.ui.views.login.LoginEvent;
+import org.apache.tamaya.ui.views.login.LoginView;
+
+/**
+ * This UI is the application entry point. A UI may either represent a browser window
+ * (or tab) or some part of a html page where a Vaadin application is embedded.
+ * <p>
+ * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
+ * overridden to add component to the user interface and initialize non-component functionality.
+ */
+@Theme("valo")
+@Title("Tamaya")
+public class VadiinApp extends UI {
+
+ public VadiinApp(){
+ super(new Panel());
+ super.setPollInterval(2000);
+ }
+
+ @Override
+ protected void init(VaadinRequest vaadinRequest) {
+ setupEventBus();
+ if (CurrentUser.isLoggedIn()) {
+ setContent(new ApplicationLayout(this));
+ } else {
+ setContent(new LoginView());
+ }
+ }
+
+ @Subscribe
+ public void userLoggedIn(
+ LoginEvent event) {
+ CurrentUser.set(event.getUser());
+ setContent(new ApplicationLayout(this));
+ }
+
+ @Subscribe
+ public void navigateTo(NavigationEvent evt) {
+ if(getNavigator()==null){
+ return;
+ }
+ if(evt.getViewName().isEmpty()){
+ getNavigator().navigateTo("/home");
+
+ }else {
+ getNavigator().navigateTo(evt.getViewName());
+ }
+ }
+
+ public static VadiinApp getCurrent() {
+ return (VadiinApp) UI.getCurrent();
+ }
+
+ @Subscribe
+ public void logout(LogoutEvent logoutEvent) {
+ // Don't invalidate the underlying HTTP session if you are using it for something else
+ VaadinSession.getCurrent().getSession().invalidate();
+ VaadinSession.getCurrent().close();
+ Page.getCurrent().reload();
+
+ }
+
+ private void setupEventBus() {
+ org.apache.tamaya.ui.event.EventBus.register(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/ViewProvider.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/ViewProvider.java b/ui/base/src/main/java/org/apache/tamaya/ui/ViewProvider.java
new file mode 100644
index 0000000..578689f
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/ViewProvider.java
@@ -0,0 +1,73 @@
+/*
+ * 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 view's name, used for resolving the view display name.
+ * @return the view's name.
+ */
+ String getName();
+
+ /**
+ * 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()
+ * @param params any parameters that may be needed to create the view.
+ * @return a new view instance, not null.
+ */
+ View createView(Object... params);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/components/LazyProvider.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/components/LazyProvider.java b/ui/base/src/main/java/org/apache/tamaya/ui/components/LazyProvider.java
new file mode 100644
index 0000000..2d1547f
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/components/LazyProvider.java
@@ -0,0 +1,81 @@
+/*
+ * 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.components;
+
+import com.vaadin.navigator.View;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.ViewProvider;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Lazily initializes a view when it's first accessed, then always returns the
+ * same instance on subsequent calls.
+ */
+public class LazyProvider implements ViewProvider {
+ private static final Logger LOG = Logger.getLogger(
+ LazyProvider.class.getName());
+ private Class<? extends View> viewClass;
+ private View view;
+ private String urlPattern;
+ private String name;
+
+ public LazyProvider(String name, String urlPattern, Class<? extends View> viewClass) {
+ this.viewClass = Objects.requireNonNull(viewClass);
+ this.urlPattern = Objects.requireNonNull(urlPattern);
+ this.name = Objects.requireNonNull(name);
+ }
+
+ @Override
+ public String getUrlPattern() {
+ return urlPattern;
+ }
+
+
+ @Override
+ public ViewLifecycle getLifecycle() {
+ return ViewLifecycle.LAZY;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+ .getMessage(name);
+ }
+
+ @Override
+ public View createView(Object... params) {
+ if(view==null){
+ try {
+ view = viewClass.newInstance();
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Failed to create view: "+urlPattern, e);
+ }
+ }
+ return view;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/components/PageTitleUpdater.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/components/PageTitleUpdater.java b/ui/base/src/main/java/org/apache/tamaya/ui/components/PageTitleUpdater.java
new file mode 100644
index 0000000..83a0105
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/components/PageTitleUpdater.java
@@ -0,0 +1,47 @@
+/*
+ * 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.components;
+
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.server.Page;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+/**
+ * Listener that updates the page title when a new view is shown.
+ */
+public class PageTitleUpdater implements ViewChangeListener {
+
+ @Override
+ public boolean beforeViewChange(ViewChangeEvent event) {
+ return true;
+ }
+
+ @Override
+ public void afterViewChange(ViewChangeEvent event) {
+ View view = event.getNewView();
+ String displayName = ServiceContextManager.getServiceContext().getService(MessageProvider.class)
+ .getMessage("view."+view.getClass().getSimpleName()+".name");
+ if (displayName != null) {
+ Page.getCurrent().setTitle(displayName);
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/components/VerticalSpacedLayout.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/components/VerticalSpacedLayout.java b/ui/base/src/main/java/org/apache/tamaya/ui/components/VerticalSpacedLayout.java
new file mode 100644
index 0000000..94fc980
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/components/VerticalSpacedLayout.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.ui.components;
+
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * Vertical layout with spacing and margin on by default
+ */
+public class VerticalSpacedLayout extends VerticalLayout {
+
+ public VerticalSpacedLayout() {
+ setMargin(true);
+ setSpacing(true);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/event/EventBus.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/event/EventBus.java b/ui/base/src/main/java/org/apache/tamaya/ui/event/EventBus.java
new file mode 100644
index 0000000..ffa9ba4
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/event/EventBus.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.ui.event;
+
+
+import com.google.common.eventbus.SubscriberExceptionContext;
+import com.google.common.eventbus.SubscriberExceptionHandler;
+
+/**
+ * Convenience class for accessing the _UI Scoped_ EventBus. If you are using something like the CDI event
+ * bus, you don't need a class like this.
+ */
+public final class EventBus {
+
+ private static final com.google.common.eventbus.EventBus EVENT_BUS =
+ new com.google.common.eventbus.EventBus(new SubscriberExceptionHandler(){
+ @Override
+ public void handleException(Throwable throwable, SubscriberExceptionContext subscriberExceptionContext) {
+ throwable.printStackTrace();
+ }
+ });
+
+ private EventBus(){}
+
+ public static void register(final Object listener) {
+ EVENT_BUS.register(listener);
+ }
+
+ public static void unregister(final Object listener) {
+ EVENT_BUS.unregister(listener);
+ }
+
+ public static void post(final Object event) {
+ EVENT_BUS.post(event);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/event/LogoutEvent.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/event/LogoutEvent.java b/ui/base/src/main/java/org/apache/tamaya/ui/event/LogoutEvent.java
new file mode 100644
index 0000000..680acc3
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/event/LogoutEvent.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.ui.event;
+
+import org.apache.tamaya.ui.User;
+
+import java.util.Objects;
+
+/**
+ * Event sent when the user has been logged out.
+ */
+public class LogoutEvent {
+
+ /** The user logged out. */
+ private User user;
+
+ /**
+ * Creates a new event.
+ * @param user the user logged out, not null.
+ */
+ public LogoutEvent(User user) {
+ this.user = Objects.requireNonNull(user);
+ }
+
+ /**
+ * Get the user logged out.
+ * @return the user logged out, not null.
+ */
+ public User getUser(){
+ return user;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/event/NavigationEvent.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/event/NavigationEvent.java b/ui/base/src/main/java/org/apache/tamaya/ui/event/NavigationEvent.java
new file mode 100644
index 0000000..bb863be
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/event/NavigationEvent.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.ui.event;
+
+
+import java.util.Objects;
+
+/**
+ * Event sent when the user wants to navigate.
+ */
+public class NavigationEvent {
+ /** The target view. */
+ private String viewName;
+
+ /**
+ * Constructor.
+ * @param viewName the target view, not null.
+ */
+ public NavigationEvent(String viewName) {
+ this.viewName = Objects.requireNonNull(viewName);
+ }
+
+ /**
+ * Access the target view name.
+ * @return the target view name, never null.
+ */
+ public String getViewName() {
+ return viewName;
+ }
+
+ @Override
+ public String toString() {
+ return "NavigationEvent{" +
+ "viewName='" + viewName + '\'' +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/events/EventView.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/events/EventView.java b/ui/base/src/main/java/org/apache/tamaya/ui/events/EventView.java
new file mode 100644
index 0000000..ffb59cf
--- /dev/null
+++ b/ui/base/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-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java b/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java
new file mode 100644
index 0000000..e242418
--- /dev/null
+++ b/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfigurationBasedMessageProvider.java
@@ -0,0 +1,176 @@
+/*
+ * 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.ConfigurationContextBuilder;
+import org.apache.tamaya.spisupport.DefaultConfiguration;
+import org.apache.tamaya.ui.services.MessageProvider;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+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 key;
+ }
+
+ 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 base name
+ */
+ 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-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java b/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredMessageProvider.java
new file mode 100644
index 0000000..00c0ec7
--- /dev/null
+++ b/ui/base/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/ui.lang/tamaya", locale);
+// return bundle.getString(bundleID);
+// }
+// catch(Exception e){
+// return bundleID;
+// }
+// }
+//
+//}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java b/ui/base/src/main/java/org/apache/tamaya/ui/internal/ConfiguredUserService.java
new file mode 100644
index 0000000..14af644
--- /dev/null
+++ b/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-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java b/ui/base/src/main/java/org/apache/tamaya/ui/internal/ResourceBundleMessageProvider.java
new file mode 100644
index 0000000..193144e
--- /dev/null
+++ b/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-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java b/ui/base/src/main/java/org/apache/tamaya/ui/internal/URLPropertySource.java
new file mode 100644
index 0000000..83b4af4
--- /dev/null
+++ b/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-sandbox/blob/e4b68dfb/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java
----------------------------------------------------------------------
diff --git a/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java b/ui/base/src/main/java/org/apache/tamaya/ui/services/MessageProvider.java
new file mode 100644
index 0000000..a15ae46
--- /dev/null
+++ b/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);
+
+}