Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 212C0200B85 for ; Thu, 15 Sep 2016 19:26:51 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 1F947160AC6; Thu, 15 Sep 2016 17:26:51 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id B9D23160ABA for ; Thu, 15 Sep 2016 19:26:48 +0200 (CEST) Received: (qmail 25794 invoked by uid 500); 15 Sep 2016 17:26:47 -0000 Mailing-List: contact commits-help@tamaya.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tamaya.incubator.apache.org Delivered-To: mailing list commits@tamaya.incubator.apache.org Received: (qmail 25781 invoked by uid 99); 15 Sep 2016 17:26:47 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 15 Sep 2016 17:26:47 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 5EB33C03BC for ; Thu, 15 Sep 2016 17:26:47 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx2-lw-us.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id noS8b8MN8SE4 for ; Thu, 15 Sep 2016 17:26:32 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx2-lw-us.apache.org (ASF Mail Server at mx2-lw-us.apache.org) with SMTP id A91185FC57 for ; Thu, 15 Sep 2016 17:26:20 +0000 (UTC) Received: (qmail 23618 invoked by uid 99); 15 Sep 2016 17:26:19 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 15 Sep 2016 17:26:19 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 5385CEF79F; Thu, 15 Sep 2016 17:26:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: plexus@apache.org To: commits@tamaya.incubator.apache.org Date: Thu, 15 Sep 2016 17:26:35 -0000 Message-Id: In-Reply-To: <601e12b1c9f64d208a03247b1439c1ca@git.apache.org> References: <601e12b1c9f64d208a03247b1439c1ca@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [18/24] incubator-tamaya git commit: Removed all modules from the main repository. They will be reborn in separate ASF repository. archived-at: Thu, 15 Sep 2016 17:26:51 -0000 http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/filter/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter ---------------------------------------------------------------------- diff --git a/modules/filter/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter b/modules/filter/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter deleted file mode 100644 index 806b833..0000000 --- a/modules/filter/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter +++ /dev/null @@ -1,19 +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 current the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -org.apache.tamaya.filter.ConfigurationFilter \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/filter/src/test/java/org/apache/tamaya/filter/ConfigurationFilterTest.java ---------------------------------------------------------------------- diff --git a/modules/filter/src/test/java/org/apache/tamaya/filter/ConfigurationFilterTest.java b/modules/filter/src/test/java/org/apache/tamaya/filter/ConfigurationFilterTest.java deleted file mode 100644 index 9d0da1f..0000000 --- a/modules/filter/src/test/java/org/apache/tamaya/filter/ConfigurationFilterTest.java +++ /dev/null @@ -1,122 +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.filter; - -import org.apache.tamaya.Configuration; -import org.apache.tamaya.ConfigurationProvider; -import org.apache.tamaya.spi.FilterContext; -import org.apache.tamaya.spi.PropertyFilter; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Tests for {@link ConfigurationFilter}. Created by atsticks on 11.02.16. - */ -public class ConfigurationFilterTest { - - @Test - public void testMetadataFiltered() throws Exception { - ConfigurationFilter.setMetadataFiltered(true); - assertTrue(ConfigurationFilter.isMetadataFiltered()); - ConfigurationFilter.setMetadataFiltered(false); - assertFalse(ConfigurationFilter.isMetadataFiltered()); - } - - @Test - public void testGetSingleFilters() throws Exception { - Configuration config = ConfigurationProvider.getConfiguration(); - assertNotNull(ConfigurationFilter.getSingleFilters()); - PropertyFilter testFilter = new PropertyFilter() { - @Override - public String filterProperty(String value, FilterContext context) { - return context.getKey() + ":testGetSingleFilters"; - } - }; - ConfigurationFilter.getSingleFilters().addFilter(testFilter); - assertEquals("user.home:testGetSingleFilters", config.get("user.home")); - ConfigurationFilter.getSingleFilters().removeFilter(testFilter); - assertNotSame("user.home:testGetSingleFilters", config.get("user.home")); - } - - @Test - public void testRemoveSingleFiltersAt0() throws Exception { - Configuration config = ConfigurationProvider.getConfiguration(); - assertNotNull(ConfigurationFilter.getSingleFilters()); - PropertyFilter testFilter = new PropertyFilter() { - @Override - public String filterProperty(String value, FilterContext context) { - return context.getKey() + ":testGetSingleFilters"; - } - }; - ConfigurationFilter.getSingleFilters().addFilter(testFilter); - assertEquals("user.home:testGetSingleFilters", config.get("user.home")); - ConfigurationFilter.getSingleFilters().removeFilter(0); - assertNotSame("user.home:testGetSingleFilters", config.get("user.home")); - } - - @Test - public void testGetMapFilters() throws Exception { - Configuration config = ConfigurationProvider.getConfiguration(); - assertNotNull(ConfigurationFilter.getMapFilters()); - PropertyFilter testFilter = new PropertyFilter() { - @Override - public String filterProperty(String value, FilterContext context) { - return context.getKey() + ":testGetMapFilters"; - } - }; - ConfigurationFilter.getMapFilters().addFilter(testFilter); - assertEquals("user.home:testGetMapFilters", config.getProperties().get("user.home")); - ConfigurationFilter.getSingleFilters().removeFilter(testFilter); - assertNotSame("user.home:testGetSingleFilters", config.getProperties().get("user.home")); - } - - @Test - public void testRemoveMapFilterAt0() throws Exception { - Configuration config = ConfigurationProvider.getConfiguration(); - assertNotNull(ConfigurationFilter.getMapFilters()); - PropertyFilter testFilter = new PropertyFilter() { - @Override - public String filterProperty(String value, FilterContext context) { - return context.getKey() + ":testGetMapFilters"; - } - }; - ConfigurationFilter.getMapFilters().addFilter(testFilter); - assertEquals("user.home:testGetMapFilters", config.getProperties().get("user.home")); - ConfigurationFilter.getMapFilters().removeFilter(0); - assertNotSame("user.home:testGetSingleFilters", config.getProperties().get("user.home")); - } - - @Test - public void testClearFilters() throws Exception { - Configuration config = ConfigurationProvider.getConfiguration(); - assertNotNull(ConfigurationFilter.getSingleFilters()); - PropertyFilter testFilter = new PropertyFilter() { - @Override - public String filterProperty(String value, FilterContext context) { - return context.getKey() + ":testGetSingleFilters"; - } - }; - ConfigurationFilter.getSingleFilters().addFilter(testFilter); - assertEquals("user.home:testGetSingleFilters", config.get("user.home")); - ConfigurationFilter.clearFilters(); - assertNotSame("user.home:testGetSingleFilters", config.get("user.home")); - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/filter/src/test/java/org/apache/tamaya/filter/ProgrammableFilterTest.java ---------------------------------------------------------------------- diff --git a/modules/filter/src/test/java/org/apache/tamaya/filter/ProgrammableFilterTest.java b/modules/filter/src/test/java/org/apache/tamaya/filter/ProgrammableFilterTest.java deleted file mode 100644 index 73db677..0000000 --- a/modules/filter/src/test/java/org/apache/tamaya/filter/ProgrammableFilterTest.java +++ /dev/null @@ -1,141 +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.filter; - -import org.apache.tamaya.spi.FilterContext; -import org.apache.tamaya.spi.PropertyFilter; -import org.junit.Test; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.*; - -/** - * Tests for {@link ProgrammableFilter}. Created by atsticks on 11.02.16. - */ -public class ProgrammableFilterTest { - - @Test - public void testAddRemoveFilter() throws Exception { - ProgrammableFilter filter = new ProgrammableFilter(); - RegexPropertyFilter regexFilter = new RegexPropertyFilter("test\\..*"); - Map map = new HashMap<>(); - map.put("test1", "test1"); - map.put("test2", "test2"); - map.put("test.test3", "test.test3"); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertEquals(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true)), "test.test3"); - filter.addFilter(regexFilter); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - filter.removeFilter(0); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertEquals(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true)), "test.test3"); - filter.addFilter(0, regexFilter); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - } - - @Test - public void testClearFilters() throws Exception { - ProgrammableFilter filter = new ProgrammableFilter(); - RegexPropertyFilter regexFilter = new RegexPropertyFilter("test\\..*"); - Map map = new HashMap<>(); - map.put("test1", "test1"); - map.put("test2", "test2"); - map.put("test.test3", "test.test3"); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertEquals(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true)), "test.test3"); - filter.addFilter(regexFilter); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - filter.clearFilters(); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertEquals(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true)), "test.test3"); - } - - @Test - public void testSetFilters() throws Exception { - ProgrammableFilter filter = new ProgrammableFilter(); - RegexPropertyFilter regexFilter = new RegexPropertyFilter("test\\..*"); - Map map = new HashMap<>(); - map.put("test1", "test1"); - map.put("test2", "test2"); - map.put("test.test3", "test.test3"); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertEquals(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true)), "test.test3"); - filter.setFilters(regexFilter); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - } - - @Test - public void testSetFilters1() throws Exception { - ProgrammableFilter filter = new ProgrammableFilter(); - RegexPropertyFilter regexFilter = new RegexPropertyFilter("test\\..*"); - Map map = new HashMap<>(); - map.put("test1", "test1"); - map.put("test2", "test2"); - map.put("test.test3", "test.test3"); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertEquals(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true)), "test.test3"); - filter.setFilters(Arrays.asList(new PropertyFilter[]{regexFilter})); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - } - - @Test - public void testGetFilters() throws Exception { - ProgrammableFilter filter = new ProgrammableFilter(); - assertNotNull(filter.getFilters()); - assertTrue(filter.getFilters().isEmpty()); - RegexPropertyFilter regexFilter = new RegexPropertyFilter("test\\..*"); - filter.addFilter(regexFilter); - assertNotNull(filter.getFilters()); - assertFalse(filter.getFilters().isEmpty()); - assertEquals(1, filter.getFilters().size()); - assertEquals(regexFilter, filter.getFilters().get(0)); - } - - @Test - public void testToString() throws Exception { - ProgrammableFilter filter = new ProgrammableFilter(); - assertFalse(filter.toString().contains("test\\..*")); - assertTrue(filter.toString().contains("ProgrammableFilter")); - assertFalse(filter.toString().contains("RegexPropertyFilter")); - RegexPropertyFilter regexFilter = new RegexPropertyFilter("test\\..*"); - filter.addFilter(regexFilter); - assertTrue(filter.toString().contains("test\\..*")); - assertTrue(filter.toString().contains("ProgrammableFilter")); - assertTrue(filter.toString().contains("RegexPropertyFilter")); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/filter/src/test/java/org/apache/tamaya/filter/RegexPropertyFilterTest.java ---------------------------------------------------------------------- diff --git a/modules/filter/src/test/java/org/apache/tamaya/filter/RegexPropertyFilterTest.java b/modules/filter/src/test/java/org/apache/tamaya/filter/RegexPropertyFilterTest.java deleted file mode 100644 index a560b04..0000000 --- a/modules/filter/src/test/java/org/apache/tamaya/filter/RegexPropertyFilterTest.java +++ /dev/null @@ -1,55 +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.filter; - -import org.apache.tamaya.spi.FilterContext; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.*; - -/** - * Tests for {@link RegexPropertyFilter}. Created by anatole on 11.02.16. - */ -public class RegexPropertyFilterTest { - - @org.junit.Test - public void testFilterProperty() throws Exception { - RegexPropertyFilter filter = new RegexPropertyFilter("test\\..*"); - Map map = new HashMap<>(); - map.put("test1", "test1"); - map.put("test2", "test2"); - map.put("test.test3", "test.test3"); - assertEquals(filter.filterProperty("test1", new FilterContext("test1", map, true)), "test1"); - assertEquals(filter.filterProperty("test2", new FilterContext("test2", map, true)), "test2"); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - filter = new RegexPropertyFilter(".*"); - assertNull(filter.filterProperty("test1", new FilterContext("test1", map, true))); - assertNull(filter.filterProperty("test2", new FilterContext("test2", map, true))); - assertNull(filter.filterProperty("test.test3", new FilterContext("test.test3", map, true))); - } - - @org.junit.Test - public void testToString() throws Exception { - RegexPropertyFilter filter = new RegexPropertyFilter("test\\..*"); - assertTrue(filter.toString().contains("test\\..*")); - assertTrue(filter.toString().contains("RegexPropertyFilter")); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/pom.xml ---------------------------------------------------------------------- diff --git a/modules/formats/pom.xml b/modules/formats/pom.xml deleted file mode 100644 index 3db73c9..0000000 --- a/modules/formats/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - - - org.apache.tamaya.ext - tamaya-extensions - 0.3-incubating-SNAPSHOT - .. - - tamaya-formats - Apache Tamaya Modules - Formats - bundle - - - 1.7 - - - - - org.apache.tamaya - tamaya-api - ${project.version} - provided - - - org.apache.tamaya.ext - tamaya-resources - ${project.version} - - - - org.apache.tamaya - tamaya-core - ${project.version} - test - - - org.hamcrest - java-hamcrest - - - junit - junit - - - org.mockito - mockito-core - - - - - - - org.apache.felix - maven-bundle-plugin - true - - - - org.apache.tamaya.format, - org.apache.tamaya.format.formats - - - - - - - http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java b/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java deleted file mode 100644 index 84d6cfa..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java +++ /dev/null @@ -1,154 +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.format; - -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertySourceProvider; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Enumeration; -import java.util.List; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implementation of a {@link PropertySourceProvider} that reads configuration from some given resource paths - * and using the given formats. The resource path are resolved as classpath resources. This can be changed by - * overriding {@link #getPropertySources()}. - * For each resource found the configuration formats passed get a chance to read the resource, if they succeed the - * result is taken as the providers PropertySources to be exposed. - */ -public abstract class BaseFormatPropertySourceProvider implements PropertySourceProvider { - /** - * The logger used. - */ - private static final Logger LOG = Logger.getLogger(BaseFormatPropertySourceProvider.class.getName()); - /** - * The config formats supported for the given location/resource paths. - */ - private final List configFormats = new ArrayList<>(); - /** - * The paths to be evaluated. - */ - private final Collection paths = new ArrayList<>(); - - /** - * Creates a new instance. - * - * @param formats the formats to be used, not null, not empty. - * @param paths the paths to be resolved, not null, not empty. - */ - public BaseFormatPropertySourceProvider( - List formats, - URL... paths) { - this.configFormats.addAll(Objects.requireNonNull(formats)); - this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths))); - } - - /** - * Creates a new instance, hereby using the current thread context classloader, or if not available the classloader - * that loaded this class. - * @param formats the formats to be used, not null, not empty. - * @param paths the paths to be resolved, not null, not empty. - */ - public BaseFormatPropertySourceProvider( - List formats, String... paths) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(cl==null){ - cl = getClass().getClassLoader(); - } - this.configFormats.addAll(Objects.requireNonNull(formats)); - for(String path:paths) { - Enumeration urls; - try { - urls = cl.getResources(path); - } catch (IOException e) { - LOG.log(Level.WARNING, "Failed to read resource: " + path, e); - continue; - } - while(urls.hasMoreElements()) { - this.paths.add(urls.nextElement()); - } - } - } - - /** - * Creates a new instance. - * - * @param classLoader the ClassLoader to be used, not null, not empty. - * @param formats the formats to be used, not null, not empty. - * @param paths the paths to be resolved, not null, not empty. - */ - public BaseFormatPropertySourceProvider( - List formats, - ClassLoader classLoader, String... paths) { - this.configFormats.addAll(Objects.requireNonNull(formats)); - for(String path:paths) { - Enumeration urls; - try { - urls = classLoader.getResources(path); - } catch (IOException e) { - LOG.log(Level.WARNING, "Failed to read resource: " + path, e); - continue; - } - while(urls.hasMoreElements()) { - this.paths.add(urls.nextElement()); - } - } - } - - - /** - * Method to create a {@link org.apache.tamaya.spi.PropertySource} based on the given entries read. - * - * @param data the configuration data, not null. - * @return the {@link org.apache.tamaya.spi.PropertySource} instance ready to be registered. - */ - protected abstract Collection getPropertySources(ConfigurationData data); - - /** - * This method does dynamically resolve the paths using the current ClassLoader set. If no ClassLoader was - * explcitly set during creation the current Thread context ClassLoader is used. If none of the supported - * formats is able to parse a resource a WARNING log is written. - * - * @return the PropertySources successfully read - */ - @Override - public Collection getPropertySources() { - List propertySources = new ArrayList<>(); - for (URL res : this.paths) { - try(InputStream is = res.openStream()) { - for (ConfigurationFormat format : configFormats) { - ConfigurationData data = format.readConfiguration(res.toString(), is); - propertySources.addAll(getPropertySources(data)); - } - } catch (Exception e) { - LOG.log(Level.WARNING, "Failed to put resource based config: " + res, e); - } - } - return propertySources; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java deleted file mode 100644 index b58d2ab..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java +++ /dev/null @@ -1,206 +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.format; - -import java.util.*; - -/** - *

Data that abstracts the data read from a configuration resources using a certain format. The data can be divided - * into different sections, similar to ini-files. Herebey different sections the best map to entries with different - * priorities to be applied, when integrated into PropertySource instances.

- * New instances of this class can be created using a {@link org.apache.tamaya.format.ConfigurationDataBuilder}. - *

Implementation Specification

- * This class is - *
    - *
  • immutable
  • - *
  • thread-safe
  • - *
- */ -public final class ConfigurationData { - /** - * The properties of the default section (no name). - */ - private Map defaultProperties; - /** - * A normalized flattened set of this configuration data. - */ - private Map combinedProperties; - /** - * The sections read. - */ - private Map> namedSections; - /** The format instance used to read this instance. */ - private final ConfigurationFormat format; - /** The resource read. */ - private final String resource; - - - /** - * COnstructor used by builder. - * @param builder the builder instance passing the read configuration data. - */ - ConfigurationData(ConfigurationDataBuilder builder){ - this.format = builder.format; - this.resource = builder.resource; - if (builder.defaultProperties != null) { - this.defaultProperties = new HashMap<>(); - this.defaultProperties.putAll(builder.defaultProperties); - } - if (builder.combinedProperties != null) { - this.combinedProperties = new HashMap<>(); - this.combinedProperties.putAll(builder.combinedProperties); - } - if (builder.namedSections != null) { - this.namedSections = new HashMap<>(); - this.namedSections.putAll(builder.namedSections); - } - if (this.combinedProperties == null || this.combinedProperties.isEmpty()) { - this.combinedProperties = new HashMap<>(); - this.combinedProperties.putAll(getDefaultProperties()); - // popuilate it with sections... - for (String sectionName : getSectionNames()) { - Map section = getSection(sectionName); - for (Map.Entry en : section.entrySet()) { - String key = sectionName + '.' + en.getKey(); - combinedProperties.put(key, en.getValue()); - } - } - } - } - - /** - * Get the {@link org.apache.tamaya.format.ConfigurationFormat} that read this data. - * @return the {@link org.apache.tamaya.format.ConfigurationFormat} that read this data, never null. - */ - public ConfigurationFormat getFormat(){ - return format; - } - - /** - * Get the resource from which this data was read. - * @return the resource from which this data was read, never null. - */ - public String getResource(){ - return resource; - } - - /** - * Access an immutable Set of all present section names, including the default section (if any). - * @return the set of present section names, never null. - */ - public Set getSectionNames() { - if (namedSections == null) { - return Collections.emptySet(); - } - return namedSections.keySet(); - } - - /** - * Get a section's data. - * @param name the section name, not null. - * @return the data of this section, or null, if no such section exists. - */ - public Map getSection(String name) { - return this.namedSections.get(name); - } - - /** - * Convenience accessor for accessing the default section. - * @return the default section's data, or null, if no such section exists. - */ - public Map getDefaultProperties() { - if (defaultProperties == null) { - return Collections.emptyMap(); - } - return defaultProperties; - } - - /** - * Get combined properties for this config data instance. If - * - * @return the normalized properties. - */ - public Map getCombinedProperties() { - if (combinedProperties == null) { - return Collections.emptyMap(); - } - return combinedProperties; - } - - /** - * Accessor used for easily creating a new builder based on a given data instance. - * - * @return the data contained, never null. - */ - public Map> getSections() { - if (namedSections == null) { - return Collections.emptyMap(); - } - return namedSections; - } - - /** - * Immutable accessor to ckeck, if there are default properties present. - * - * @return true, if default properties are present. - */ - public boolean hasDefaultProperties() { - return this.defaultProperties != null && !this.defaultProperties.isEmpty(); - } - - /** - * Immutable accessor to ckeck, if there are combined properties set. - * - * @return true, if combined properties are set. - */ - public boolean hasCombinedProperties() { - return this.combinedProperties != null && !this.combinedProperties.isEmpty(); - } - - /** - * Immutable accessor to ckeck, if there are named sections present. - * - * @return true, if at least one named section is present. - */ - private boolean hasSections() { - return this.namedSections != null && !this.namedSections.isEmpty(); - } - - /** - * Checks if no properties are contained in this data item. - * - * @return true, if no properties are contained in this data item. - */ - public boolean isEmpty() { - return !hasCombinedProperties() && !hasDefaultProperties() && !hasSections(); - } - - @Override - public String toString() { - return "ConfigurationData{" + - "format=" + format + - ", default properties=" + defaultProperties + - ", combined properties=" + combinedProperties + - ", sections=" + namedSections + - ", resource=" + resource + - '}'; - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java deleted file mode 100644 index da5fa35..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java +++ /dev/null @@ -1,219 +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.format; - -import java.util.*; - - -/** - * Builder for creating {@link org.apache.tamaya.format.ConfigurationData} instances. This class is not thread-safe. - */ -public final class ConfigurationDataBuilder { - - /** The format instance used to read this instance. */ - final ConfigurationFormat format; - /** The resource read. */ - final String resource; - /** - * The properties of the default section (no name). - */ - Map defaultProperties; - /** - * A normalized flattened set of this configuration data. - */ - Map combinedProperties; - /** - * The sections read. - */ - Map> namedSections; - - /** - * Private constructor. - * @param resource the configuration resource URL, not null. - * @param format the format that read this data, not null. - */ - private ConfigurationDataBuilder(String resource, ConfigurationFormat format){ - this.format = Objects.requireNonNull(format); - this.resource = Objects.requireNonNull(resource); - } - - /** - * Creates a new instance. - * @param resource the configuration resource URL, not null. - * @param format the format that read this data, not null. - * @return new instance of this class. - */ - public static ConfigurationDataBuilder of(String resource, ConfigurationFormat format){ - return new ConfigurationDataBuilder(resource, format); - } - - /** - * Creates a new instance. - * @param data an existing ConfigurationData instances used to initialize the builder. - * @return new instance of this class from the given configuration. - */ - public static ConfigurationDataBuilder of(ConfigurationData data){ - ConfigurationDataBuilder b = new ConfigurationDataBuilder(data.getResource(), data.getFormat()); - if (data.hasDefaultProperties()) { - b.getDefaultProperties().putAll(data.getDefaultProperties()); - } - if (data.hasCombinedProperties()) { - b.getCombinedProperties().putAll(data.getCombinedProperties()); - } - if (!data.getSections().isEmpty()) { - b.getSections().putAll(data.getSections()); - } - return b; - } - - /** - * Adds (empty) sections,if they are not yet existing. Already existing sections will not be touched. - * @param sections the new sections to put. - * @return the builder for chaining. - */ - public ConfigurationDataBuilder addSections(String... sections){ - for (String section : sections) { - if (!getSections().containsKey(section)) { - getSections().put(section, new HashMap()); - } - } - return this; - } - - /** - * Adds a single entry to a target section. - * @param section the target section (will be created if not existing). - * @param key the entry's key - * @param value the entry's value - * @return the builder for chaining. - */ - public ConfigurationDataBuilder addSectionProperty(String section, String key, String value) { - Map map = getSections().get(section); - if (map == null) { - map = new HashMap<>(); - getSections().put(section, map); - } - map.put(key, value); - return this; - } - - /** - * Adds a single entry to the default section. - * @param key the entry's key - * @param value the entry's value - * @return the builder for chaining. - */ - public ConfigurationDataBuilder addProperty(String key, String value) { - getDefaultProperties().put(key, value); - return this; - } - - /** - * Adds the given entries to the given section, all existing values will be overridden. - * @param section the target section (will be created if not existing). - * @param properties the entry's data - * @return the builder for chaining. - */ - public ConfigurationDataBuilder addSectionProperties(String section, Map properties) { - Map map = getSections().get(section); - if (map == null) { - map = new HashMap<>(); - getSections().put(section, map); - } - map.putAll(properties); - return this; - } - - /** - * Adds the given entries to the default section, all existing values will be overridden. - * @param properties the entry's data - * @return the builder for chaining. - */ - public ConfigurationDataBuilder addProperties(Map properties) { - getDefaultProperties().putAll(properties); - return this; - } - - /** - * Sets the given entries as the combined properties map, all existing properties of the - * combined map will be overridden. - * - * @param properties the entry's data - * @return the builder for chaining. - */ - public ConfigurationDataBuilder setCombinedProperties(Map properties) { - this.combinedProperties = new HashMap<>(properties); - return this; - } - - /** - * Access the current default section, if not present a new instance is initialized. - * - * @return the current default section, never null. - */ - public Map getDefaultProperties() { - if (defaultProperties == null) { - defaultProperties = new HashMap<>(); - } - return defaultProperties; - } - - /** - * Access the current combined properties, if not present a new instance is initialized. - * - * @return the current combined properties, never null. - */ - public Map getCombinedProperties() { - if (combinedProperties == null) { - combinedProperties = new HashMap<>(); - } - return combinedProperties; - } - - /** - * Access the current named sections, if not present a new instance is initialized. - * - * @return the current named sections, never null. - */ - public Map> getSections() { - if (namedSections == null) { - namedSections = new HashMap<>(); - } - return namedSections; - } - - /** - * Builds a new {@link org.apache.tamaya.format.ConfigurationData} instance. - * @return a new {@link org.apache.tamaya.format.ConfigurationData} instance, not null. - */ - public ConfigurationData build(){ - return new ConfigurationData(this); - } - - @Override - public String toString() { - return "ConfigurationDataBuilder{" + - "format=" + format + - ", default properties=" + defaultProperties + - ", sections=" + namedSections + - ", combined properties=" + combinedProperties + - ", resource=" + resource + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java deleted file mode 100644 index 997ef3a..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java +++ /dev/null @@ -1,103 +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.format; - -import java.io.InputStream; -import java.net.URL; - -/** - *

Implementations current this class encapsulate the mechanism how to read a - * resource including interpreting the format correctly (e.g. xml vs. - * properties vs. ini). In most cases file only contains entries of the same priority, which would then - * result in only one {@link org.apache.tamaya.spi.PropertySource}. Complex file formats, however, may contain entries - * of different priorities. In this cases, each ordinal type found typically is returned as a separate section so the - * consuming {@link org.apache.tamaya.spi.PropertySourceProvider} implementation can distribute the different part to - * individual {@link org.apache.tamaya.spi.PropertySource}s.

- * - *

Implementation Requirements

- * Implementations of this type must be - *
    - *
  • thread-safe
  • - *
- */ -public interface ConfigurationFormat { - - /** - * Get a unique name of the format. This name can be used to access the format. - * @return the (unique) format's name, never null and not empty. - */ - String getName(); - - /** - * Allows the format to examine the given resource, e.g. for a matching file ending. Only, if a format accepts an - * URL, it will be tried for reading the configuration. - * @param url the url to read the configuration data from (could be a file, a server location, a classpath - * resource or something else, not null. - * @return true, if this format accepts the given URL for reading. - */ - boolean accepts(URL url); - - /** - * Reads a configuration from an URL, hereby parsing the given {@link java.io.InputStream}. Dependening on - * the capabilities of the format the returned {@link org.apache.tamaya.format.ConfigurationData} may contain - * different levels of data: - *
    - *
  • Only a default section is returned, since the configuration format does not support - * hierarchies. This is the case for properties and xml properties.
  • - *
  • Hierarchical formats such as INI, XML and JSON can map each node to a section. Each section - * can have its own key/value pairs. This allows to map also complex formats in a generic way. A - * format implementation should then additionally flatten the whole data and store it in a accessible as - * {@link ConfigurationData#getCombinedProperties()}. This allows to use the properties as inout to a default mapping, - * which is always appropriate as long as no other semnatics - * are defined in the concrete target scenario.
  • - *
  • More complex custom scenarios should map their configuration data read into different - * sections. Typically the data will be mapped into different {@link org.apache.tamaya.spi.PropertySource} - * instances with different ordinal levels. As an example imagine a custom format that contains sections - * 'defaults', 'global-defaults', 'application', 'server-overrides'.
  • - *
  • Alternate formats
  • - *
- * - * Summarizing implementations common formats should always provide - *
    - *
  • the data organized in sections as useful for the given format. If data is organized in one section, it - * should be mapped into the DEFAULT section.
  • - *
  • Formats that do provide multiple sections, should always provide a FLATTENED section as well, where - * all the data is organized as a flattened key/value pairs, enabling a generic mapping to a - * {@link org.apache.tamaya.spi.PropertySource}.
  • - *
- * - * If the configuration format only contains entries of one ordinal type, normally only one single - * instance of PropertySource is returned (the corresponding key/values should end up in the DEFAULT section). - * Nevertheless custom formats may contain different sections or parts, - * where each part maps to a different target ordinal (eg defaults, domain config and app config). In the - * ladder case multiple PropertySources can be returned, each one with its own ordinal and the corresponding - * entries. - * @see org.apache.tamaya.spi.PropertySource - * @param resource a descriptive name for the resource, since an InputStream does not have any) - * @param inputStream the inputStream to read the configuration data from (could be a file, a server location, a classpath - * resource or something else. - * @return the corresponding {@link ConfigurationData} containing sections/properties read, never {@code null}. - * @throws org.apache.tamaya.ConfigException if parsing of the input fails. - */ - ConfigurationData readConfiguration(String resource, InputStream inputStream); - - //X TODO Add support to access a default format to see a correct formatting - //X String getFormatExample(); - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java deleted file mode 100644 index bc8aabd..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java +++ /dev/null @@ -1,187 +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.format; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.tamaya.spi.ServiceContextManager; - -/** - * Small accessor and management class dealing with {@link org.apache.tamaya.format.ConfigurationFormat} - * instances. - */ -public final class ConfigurationFormats { - /** - * The logger used. - */ - private static final Logger LOG = Logger.getLogger(ConfigurationFormats.class.getName()); - - /** - * Singleton constructor. - */ - private ConfigurationFormats() { - } - - /** - * Get all currently available formats, ordered by priority. - * - * @return the currently available formats, never null. - */ - public static List getFormats() { - return ServiceContextManager.getServiceContext().getServices(ConfigurationFormat.class); - } - - /** - * Get all currently available formats, ordered by priority. - * - * @param formatNames available formats to be ordered. - * @return the currently available formats, never null. - */ - public static List getFormats(String... formatNames) { - final List result = new ArrayList<>(); - final Set names = new HashSet<>(Arrays.asList(formatNames)); - for (final ConfigurationFormat f : getFormats()) { - if (names.contains(f.getName())) { - result.add(f); - } - } - return result; - } - - // Activate for JDK 8... -// /** -// * Get all currently available formats, ordered by priority. -// * -// * @return the currently available formats, never null. -// */ -// public static List getFormats(Predicate namePredicate) { -// List result = new ArrayList<>(); -// for(ConfigurationFormat f:getFormats()){ -// if(namePredicate.test(f.getName()){ -// result.add(f); -// } -// } -// return result; -// } - - /** - * Get all currently available formats, ordered by priority. - * - * @param url source to read configuration from. - * @return the currently available formats, never null. - */ - public static List getFormats(final URL url) { - final List formats = getFormats(); - final List result = new ArrayList<>(); - for (final ConfigurationFormat f : formats) { - if (f.accepts(url)) { - result.add(f); - } - } - return result; - } - - /** - * Tries to read configuration data from a given URL, hereby traversing all known formats in order of precedence. - * Hereby the formats are first filtered to check if the URL is acceptable, before the input is being parsed. - * - * @param url the url from where to read, not null. - * @return the ConfigurationData read, or null. - * @throws IOException if the resource cannot be read. - */ - public static ConfigurationData readConfigurationData(final URL url) throws IOException { - final List formats = getFormats(url); - return readConfigurationData(url, formats.toArray(new ConfigurationFormat[formats.size()])); - } - - /** - * Tries to read configuration data from a given URL, hereby explicitly trying all given formats in order. - * - * @param url the url from where to read, not null. - * @param formats the formats to try. - * @return the ConfigurationData read, or null. - * @throws IOException if the resource cannot be read. - */ - public static ConfigurationData readConfigurationData(URL url, ConfigurationFormat... formats) throws IOException { - return readConfigurationData(url.toString(), url.openStream(), formats); - } - - /** - * @param urls the urls from where to read, not null. - * @param formats the formats to try. - * @return the {@link org.apache.tamaya.format.ConfigurationData} of the files successfully decoded by the - * given formats. - */ - public static Collection getPropertySources(Collection urls, ConfigurationFormat... formats) { - final List dataRead = new ArrayList<>(); - for (final URL url : urls) { - try { - final ConfigurationData data = readConfigurationData(url, formats); - if (data != null) { - dataRead.add(data); - } - } catch (final Exception e) { - LOG.log(Level.SEVERE, "Error reading file: " + url.toExternalForm(), e); - } - } - return dataRead; - } - - /** - * Tries to read configuration data from a given URL, hereby explicitly trying all given formats in order. - * - * @param resource a descriptive name for the resource, since an InputStream does not have any - * @param inputStream the inputStream from where to read, not null. - * @param formats the formats to try. - * @return the ConfigurationData read, or null. - * @throws IOException if the resource cannot be read. - */ - public static ConfigurationData readConfigurationData(String resource, InputStream inputStream, - ConfigurationFormat... formats) throws IOException { - Objects.requireNonNull(inputStream); - Objects.requireNonNull(resource); - try(InputStreamFactory isFactory = new InputStreamFactory(inputStream)) { - for (final ConfigurationFormat format : formats) { - try (InputStream is = isFactory.createInputStream()) { - final ConfigurationData data = format.readConfiguration(resource, is); - if (data != null) { - return data; - } - } catch (final Exception e) { - LOG.log(Level.INFO, - "Format " + format.getClass().getName() + " failed to read resource " + resource, e); - } - } - } - return null; - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java b/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java deleted file mode 100644 index 9d2097f..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java +++ /dev/null @@ -1,118 +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.format; - -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Flattened default PropertySource that uses the flattened config data read from an URL by a - * ${@link org.apache.tamaya.format.ConfigurationFormat}. - */ -public class FlattenedDefaultPropertySource implements PropertySource { - private static final Logger LOG = Logger.getLogger(FlattenedDefaultPropertySource.class.getName()); - private final Map properties; - private final ConfigurationData data; - private int defaultOrdinal = 0; - - - /* - * Constructor, uses hereby the flattened config data read from an URL by a - * ${@link org.apache.tamaya.format.ConfigurationFormat}, and if not present falls back to the default section. - */ - public FlattenedDefaultPropertySource(ConfigurationData data) { - this.properties = populateData(data); - this.data = data; - } - - /* - * Constructor, uses hereby the flattened config data read from an URL by a - * ${@link org.apache.tamaya.format.ConfigurationFormat}, and if not present falls back to the default section. - */ - public FlattenedDefaultPropertySource(int defaultOrdinal, ConfigurationData data) { - this.properties = populateData(data); - this.data = data; - this.defaultOrdinal = defaultOrdinal; - } - - protected Map populateData(ConfigurationData data) { - Map result = data.getCombinedProperties(); - if (result.isEmpty()) { - result = data.getDefaultProperties(); - } - if (result.isEmpty()) { - result = new HashMap<>(); - } - if(result.isEmpty()){ - for (String section : data.getSectionNames()) { - Map sectionMap = data.getSection(section); - for(Map.Entry en: sectionMap.entrySet()){ - result.put(section + '.' + en.getKey(), en.getValue()); - } - } - } - return Collections.unmodifiableMap(result); - } - - @Override - public String getName() { - String name = this.properties.get("[meta].name"); - if (name == null) { - name = this.data.getResource(); - } - if (name == null) { - name = getClass().getSimpleName(); - } - return name; - } - - @Override - public int getOrdinal() { - String ordinalValue = this.properties.get(PropertySource.TAMAYA_ORDINAL); - if (ordinalValue != null) { - try { - return Integer.parseInt(ordinalValue.trim()); - } catch (Exception e) { - LOG.log(Level.WARNING, "Failed to parse Tamaya ordinal from " + data.getResource(), e); - } - } - return defaultOrdinal; - } - - @Override - public PropertyValue get(String key) { - return PropertyValue.of(key, properties.get(key), getName()); - } - - @Override - public Map getProperties() { - return properties; - } - - @Override - public boolean isScannable() { - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java b/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java deleted file mode 100644 index 912dd08..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java +++ /dev/null @@ -1,89 +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.format; - -import java.io.*; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Wrapper for a given {@link InputStream} to be able to close - * it via the try-with-resources construct of Java 7. - * - *

Usage example

- * - *
- * public void readIt(InputStream inputStream) {
- *    try (InputStream is = new ParallelInputStream(inputStream) {
- *        // Consume the stream
- *    }
- * }
- * 
- */ -public class InputStreamFactory implements Closeable { - private static final Logger LOG = Logger.getLogger(InputStreamFactory.class.getName()); - - private byte[] data; - - /** - * Creates a new InputStreamFactory. - * - * @param original the InputStream to be read for extract its data into memory. - * @throws IOException if thrown by the original during read. - */ - public InputStreamFactory(InputStream original) throws IOException { - Objects.requireNonNull(original); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - byte[] bytes = new byte[256]; - try { - int read = original.read(bytes); - while (read > 0) { - bos.write(bytes, 0, read); - read = original.read(bytes); - } - this.data = bos.toByteArray(); - } finally { - try { - original.close(); - } catch (IOException e) { - LOG.log(Level.FINEST, "Error closing stream: " + original, e); - } - } - } - - /** - * Creates a new InputStream with the same data as provided by the InputStream passed on factory creation. - * - * @return a new InputStream , never null. - * @throws IOException if no data is available. - */ - public InputStream createInputStream() throws IOException { - byte[] bytes = this.data; - if (bytes == null) { - throw new IOException("InputStreamFactory is closed."); - } - return new ByteArrayInputStream(bytes); - } - - @Override - public void close() throws IOException { - this.data = null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java deleted file mode 100644 index fe27ba7..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java +++ /dev/null @@ -1,95 +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.format.formats; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.format.ConfigurationData; -import org.apache.tamaya.format.ConfigurationDataBuilder; -import org.apache.tamaya.format.ConfigurationFormat; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implements a ini file format. - */ -public class IniConfigurationFormat implements ConfigurationFormat { - - /** - * The logger. - */ - private final static Logger LOG = Logger.getLogger(IniConfigurationFormat.class.getName()); - - @Override - public String getName() { - return "ini"; - } - - @Override - public boolean accepts(URL url) { - String fileName = url.getFile(); - return fileName.endsWith(".ini") || fileName.endsWith(".INI"); - } - - @Override - public ConfigurationData readConfiguration(String resource, InputStream inputStream) { - ConfigurationDataBuilder builder = ConfigurationDataBuilder.of(resource, this); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) { - String line = reader.readLine(); - int lineNum = 0; - String section = null; - while (line != null) { - lineNum++; - line = line.trim(); - if (line.isEmpty()) { - line = reader.readLine(); - continue; - } - if (line.startsWith("[")) { - int end = line.indexOf(']'); - if (end < 0) { - throw new ConfigException( - "Invalid INI-Format, ']' expected, at " + lineNum + " in " + resource); - } - section = line.substring(1, end); - } else if (line.trim().startsWith("#")) { - // comment - } else { - int sep = line.indexOf('='); - String key = line.substring(0, sep); - String value = line.substring(sep + 1); - if (section != null) { - builder.addSectionProperty(section, key, value); - } else { - builder.addProperty(key, value); - } - } - line = reader.readLine(); - } - return builder.build(); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Could not read configuration: " + resource, e); - } - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java deleted file mode 100644 index 35cef77..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java +++ /dev/null @@ -1,71 +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.format.formats; - -import org.apache.tamaya.format.ConfigurationData; -import org.apache.tamaya.format.ConfigurationDataBuilder; -import org.apache.tamaya.format.ConfigurationFormat; - -import java.io.InputStream; -import java.net.URL; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implementation of a {@link org.apache.tamaya.format.ConfigurationFormat} for -properties files. - * - * @see java.util.Properties#load(java.io.InputStream) - */ -public class PropertiesFormat implements ConfigurationFormat { - /** - * The logger. - */ - private final static Logger LOG = Logger.getLogger(PropertiesFormat.class.getName()); - - - @Override - public String getName() { - return "properties"; - } - - @Override - public boolean accepts(URL url) { - String fileName = url.getFile(); - return fileName.endsWith(".properties") || fileName.endsWith(".PROPERTIES") || - fileName.endsWith(".conf") || fileName.endsWith(".CONF"); - } - - @SuppressWarnings("unchecked") - @Override - public ConfigurationData readConfiguration(String resource, InputStream inputStream) { - Objects.requireNonNull(inputStream); - Objects.requireNonNull(resource); - try { - final Properties p = new Properties(); - p.load(inputStream); - return ConfigurationDataBuilder.of(resource, this).addProperties(Map.class.cast(p)).build(); - } catch (Exception e) { - LOG.log(Level.FINEST, "Failed to read config from resource: " + resource, e); - } - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java deleted file mode 100644 index c47b6f6..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java +++ /dev/null @@ -1,69 +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.format.formats; - -import org.apache.tamaya.format.ConfigurationData; -import org.apache.tamaya.format.ConfigurationDataBuilder; -import org.apache.tamaya.format.ConfigurationFormat; - -import java.io.InputStream; -import java.net.URL; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implementation of a {@link org.apache.tamaya.format.ConfigurationFormat} for xml property - * files. - * - * @see java.util.Properties#loadFromXML(java.io.InputStream) - */ -public class PropertiesXmlFormat implements ConfigurationFormat { - /** - * The logger. - */ - private final static Logger LOG = Logger.getLogger(PropertiesXmlFormat.class.getName()); - - @Override - public String getName() { - return "xml-properties"; - } - - @Override - public boolean accepts(URL url) { - String fileName = url.getFile(); - return fileName.endsWith(".xml") || fileName.endsWith(".XML"); - } - - @SuppressWarnings("unchecked") - @Override - public ConfigurationData readConfiguration(String resource, InputStream inputStream) { - Objects.requireNonNull(inputStream); - Objects.requireNonNull(resource); - - try { - final Properties p = new Properties(); - p.loadFromXML(inputStream); - return ConfigurationDataBuilder.of(resource, this).addProperties(Map.class.cast(p)).build(); - } catch (Exception e) { - LOG.log(Level.FINEST, "Failed to read config from resource: " + resource, e); - } - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java deleted file mode 100644 index db8987d..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java +++ /dev/null @@ -1,23 +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. - */ -/** - * This package provides implementtion of {@link org.apache.tamaya.format.ConfigurationFormat} - * for properties, xml-properties and ini files. - */ -package org.apache.tamaya.format.formats; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java b/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java deleted file mode 100644 index 39b5f0b..0000000 --- a/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java +++ /dev/null @@ -1,28 +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. - */ -/** - * This package provides an abstraction for parsing a configuration - * from an input strem, called {@link org.apache.tamaya.format.ConfigurationFormat} - * and corresponding helper artifacts. - * - * @see org.apache.tamaya.format.ConfigurationFormat - * @see org.apache.tamaya.format.ConfigurationData - * @see org.apache.tamaya.format.ConfigurationFormats - */ -package org.apache.tamaya.format; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat ---------------------------------------------------------------------- diff --git a/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat deleted file mode 100644 index 96e898f..0000000 --- a/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat +++ /dev/null @@ -1,21 +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 current the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -org.apache.tamaya.format.formats.IniConfigurationFormat -org.apache.tamaya.format.formats.PropertiesFormat -org.apache.tamaya.format.formats.PropertiesXmlFormat \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/359d3e4a/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java ---------------------------------------------------------------------- diff --git a/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java b/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java deleted file mode 100644 index 0839714..0000000 --- a/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java +++ /dev/null @@ -1,68 +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.format; - -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * Tests for {@link org.apache.tamaya.format.ConfigurationFormats}. - */ -public class ConfigurationFormatsTest { - - @org.junit.Test - public void testGetFormats() throws Exception { - List formats = ConfigurationFormats.getFormats(); - assertNotNull(formats); - assertEquals(formats.size(), 3); - } - - @org.junit.Test - public void testReadConfigurationData() throws Exception { - List formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.ini")); - assertNotNull(formats); - assertEquals(formats.size(), 1); - formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.properties")); - assertNotNull(formats); - assertEquals(formats.size(), 1); -// formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.xml")); -// assertNotNull(formats); -// assertEquals(formats.size(), 1); - - } - - @org.junit.Test - public void testReadConfigurationData_URL() throws Exception { - ConfigurationData data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.ini")); - assertNotNull(data); - data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.properties")); - assertNotNull(data); - } - - @org.junit.Test - public void testReadConfigurationData2() throws Exception { - List formats = ConfigurationFormats.getFormats(); - ConfigurationData data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.ini"), - formats.toArray(new ConfigurationFormat[formats.size()])); - assertNotNull(data); - System.out.println(data); - } -} \ No newline at end of file