tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [1/3] incubator-tamaya-extensions git commit: TAMAYA-190: Simplified event component, updated docs.
Date Mon, 07 Nov 2016 00:45:12 GMT
Repository: incubator-tamaya-extensions
Updated Branches:
  refs/heads/master 9d346676a -> 7505b0078


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/delta/ConfigurationContextChangeTest.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/delta/ConfigurationContextChangeTest.java
b/modules/events/src/test/java/org/apache/tamaya/events/delta/ConfigurationContextChangeTest.java
deleted file mode 100644
index ee631ce..0000000
--- a/modules/events/src/test/java/org/apache/tamaya/events/delta/ConfigurationContextChangeTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.delta;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.core.propertysource.SystemPropertySource;
-import org.apache.tamaya.events.ChangeType;
-import org.apache.tamaya.events.ConfigurationContextChange;
-import org.apache.tamaya.events.ConfigurationContextChangeBuilder;
-import org.apache.tamaya.events.PropertySourceChangeBuilder;
-import org.apache.tamaya.spi.PropertySource;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Test class for {@link ConfigurationContextChange}.
- */
-public class ConfigurationContextChangeTest {
-
-    @Test
-    public void testEmptyChangeSet() throws Exception {
-        ConfigurationContextChange change = ConfigurationContextChange.emptyChangeSet(
-                ConfigurationProvider.getConfigurationContext());
-        assertNotNull(change);
-        assertTrue(change.isEmpty());
-    }
-
-    @Test
-    public void testGetVersion() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertNotNull(change.getVersion());
-        change = ConfigurationContextChangeBuilder.of().setVersion("version2").build();
-        assertNotNull(change.getVersion());
-        assertEquals("version2", change.getVersion());
-    }
-
-    @Test
-    public void testGetTimestamp() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue((System.currentTimeMillis() - change.getTimestamp()) <= 10L);
-        change = ConfigurationContextChangeBuilder.of().setTimestamp(10L).build();
-        assertEquals(10L, change.getTimestamp());
-    }
-
-    @Test
-    public void testGetPropertySourceChanges() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceChanges(). isEmpty());
-        change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceChanges(). isEmpty());
-    }
-
-    @Test
-    public void testGetPropertySourceUpdates() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceChanges(). isEmpty());
-        change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceUpdates(). isEmpty());
-    }
-
-    @Test
-    public void testGetRemovedPropertySources() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceChanges(). isEmpty());
-        change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getRemovedPropertySources(). isEmpty());
-    }
-
-    @Test
-    public void testGetAddedPropertySources() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceChanges(). isEmpty());
-        change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getAddedPropertySources().isEmpty());
-    }
-
-    @Test
-    public void testGetUpdatedPropertySources() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getPropertySourceChanges(). isEmpty());
-        change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.getUpdatedPropertySources().isEmpty());
-    }
-
-    @Test
-    public void testIsAffected() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        PropertySource ps = new SystemPropertySource();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().changedPropertySource(
-                PropertySourceChangeBuilder.of(ps, ChangeType.UPDATED).build()
-        ).build();
-        String toString = change.toString();
-        assertTrue(change.isAffected(ps));
-    }
-
-    @Test
-    public void testIsEmpty() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().build();
-        assertTrue(change.isEmpty());
-        change = ConfigurationContextChangeBuilder.of().newPropertySource(new SystemPropertySource()).build();
-        assertFalse(change.isEmpty());
-    }
-
-    @Test
-    public void testToString() throws Exception {
-        Configuration config = ConfigurationProvider.getConfiguration();
-        ConfigurationContextChange change = ConfigurationContextChangeBuilder.of().newPropertySource(new
SystemPropertySource()).build();
-        String toString = change.toString();
-        assertNotNull(toString);
-        assertTrue(toString.contains(new SystemPropertySource().getName()));
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/delta/PropertySourceChangeTest.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/delta/PropertySourceChangeTest.java
b/modules/events/src/test/java/org/apache/tamaya/events/delta/PropertySourceChangeTest.java
deleted file mode 100644
index 0dcdfba..0000000
--- a/modules/events/src/test/java/org/apache/tamaya/events/delta/PropertySourceChangeTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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.delta;
-
-import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
-import org.apache.tamaya.core.propertysource.SimplePropertySource;
-import org.apache.tamaya.core.propertysource.SystemPropertySource;
-import org.apache.tamaya.events.ChangeType;
-import org.apache.tamaya.events.PropertySourceChange;
-import org.apache.tamaya.events.PropertySourceChangeBuilder;
-import org.apache.tamaya.spi.PropertySource;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests for {@link PropertySourceChange} and its builder.
- */
-public class PropertySourceChangeTest {
-
-    private static final PropertySource myPS = new SystemPropertySource();
-
-    @Test
-    public void testGetChangeType() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED).build();
-        assertEquals(change.getChangeType(), ChangeType.DELETED);
-        change = PropertySourceChangeBuilder.of(myPS, ChangeType.UPDATED).build();
-        assertEquals(change.getChangeType(), ChangeType.UPDATED);
-    }
-
-    @Test
-    public void testGetPropertySource() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED).build();
-        assertEquals(change.getResource().getName(), myPS.getName());
-    }
-
-    @Test
-    public void testGetVersion() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED)
-                .setVersion("myVersion1").build();
-        assertEquals(change.getVersion(), "myVersion1");
-    }
-
-    @Test
-    public void testGetTimestamp() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED)
-                .setTimestamp(111L).build();
-        assertEquals(change.getTimestamp(), 111L);
-    }
-
-    @Test
-    public void testGetEvents() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED)
-                .addChanges(
-                        new EnvironmentPropertySource()
-                ).build();
-        assertTrue(change.getChanges().size()>0);
-    }
-
-    @Test
-    public void testGetRemovedSize() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.UPDATED)
-                .addChanges(
-                        new EnvironmentPropertySource()
-                ).build();
-        assertTrue(change.getRemovedSize()>0);
-    }
-
-    @Test
-    public void testGetAddedSize() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED)
-                .addChanges(
-                        new EnvironmentPropertySource()
-                ).build();
-        assertTrue(change.getAddedSize()>0);
-    }
-
-    @Test
-    public void testGetUpdatedSize() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(myPS, ChangeType.DELETED)
-                .addChanges(
-                        new EnvironmentPropertySource()
-                ).build();
-        assertTrue(change.getUpdatedSize()==0);
-    }
-
-    @Test
-    public void testIsRemoved() throws Exception {
-        Map<String, String> testData = new HashMap<>();
-        testData.put("key1", "value1");
-        testData.put("key2", "value2");
-        PropertySource ps1 = new SimplePropertySource("test", testData);
-        testData = new HashMap<>();
-        testData.put("key1", "value2");
-        testData.put("key3", "value3");
-        PropertySource ps2 = new SimplePropertySource("test", testData);
-        PropertySourceChange change = PropertySourceChangeBuilder.of(ps1, ChangeType.UPDATED)
-                .addChanges(
-                        ps2
-                ).build();
-        assertFalse(change.isRemoved("key1"));
-        assertTrue(change.isRemoved("key2"));
-        assertFalse(change.isRemoved("key3"));
-    }
-
-    @Test
-    public void testIsAdded() throws Exception {
-        Map<String, String> testData = new HashMap<>();
-        testData.put("key1", "value1");
-        testData.put("key2", "value2");
-        PropertySource ps1 = new SimplePropertySource("test", testData);
-        testData = new HashMap<>();
-        testData.put("key1", "value2");
-        testData.put("key3", "value3");
-        PropertySource ps2 = new SimplePropertySource("test", testData);
-        PropertySourceChange change = PropertySourceChangeBuilder.of(ps1, ChangeType.UPDATED)
-                .addChanges(
-                        ps2
-                ).build();
-        assertTrue(change.isAdded("key3"));
-        assertFalse(change.isAdded("key2"));
-        assertFalse(change.isAdded("key1"));
-    }
-
-    @Test
-    public void testIsUpdated() throws Exception {
-        Map<String, String> testData = new HashMap<>();
-        testData.put("key1", "value1");
-        testData.put("key2", "value2");
-        PropertySource ps1 = new SimplePropertySource("test", testData);
-        testData = new HashMap<>();
-        testData.put("key1", "value2");
-        testData.put("key3", "value3");
-        PropertySource ps2 = new SimplePropertySource("test", testData);
-        PropertySourceChange change = PropertySourceChangeBuilder.of(ps1, ChangeType.UPDATED)
-                .addChanges(
-                        ps2
-                ).build();
-        assertTrue(change.isUpdated("key1"));
-        assertFalse(change.isUpdated("key2"));
-        assertFalse(change.isUpdated("key3"));
-    }
-
-    @Test
-    public void testContainsKey() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(new EnvironmentPropertySource(),
ChangeType.DELETED)
-                .addChanges(
-                        myPS
-                ).build();
-        assertTrue(change.isKeyAffected("java.version"));
-    }
-
-    @Test
-    public void testIsEmpty() throws Exception {
-        PropertySourceChange change = PropertySourceChangeBuilder.of(new EnvironmentPropertySource(),
ChangeType.DELETED)
-                .build();
-        assertTrue(change.isEmpty());
-        change = PropertySourceChangeBuilder.of(new EnvironmentPropertySource(), ChangeType.DELETED)
-                .addChanges(
-                        myPS
-                ).build();
-        assertFalse(change.isEmpty());
-    }
-
-    @Test
-    public void testOfAdded() throws Exception {
-        PropertySourceChange change = PropertySourceChange.ofAdded(myPS);
-        assertNotNull(change);
-        assertEquals(change.getChangeType(), ChangeType.NEW);
-    }
-
-    @Test
-    public void testOfDeleted() throws Exception {
-        PropertySourceChange change = PropertySourceChange.ofDeleted(myPS);
-        assertNotNull(change);
-        assertEquals(change.getChangeType(), ChangeType.DELETED);
-    }
-
-    @Test
-    public void testToString() throws Exception {
-        PropertySourceChange change = PropertySourceChange.ofAdded(myPS);
-        String toString = change.toString();
-        assertNotNull(toString);
-        assertTrue(toString.contains(myPS.getName()));
-        change = PropertySourceChange.ofDeleted(myPS);
-        toString = change.toString();
-        assertNotNull(toString);
-        assertTrue(toString.contains(myPS.getName()));
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
new file mode 100644
index 0000000..283719e
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
@@ -0,0 +1,144 @@
+/*
+ * 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.folderobserver;
+
+import org.apache.tamaya.ConfigException;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * Class that has the responsibility to watch the folder and then publish the changes to
a
+ * {@link org.apache.tamaya.events.PropertySourceChange}.
+ * @see ObservingPropertySourceProvider
+ * This listener will wait to events and wait to one second to watch again.
+ * <p>If new file was created or modified will commit from this file.</p>
+ * <p>If a file was removed then the listener will load using all files left.</p>
+ * @author otaviojava
+ */
+class FileChangeListener implements Runnable {
+
+    private static final Logger LOGGER = Logger.getLogger(FileChangeListener.class.getName());
+
+    private final WatchService watchService;
+
+    private final FileChangeObserver observer;
+
+    private final Path directory;
+
+    private volatile boolean running = true;
+
+    public FileChangeListener(Path directory, FileChangeObserver observer) {
+        this.observer = observer;
+        this.directory = directory;
+        this.watchService = getWatchService();
+
+        if (watchService!=null && directory!=null) {
+            try {
+                directory.register(watchService,
+                        StandardWatchEventKinds.ENTRY_DELETE,
+                        StandardWatchEventKinds.ENTRY_MODIFY,
+                        StandardWatchEventKinds.ENTRY_CREATE);
+            } catch (IOException e) {
+                throw new FileChangeListenerException("An error happened when does try to
registry to watch the folder", e);
+            }
+        }
+    }
+
+    /**
+     * Stops the listener service from observing the target directory.
+     */
+    public void stopListener(){
+        running = false;
+    }
+
+    @Override
+    public void run() {
+        if (watchService!=null || directory!=null) {
+            return;
+        }
+        while (running) {
+            watchFolder();
+        }
+    }
+
+    /**
+     * Start watching the current folder.
+     */
+    private void watchFolder() {
+        try {
+            WatchKey watckKey = watchService.take();
+            for (WatchEvent<?> event : watckKey.pollEvents()) {
+                Path filePath = (Path) watckKey.watchable();
+                if(event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE)||
+                        event.kind().equals(StandardWatchEventKinds.ENTRY_MODIFY) ||
+                        event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)){
+                    LOGGER.info("File change detected in: " + filePath.getFileName());
+                    observer.directoryChanged(filePath);
+                }
+            }
+            watckKey.reset();
+            Thread.sleep(1_000L);
+        } catch (Exception e) {
+            throw new FileChangeListenerException("An error happened when does try to watch
the folder", e);
+        }
+    }
+
+    /**
+     * Get the watch service.
+     * @return the watch service, or null, if the watch service is not supported.
+     */
+    private WatchService getWatchService() {
+        try {
+            FileSystem fileSystem = Paths.get(".").getFileSystem();
+            return fileSystem.newWatchService();
+        } catch (IOException e) {
+            LOGGER.log(Level.WARNING, "The file System does not supports WatchService", e);
+            return null;
+        }
+
+    }
+
+    /**
+     * Exception if file listening fails.
+     */
+    static class FileChangeListenerException extends ConfigException {
+        /** Serialversion UID. */
+        private static final long serialVersionUID = -8965486770881001513L;
+
+        /**
+         * Constructor.
+         * @param message a message
+         * @param cause an (optional) root cause.
+         */
+        public FileChangeListenerException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeObserver.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeObserver.java
b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeObserver.java
new file mode 100644
index 0000000..63d25cd
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/FileChangeObserver.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.events.folderobserver;
+
+import java.nio.file.Path;
+
+/**
+ * Observer to be used in {@link FileChangeListener} to commit all configurations and provider.
+ */
+interface FileChangeObserver {
+    /**
+     * Called when a file has been modified.
+     * @param path the file path, not null.
+     */
+    void directoryChanged(Path path);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
new file mode 100644
index 0000000..908c327
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
@@ -0,0 +1,190 @@
+/*
+ * 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.folderobserver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spisupport.BasePropertySource;
+
+/**
+ * This implementation runs in a folder taking up all files compatible with the given
+ * ConfigurationFormats. When a file is added, deleted or modified the PropertySourceProvider
+ * will adapt the changes automatically and trigger according
+ * {@link org.apache.tamaya.events.PropertySourceChange} events.
+ * The default folder is META-INF/config, but you can change it via an absolute path in the
+ * "-Dtamaya.configdir" parameter.
+ */
+public class ObservingPropertySourceProvider implements PropertySourceProvider, FileChangeObserver
{
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(ObservingPropertySourceProvider.class.getName());
+    /**
+     * The current active property sources of this provider.
+     */
+    private final List<PropertySource> propertySources = Collections.synchronizedList(new
LinkedList<PropertySource>());
+    /**
+     * The thread pool used.
+     */
+    private final ExecutorService executor = Executors.newSingleThreadExecutor();
+
+    /**
+     * Constructorm using an explicit directory, ignoring all kind of configuration, if set.
+     *
+     * @param directory the target directory. If null, the default configuration and system
property are used.
+     */
+    public ObservingPropertySourceProvider(Path directory) {
+        if (directory == null) {
+            directory = getDirectory();
+        }
+        if (directory!=null){
+            synchronized (this.propertySources) {
+                this.propertySources.addAll(readConfiguration(directory));
+            }
+            final Runnable runnable = new FileChangeListener(directory, this);
+            executor.execute(runnable);
+        } else {
+            executor.shutdown();
+        }
+    }
+
+    /**
+     * Read the initial configuration.
+     *
+     * @param directory the target directory, not null.
+     */
+    private List<PropertySource> readConfiguration(Path directory) {
+        final List<PropertySource> result = new ArrayList<>();
+        try {
+            synchronized (propertySources) {
+                for (final Path path : Files.newDirectoryStream(directory, "*")) {
+                    result.addAll(getPropertySources(path));
+                }
+                return result;
+            }
+        } catch (final IOException e) {
+            LOG.log(Level.WARNING, "Failed to read configuration from dir: " + directory,
e);
+        }
+        return result;
+    }
+
+    /**
+     * Read property sources from the given file.
+     * 
+     * @param file source of the property sources.
+     * @return property sources from the given file.
+     */
+    protected Collection<PropertySource> getPropertySources(final Path file) {
+        return Arrays.asList(new PropertySource[]{new BasePropertySource() {
+            private final Map<String,String> props = readProperties(file);
+
+            @Override
+            public Map<String, String> getProperties() {
+                return props;
+            }
+        }});
+    }
+
+    /**
+     * Load a single file.
+     *
+     * @param file the file, not null.
+     * @return properties as read from the given file.
+     */
+    protected static Map<String,String> readProperties(Path file) {
+        try (InputStream is = file.toUri().toURL().openStream()){
+            final Properties props = new Properties();
+                props.load(is);
+            final Map<String,String> result = new HashMap<>();
+            for(final Map.Entry<Object,Object> en:props.entrySet()){
+                result.put(String.valueOf(en.getKey()), String.valueOf(en.getValue()));
+            }
+            return result;
+        } catch (final Exception e) {
+            LOG.log(Level.INFO, "Error reading file: " + file.toString() +
+                    ", using format: properties", e);
+        }
+        return Collections.emptyMap();
+    }
+
+
+    /**
+     * Evaluates the target directory from system property (tamaya.configdir) or classpath.
+     *
+     * @return the directory to be read, or null.
+     */
+    private Path getDirectory() {
+        final String absolutePath = System.getProperty("tamaya.configdir");
+        if (null!=absolutePath) {
+            final Path path = Paths.get(absolutePath);
+            if (Files.isDirectory(path)) {
+                return path;
+            }
+        }
+        final URL resource = ObservingPropertySourceProvider.class.getResource("/META-INF/config/");
+        if (null!=resource) {
+            try {
+                return Paths.get(resource.toURI());
+            } catch (final URISyntaxException e) {
+                throw new ConfigException("An error to find the directory to watch", e);
+            }
+        }
+        return null;
+    }
+
+
+    @Override
+    public void directoryChanged(Path directory) {
+        synchronized (this.propertySources) {
+            final List<PropertySource> existingPropertySources = new ArrayList<>(propertySources);
+            propertySources.clear();
+            final Collection<PropertySource> sourcesRead = readConfiguration(directory);
+            this.propertySources.addAll(sourcesRead);
+        }
+    }
+
+    @Override
+    public Collection<PropertySource> getPropertySources() {
+        synchronized (propertySources) {
+            return new ArrayList<>(this.propertySources);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/TestObservingProvider.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/TestObservingProvider.java
b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/TestObservingProvider.java
new file mode 100644
index 0000000..b1e3962
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/TestObservingProvider.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.events.folderobserver;
+
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Test configuration property source provider that observes a directory and updated the
config if necessary.
+ */
+public class TestObservingProvider extends ObservingPropertySourceProvider{
+
+    public static Path propertyLocation;
+
+    static{
+        try {
+            // create some temporary config
+            Path tempDir = Files.createTempDirectory("observedFolder");
+
+            TestObservingProvider.propertyLocation = tempDir;
+
+            FileUtils.copyInputStreamToFile(
+                    TestObservingProvider.class.getResourceAsStream("/test.properties"),
+                    new File(tempDir.toFile(), "test.properties"));
+
+            Runtime.getRuntime().addShutdownHook(new Thread(){
+                @Override
+                public void run(){
+                    try{
+                        // cleanup directory
+                        Files.deleteIfExists(getTargetFile("test1.properties"));
+                        Files.deleteIfExists(getTargetFile("test2.properties"));
+                        Files.deleteIfExists(getTargetFile("test3.properties"));
+                    }
+                    catch(Exception e){
+                        Logger.getLogger("TestObservingProvider").log(Level.WARNING,
+                                "Failed to cleanup config test dir", e);
+                    }
+                }
+            });
+        }
+        catch(Exception e){
+            Logger.getLogger("TestObservingProvider").log(Level.WARNING, "Failed to init
config test dir", e);
+        }
+    }
+
+    private static Path getTargetFile(String name) {
+        File testFile = new File(TestObservingProvider.getTestDirectory(), name);
+        return Paths.get(testFile.toURI());
+    }
+
+    public TestObservingProvider(){
+        super(propertyLocation);
+        Logger.getLogger(getClass().getName()).info("Using test directory: " + getTestPath());
+    }
+
+    public static File getTestDirectory(){
+        String tempDir = System.getProperty("java.io.tmpdir");
+        File dir = new File(tempDir, "tamaya-events-testdir");
+        if(!dir.exists()){
+            dir.mkdirs();
+        }
+        return dir;
+    }
+
+    private static String getTestPath(){
+        return getTestDirectory().getAbsolutePath();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/package-info.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/package-info.java
b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/package-info.java
new file mode 100644
index 0000000..347f2d8
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/folderobserver/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * This package contains code to observe a folder for file changes and to trigger
+ * corresponding events, that are handled by an according {@link org.apache.tamaya.events.folderobserver.ObservingPropertySourceProvider}
+ * instance.
+ */
+package org.apache.tamaya.events.folderobserver;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
----------------------------------------------------------------------
diff --git a/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
index f675fd6..d42210e 100644
--- a/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
+++ b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
@@ -16,4 +16,4 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-org.apache.tamaya.events.internal.DefaultConfigurationContextChangeListener
\ No newline at end of file
+org.apache.tamaya.events.ObservedConfigTest$MyConfigObserver
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/7505b007/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
----------------------------------------------------------------------
diff --git a/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
index d34b4a2..6b3dc1d 100644
--- a/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
+++ b/modules/events/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
@@ -16,4 +16,4 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-org.apache.tamaya.events.TestObservingProvider
+org.apache.tamaya.events.folderobserver.TestObservingProvider



Mime
View raw message