http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java ---------------------------------------------------------------------- diff --git a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java b/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java deleted file mode 100644 index 23e73c0..0000000 --- a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java +++ /dev/null @@ -1,306 +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.clsupport; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.ref.WeakReference; -import java.net.URL; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.ServiceConfigurationError; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Classloader managed ServiceContainer. - */ -class ServiceContainer { - - private static final Logger LOG = Logger.getLogger(ServiceContainer.class.getName()); - - private static final String PREFIX = "META-INF/services/"; - - // The access control context taken when the ServiceLoader is created - private final AccessControlContext acc; - - private final WeakReference<ClassLoader> classLoaderRef; - - /** - * List current services loaded using this classloader, per class. - */ - private final Map<Class<?>, Map<String, Object>> servicesLoaded = new ConcurrentHashMap<>(); - /** - * The cached singletons for the given classloader. - */ - private final Map<Class, Object> singletons = new ConcurrentHashMap<>(); - - /** - * List current services loaded using this classloader, per class. - */ - private final Map<Class, List<URL>> configsLoaded = new ConcurrentHashMap<>(); - - ServiceContainer(ClassLoader classLoader) { - acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null; - this.classLoaderRef = new WeakReference<>(classLoader); - } - - public ClassLoader getClassLoader() { - ClassLoader cl = classLoaderRef.get(); - if (cl == null) { - throw new IllegalStateException("Classloader reference removed, not active anynire."); - } - return cl; - } - - - public <T> void loadServices(Class<?> type, - Collection<ServiceContainer> preceedingContainers) { - Map<String, Object> services = this.servicesLoaded.get(type); - if (services == null) { - services = new LinkedHashMap<>(); - this.servicesLoaded.put(type, services); - } - loop: - for (URL config : getConfigs(type)) { - for (ServiceContainer cont : preceedingContainers) { - if (cont.getConfigs(type).contains(config)) { - LOG.finer("Ignoring already loaded config: " + config); - continue loop; - } - } - Collection<String> serviceNames = parse(type, config); - for (String s : serviceNames) { - for (ServiceContainer cont : preceedingContainers) { - if (cont.containsService(type, s)) { - LOG.finest("Ignoring duplicate service: " + s); - } - } - LOG.info("Loading component: " + s); - services.put(s, create(type, s)); - } - } - } - - private Collection<URL> getConfigs(Class<?> type) { - List<URL> result = this.configsLoaded.get(type); - if (result == null) { - ClassLoader cl = this.classLoaderRef.get(); - if (cl == null) { - throw new IllegalStateException("CLassLoader dereferenced already."); - } - result = new ArrayList<>(); - try { - Enumeration<URL> resources = cl.getResources(PREFIX + type.getName()); - while (resources.hasMoreElements()) { - result.add(resources.nextElement()); - } - } catch (Exception e) { - LOG.log(Level.WARNING, "Failed to read service config for " + type.getName() + " from " + cl, e); - } - this.configsLoaded.put(type, result); - LOG.log(Level.FINE, "Found service config for " + type.getName() + ": " + result); - } - return result; - } - - private boolean containsService(Class<?> type, String serviceClassName) { - Map<String, Object> services = servicesLoaded.get(type); - return services != null && services.containsKey(serviceClassName); - } - - - private <S> S create(Class<S> serviceType, String className) { - Class<?> c = null; - ClassLoader classLoader = getClassLoader(); - try { - c = Class.forName(className, false, classLoader); - } catch (ClassNotFoundException x) { - fail(serviceType, - "Provider " + className + " not found"); - } - if (!serviceType.isAssignableFrom(c)) { - fail(serviceType, - "Provider " + className + " not a subtype"); - } - try { - return serviceType.cast(c.newInstance()); - } catch (Throwable x) { - fail(serviceType, - "Provider " + className + " could not be instantiated", - x); - } - throw new Error(); // This cannot happen - } - - public <T> Collection<T> getServices(Class<T> serviceType) { - Map<String, Object> services = this.servicesLoaded.get(serviceType); - if (services != null) { - return (Collection<T>) services.values(); - } - return Collections.emptySet(); - } - - public boolean isTypeLoaded(Class<?> serviceType) { - return this.servicesLoaded.containsKey(serviceType); - } - - public Collection<URL> load(Class<?> serviceType) { - return load(serviceType, Collection.class.cast(Collections.emptySet())); - } - - public Collection<URL> load(Class<?> serviceType, Collection<URL> configsLoaded) { - List<URL> result = new ArrayList<>(); - try { - Enumeration<URL> resources = getClassLoader().getResources(PREFIX + serviceType.getName()); - while (resources.hasMoreElements()) { - URL res = resources.nextElement(); - if (!configsLoaded.contains(res)) { - result.add(res); - } - } - return result; - } catch (Exception e) { - fail(serviceType, "Failed to load service config: " + PREFIX + serviceType.getName(), e); - } - return result; - } - - - // Parse a single line from the given configuration file, adding the name - // on the line to the names list. - // - private int parseLine(Class<?> serviceType, URL u, BufferedReader r, int lc, - List<String> names) - throws IOException, ServiceConfigurationError { - String ln = r.readLine(); - if (ln == null) { - return -1; - } - int ci = ln.indexOf('#'); - if (ci >= 0) { - ln = ln.substring(0, ci); - } - ln = ln.trim(); - int n = ln.length(); - if (n != 0) { - if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) { - fail(serviceType, u, lc, "Illegal configuration-file syntax"); - } - int cp = ln.codePointAt(0); - if (!Character.isJavaIdentifierStart(cp)) { - fail(serviceType, u, lc, "Illegal provider-class name: " + ln); - } - for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) { - cp = ln.codePointAt(i); - if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) { - fail(serviceType, u, lc, "Illegal provider-class name: " + ln); - } - } - Map<String, Object> services = this.servicesLoaded.get(serviceType); - if (services == null || !services.containsKey(ln) && !names.contains(ln)) { - names.add(ln); - } - } - return lc + 1; - } - - - // Parse the content of the given URL as a provider-configuration file. - // - // @param service - // The service type for which providers are being sought; - // used to construct error detail strings - // - // @param u - // The URL naming the configuration file to be parsed - // - // @return A (possibly empty) iterator that will yield the provider-class - // names in the given configuration file that are not yet members - // of the returned set - // - // @throws ServiceConfigurationError - // If an I/O error occurs while reading from the given URL, or - // if a configuration-file format error is detected - // - private Collection<String> parse(Class<?> service, URL u) - throws ServiceConfigurationError { - InputStream in = null; - BufferedReader r = null; - ArrayList<String> names = new ArrayList<>(); - try { - in = u.openStream(); - r = new BufferedReader(new InputStreamReader(in, "utf-8")); - int lc = 1; - while ((lc = parseLine(service, u, r, lc, names)) >= 0) { - // go ahead - } - } catch (IOException x) { - fail(service, "Error reading configuration file", x); - } finally { - try { - if (r != null) { - r.close(); - } - if (in != null) { - in.close(); - } - } catch (IOException y) { - fail(service, "Error closing configuration file", y); - } - } - return names; - } - - - private static void fail(Class<?> service, String msg, Throwable cause) - throws ServiceConfigurationError { - LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg, cause); - } - - private static void fail(Class<?> service, String msg) - throws ServiceConfigurationError { - LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg); - } - - private static void fail(Class<?> service, URL u, int line, String msg) - throws ServiceConfigurationError { - fail(service, u + ":" + line + ": " + msg); - } - - public <T> T getSingleton(Class<T> serviceType) { - return (T) this.singletons.get(serviceType); - } - - <T> void setSingleton(Class<T> type, T instance) { - LOG.info("Caching singleton for " + type.getName() + " and classloader: " + - getClassLoader().toString() + ": " + instance); - this.singletons.put(type, instance); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java ---------------------------------------------------------------------- diff --git a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java b/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java deleted file mode 100644 index d8e3953..0000000 --- a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java +++ /dev/null @@ -1,22 +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. - */ -/** - * Programmatic API of the classloader support. - */ -package org.apache.tamaya.clsupport; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext ---------------------------------------------------------------------- diff --git a/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext deleted file mode 100644 index 7016afb..0000000 --- a/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext +++ /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.clsupport.CLAwareServiceContext http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi ---------------------------------------------------------------------- diff --git a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi b/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi deleted file mode 100644 index 7f71c15..0000000 --- a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi +++ /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 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.environment.internal.ClassLoaderDependentAppEnvironmentProvider -org.apache.tamaya.environment.internal.ClassLoaderDependentEarEnvironmentProvider -org.apache.tamaya.environment.internal.InitialEnvironmentProviderSpi -org.apache.tamaya.environment.internal.SystemClassLoaderEnvironmentProviderSpi -org.apache.tamaya.metamodel.environment.TestEnvironmentProvider \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi ---------------------------------------------------------------------- diff --git a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi b/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi deleted file mode 100644 index 166dd67..0000000 --- a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi +++ /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.environment.internal.SingleEnvironmentManager http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/ui/base/pom.xml ---------------------------------------------------------------------- diff --git a/ui/base/pom.xml b/ui/base/pom.xml index 588e8b9..075ebb5 100644 --- a/ui/base/pom.xml +++ b/ui/base/pom.xml @@ -23,7 +23,7 @@ under the License. <parent> <groupId>org.apache.tamaya.ext</groupId> - <artifactId>tamaya-ui</artifactId> + <artifactId>tamaya-ui-parent</artifactId> <version>0.3-incubating-SNAPSHOT</version> <relativePath>..</relativePath> </parent> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/ui/mutableconfig/pom.xml ---------------------------------------------------------------------- diff --git a/ui/mutableconfig/pom.xml b/ui/mutableconfig/pom.xml index 8a94150..e05359f 100644 --- a/ui/mutableconfig/pom.xml +++ b/ui/mutableconfig/pom.xml @@ -23,7 +23,7 @@ under the License. <parent> <groupId>org.apache.tamaya.ext</groupId> - <artifactId>tamaya-ui</artifactId> + <artifactId>tamaya-ui-parent</artifactId> <version>0.3-incubating-SNAPSHOT</version> <relativePath>..</relativePath> </parent> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/pom.xml ---------------------------------------------------------------------- diff --git a/usagetracker/pom.xml b/usagetracker/pom.xml new file mode 100644 index 0000000..371990c --- /dev/null +++ b/usagetracker/pom.xml @@ -0,0 +1,113 @@ +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy current the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-sandbox</artifactId> + <version>0.3-incubating-SNAPSHOT</version> + <relativePath>..</relativePath> + </parent> + + <artifactId>tamaya-usagetracker</artifactId> + <name>Apache Tamaya Modules - Usage tracker</name> + <description>This extension module provides functionality to measure configuration + usage during runtime. + </description> + <packaging>bundle</packaging> + + <properties> + <jdkVersion>1.7</jdkVersion> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-injection-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-events</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-json</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.johnzon</groupId> + <artifactId>johnzon-core</artifactId> + <version>0.9-incubating</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-json_1.0_spec</artifactId> + <version>1.0-alpha-1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>java-hamcrest</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package> + org.apache.tamaya.model, + org.apache.tamaya.model.spi + </Export-Package> + <Private-Package> + org.apache.tamaya.model.internal + </Private-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java new file mode 100644 index 0000000..3d10e80 --- /dev/null +++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java @@ -0,0 +1,129 @@ +/* + * 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.usagetracker; + +import org.apache.tamaya.spi.ServiceContextManager; +import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi; + +import java.util.Collection; +import java.util.Objects; +import java.util.Set; +import java.util.logging.Logger; + +/** + * Validator accessor to validate the current configuration. + */ +public final class ConfigUsage { + + /** The logger used. */ + private static final Logger LOG = Logger.getLogger(ConfigUsage.class.getName()); + private static final String NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE = "No UsageTrackerSpi component available."; + + /** The loaded usage tracking SPI. */ + private static ConfigUsageSpi usageTracker = ServiceContextManager + .getServiceContext().getService(ConfigUsageSpi.class); + + /** + * Singleton constructor. + */ + private ConfigUsage() { + } + + /** + * Returns a set of package names that are to be ignored when collecting usage data. + * @return the ignored package names, not null. + */ + public static Set<String> getIgnoredUsagePackages(){ + return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .getIgnoredPackages(); + } + + /** + * Adds the given packageNames to the list of packages to be ignored when collecting usage data. + * @param packageName the package names to be added, not null. + */ + public static void addIgnoredUsagePackages(String... packageName){ + Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .addIgnoredUsagePackages(packageName); + } + + /** + * Enables/disables usage tracking. + * @param enabled set to true to enable usage tracking. + */ + public static void enableUsageTracking(boolean enabled){ + Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .enableUsageTracking(enabled); + } + + /** + * Access the usage statistics for a given key. If usage stats collection is not + * activated (default), this method returns null. + * @param key the fully qualified configuration key, not null. + * @return the stats collected, or null. + */ + public static UsageStat getUsage(String key){ + return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .getUsage(key); + } + + /** + * Get the recorded usage references of configuration. + * @return the recorded usge references, never null. + */ + public static Collection<UsageStat> getUsages() { + return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE).getUsages(); + } + + /** + * Clears all collected usage statistics. + */ + public static void clearUsageStats() { + Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .clearUsageStats(); + } + + /** + * Access the usage statistics for accessing {@link org.apache.tamaya.Configuration#getProperties()}. + * If usage stats collection is not activated (default), this method returns null. + * @return the stats collected, or null. + */ + public static UsageStat getUsageAllProperties(){ + return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .getUsageAllProperties(); + } + + /** + * Allows to check if usage tracking is enabled (should be disbled by default). + * @return true, if usage tracking is enabled. + */ + public static boolean isUsageTrackingEnabled(){ + return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE) + .isUsageTrackingEnabled(); + } + + /** + * Access the usage statistics for the recorded uses of configuration. + * @return usage info or default message. + */ + public static String getUsageInfo(){ + return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE).getUsageInfo(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java new file mode 100644 index 0000000..6161644 --- /dev/null +++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java @@ -0,0 +1,312 @@ +/* + * 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.usagetracker; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Logger; + +/** + * Metrics container containing access statistics for a given configuration key. + */ +public final class UsageStat { + private static final Logger LOG = Logger.getLogger(UsageStat.class.getName()); + private static final String[] EMPTY_TRACE = new String[0]; + /** + * the config section. + */ + private final String key; + + /** + * Maps with usage references, key is the fully qualified package name. + */ + private final Map<String,AccessDetail> accessDetails = new ConcurrentHashMap<>(); + /** + * The maximal length of the stacktrace stored. + */ + private static int maxTrace = 10; + + /** + * Creates a usage metric container for a given key. + * @param key the parameter (fully qualified). + */ + public UsageStat(String key) { + this.key = Objects.requireNonNull(key); + } + + /** + * Get the maximal length of the stack traces recorded, default is 10. + * @return the maximal length of the stack traces recorded + */ + public static int getMaxTraceLength(){ + return UsageStat.maxTrace; + } + + /** + * Sets the maximal length of the stacktraces stored when tracking configuration + * usage. Setting it to a negative value, disabled stacktrace logging. + * @param maxTrace the maximal recorded stack length. + */ + public static void setMaxTraceLength(int maxTrace){ + UsageStat.maxTrace =maxTrace; + } + + /** + * Get the configModel section. + * + * @return the section, never null. + */ + public String getKey() { + return key; + } + + /** + * Clears all collected usage metrics for this key. + */ + public void clearMetrics(){ + this.accessDetails.clear(); + } + + /** + * Get the detail message. + * + * @return the detail message, or null. + */ + public int getReferenceCount() { + return accessDetails.size(); + } + + /** + * Get the detail message. + * + * @return the detail message, or null. + */ + public int getUsageCount() { + int count = 0; + for(AccessDetail ref: accessDetails.values()){ + count += ref.getAccessCount(); + } + return count; + } + + /** + * Access a usage reference for a given class. + * @param type class to get usage references for, not null. + * @return the usage ref, if present, or null. + */ + public Collection<AccessDetail> getAccessDetails(Class type){ + return getAccessDetails(type.getName() +"\\..*"); + } + + /** + * Access a usage reference for a given package. + * @param pack package to get usage references for, not null. + * @return the usage ref, if present, or null. + */ + public Collection<AccessDetail> getAccessDetails(Package pack){ + return getAccessDetails(pack.getName() +"\\..*"); + } + + /** + * Find usages of this key for the given expression (regex). Hereby the expression is + * matched with the tracked reference identifier, which has the form + * {@code f.q.n.ClassName#methodName(line: 123)}. + * @param lookupExpression the target lookup expression, not null. + * @return the matching references, not null. + */ + public Collection<AccessDetail> getAccessDetails(String lookupExpression){ + List<AccessDetail> result = new ArrayList<>(); + for(AccessDetail ref:this.accessDetails.values()){ + if(ref.getAccessPoint().matches(lookupExpression)){ + result.add(ref); + } + } + return result; + } + + @Override + public String toString() { + return "Usage Count: " + key + " -> " + getUsageCount() + '\n'; + } + + /** + * Get the access details (stacktrace etc) for this reference. + * @return return the access details, not null. + */ + public Collection<AccessDetail> getAccessDetails(){ + return Collections.unmodifiableCollection(accessDetails.values()); + } + + /** + * Evaluates the current access point from the current stacktrace and adds an according + * usage reference object (or updates any existing one) for the given key. The + * stacktrace is shortened to a maximal size of 20 items. + * @param value the value returned, not null. + */ + public void trackUsage(String value){ + trackUsage(value, maxTrace); + } + + /** + * Evaluates the current access point from the current stacktrace and adds an according + * usage reference object (or updates any existing one) for the given key. + * @param value the value returned, not null. + * @param maxTraceLength the maximal length of the stored stacktrace. + */ + public void trackUsage(String value, int maxTraceLength){ + String accessPoint = null; + if(maxTraceLength>0) { + Exception e = new Exception(); + List<String> trace = new ArrayList<>(); + stack: + for (StackTraceElement ste : e.getStackTrace()) { + for (String ignored : ConfigUsage.getIgnoredUsagePackages()) { + if (ste.getClassName().startsWith(ignored)) { + continue stack; + } + } + String ref = ste.getClassName() + '#' + ste.getMethodName() + "(line:" + ste.getLineNumber() + ')'; + trace.add(ref); + if (accessPoint == null) { + accessPoint = ref; + } + if (trace.size() >= maxTraceLength) { + break; + } + } + if (accessPoint == null) { + // all ignored, take first one, with different package + accessPoint = "<unknown/filtered/internal>"; + } + AccessDetail details = getAccessDetails(accessPoint, trace.toArray(new String[trace.size()])); + details.trackAccess(value); + }else{ + accessPoint = "<disabled>"; + AccessDetail details = getAccessDetails(accessPoint, EMPTY_TRACE); + details.trackAccess(value); + } + } + + private AccessDetail getAccessDetails(String accessPoint, String[] trace) { + AccessDetail details = accessDetails.get(accessPoint); + if(details==null){ + details = new AccessDetail(key, accessPoint, trace); + accessDetails.put(accessPoint, details); + } + return details; + } + + /** + * Class modelling the access details tracked per detailed item, e.g. per class in the owning package. + */ + public static final class AccessDetail { + private String key; + private AtomicLong accessCount = new AtomicLong(); + private long lastAccessTS; + private long firstAccessTS; + private String[] stackTrace; + private String accessPoint; + private Map<Long, String> trackedValues; + + public AccessDetail(String key, String accessPoint, String[] stackTrace){ + this.key = Objects.requireNonNull(key); + this.accessPoint = Objects.requireNonNull(accessPoint); + this.stackTrace = stackTrace.clone(); + } + + public void clearStats(){ + lastAccessTS = 0; + firstAccessTS = 0; + accessCount.set(0); + } + + public long trackAccess(String value){ + long count = accessCount.incrementAndGet(); + lastAccessTS = System.currentTimeMillis(); + if(firstAccessTS==0){ + firstAccessTS = lastAccessTS; + } + if(value!=null){ + synchronized (this) { + if(trackedValues==null){ + trackedValues = new HashMap<>(); + } + trackedValues.put(lastAccessTS, value); + } + } + return count; + } + + public String getKey(){ + return key; + } + + public long getAccessCount() { + return accessCount.get(); + } + + public String getAccessPoint() { + return accessPoint; + } + + public long getFirstAccessTS() { + return firstAccessTS; + } + + public long getLastAccessTS() { + return lastAccessTS; + } + + public String[] getStackTrace() { + return stackTrace.clone(); + } + + public Map<Long, String> getTrackedValues(){ + synchronized (this) { + if (trackedValues == null) { + return Collections.emptyMap(); + } else { + return new HashMap<>(trackedValues); + } + } + } + + @Override + public String toString() { + return "AccessDetails{" + + "key=" + key + + ", accessCount=" + accessCount + + ", lastAccessTS=" + lastAccessTS + + ", firstAccessTS=" + firstAccessTS + + ", stackTrace=" + Arrays.toString(stackTrace) + + ", accessPoint='" + accessPoint + '\'' + + ", trackedValues=" + trackedValues + + '}'; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java new file mode 100644 index 0000000..f268cc7 --- /dev/null +++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.usagetracker.internal; + +import org.apache.tamaya.usagetracker.UsageStat; +import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by atsticks on 29.04.16. + */ +public class DefaultConfigUsage implements ConfigUsageSpi { + + private Set<String> ignoredPackages = new HashSet<>(); + + private Map<String, UsageStat> usages = new ConcurrentHashMap<>(); + + /** By default usage tracking is not enabled. */ + private boolean usageTrackingEnabled = initEnabled(); + + /** + * Method that checks the 'tamaya.usage-report' system property for + * enabling tamaya usage reporting initially. + * @return {@code true} iff property is set to {@code true} + */ + private boolean initEnabled() { + String val = System.getProperty("tamaya.usage-report"); + if(Boolean.parseBoolean(val)){ + return true; + } + return false; + } + + public DefaultConfigUsage(){ + ignoredPackages.add("com.intellij"); + ignoredPackages.add("java"); + ignoredPackages.add("org.junit"); + ignoredPackages.add("junit"); + ignoredPackages.add("javax"); + ignoredPackages.add("sun"); + ignoredPackages.add("oracle"); + ignoredPackages.add("com.sun"); + ignoredPackages.add("com.oracle"); + ignoredPackages.add("org.apache.tamaya"); + } + + @Override + public void enableUsageTracking(boolean enabled){ + this.usageTrackingEnabled = enabled; + } + + @Override + public boolean isUsageTrackingEnabled(){ + return usageTrackingEnabled; + } + + @Override + public Set<String> getIgnoredPackages() { + return Collections.unmodifiableSet(ignoredPackages); + } + + @Override + public void addIgnoredUsagePackages(String... packageName) { + + } + + @Override + public UsageStat getUsage(String key) { + return this.usages.get(key); + } + + @Override + public UsageStat getUsageAllProperties() { + return this.usages.get("<<all>>"); + } + + /** + * Get the recorded usage references of configuration. + * @return the recorded usge references, never null. + */ + @Override + public Collection<UsageStat> getUsages() { + return usages.values(); + } + + @Override + public void trackAllPropertiesAccess(){ + trackSingleKeyAccess("<<all>>", "<not stored>"); + } + + @Override + public void trackSingleKeyAccess(String key, String value){ + // Ignore meta-entries + if(!isUsageTrackingEnabled() || key.startsWith("_")){ + return; + } + UsageStat usage = this.usages.get(key); + if(usage==null){ + usage = new UsageStat(key); + this.usages.put(key, usage); + } + usage.trackUsage(value); + } + + + /** + * Access the usage statistics for the recorded uses of configuration. + */ + @Override + public String getUsageInfo(){ + StringBuilder b = new StringBuilder(); + b.append("Apache Tamaya Configuration Usage Metrics\n"); + b.append("=========================================\n"); + b.append("DATE: ").append(new Date()).append("\n\n"); + List<UsageStat> usages = new ArrayList<>(getUsages()); + Collections.sort(usages, new Comparator<UsageStat>() { + @Override + public int compare(UsageStat k1, UsageStat k2) { + return k2.getUsageCount() - k1.getUsageCount(); + } + }); + for(UsageStat usage:usages){ + String usageCount = String.valueOf(usage.getUsageCount()); + b.append(usageCount); + b.append(" ".substring(0, 7-usageCount.length())); + b.append(usage.getKey()).append(":\n"); + for(UsageStat.AccessDetail details: usage.getAccessDetails()) { + String accessCount = String.valueOf(details.getAccessCount()); + b.append(" - ").append(accessCount); + b.append(" ".substring(0, 6-usageCount.length())); + b.append(details.getAccessPoint()); + int endIndex = 50-details.getAccessPoint().length(); + if(endIndex<0){ + endIndex = 0; + } + b.append(" ".substring(0, endIndex)); + b.append(",");b.append(" first=").append(new Date(details.getFirstAccessTS())) + .append(",");b.append(" last=").append(new Date(details.getLastAccessTS())) + .append('\n'); + } + } + return b.toString(); + } + + @Override + public void clearUsageStats() { + this.usages.clear(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java new file mode 100644 index 0000000..30a643d --- /dev/null +++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java @@ -0,0 +1,46 @@ +/* + * 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.usagetracker.internal; + +import org.apache.tamaya.spi.FilterContext; +import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.ServiceContextManager; +import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi; + +import javax.annotation.Priority; + +/** + * Configuration filter to be applied at the end of the filter chain. This filter + * actually does not change the current filter value, but use the filter process + * to track configuration usage. + */ +@Priority(Integer.MAX_VALUE) +public class UsageTrackerFilter implements PropertyFilter{ + + @Override + public String filterProperty(String value, FilterContext context) { + ConfigUsageSpi tracker = ServiceContextManager.getServiceContext().getService(ConfigUsageSpi.class); + if (context.isSinglePropertyScoped()) { + tracker.trackSingleKeyAccess(context.getKey(), value); + } else { + tracker.trackAllPropertiesAccess(); + } + return value; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java new file mode 100644 index 0000000..f76586c --- /dev/null +++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java @@ -0,0 +1,101 @@ +/* + * 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.usagetracker.spi; + +import org.apache.tamaya.usagetracker.UsageStat; + +import java.util.Collection; +import java.util.Set; + +/** + * SPI to be implemented by the component responsible for usage tracking of + * configuration. + */ +public interface ConfigUsageSpi { + + /** + * Enables/disables usage tracking. + * @param enable set to true to enable usage tracking. + */ + void enableUsageTracking(boolean enable); + + /** + * Allows to check if usage tracking is enabled (should be disbled by default). + * @return true, if usage tracking is enabled. + */ + boolean isUsageTrackingEnabled(); + + /** + * Get the list of packages, which are not evaluated for tracking configuration access and usage statistics. + * @return the set of ignored package names. + */ + Set<String> getIgnoredPackages(); + + /** + * Adds the given packageNames to the list of packages to be ignored when collecting usage data. + * @param packageName the package names to be added, not null. + */ + void addIgnoredUsagePackages(String... packageName); + + /** + * Access the usage statistics for a given key. If usage stats collection is not + * activated (default), this method returns null. + * @param key the fully qualified configuration key, not null. + * @return the stats collected, or null. + */ + UsageStat getUsage(String key); + + /** + * Access the usage statistics for accessing {@link org.apache.tamaya.Configuration#getProperties()}. + * If usage stats collection is not activated (default), this method returns null. + * @return the stats collected, or null. + */ + UsageStat getUsageAllProperties(); + + /** + * Get the recorded usage references of configuration. + * @return the recorded usge references, never null. + */ + Collection<UsageStat> getUsages(); + + /** + * Track the access of {@code Configuration#getProperties()} for + * usage statistics. + */ + void trackAllPropertiesAccess(); + + /** + * Track the access of {@code Configuration#get(String)} for + * usage statistics. + * @param key key to track for + * @param value value to track for + */ + void trackSingleKeyAccess(String key, String value); + + /** + * Access the usage statistics for the recorded uses of configuration. + * @return usage statistics info + */ + String getUsageInfo(); + + /** + * Clears all collected usage statistics. + */ + void clearUsageStats(); +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/configmodel.properties ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/resources/META-INF/configmodel.properties b/usagetracker/src/main/resources/META-INF/configmodel.properties new file mode 100644 index 0000000..3381a09 --- /dev/null +++ b/usagetracker/src/main/resources/META-INF/configmodel.properties @@ -0,0 +1,35 @@ +# +# 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. +# +# Contains definitions for default system property areas. +_awt.model.target=Section +_awt.model.transitive=true +_file.model.target=Section +_file.model.transitive=true +_java.model.target=Section +_java.model.transitive=true +_line.model.target=Section +_line.model.transitive=true +_os.model.target=Section +_os.model.transitive=true +_path.model.target=Section +_path.model.transitive=true +_sun.model.target=Section +_sun.model.transitive=true +_user.model.target=Section +_user.model.transitive=true http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener new file mode 100644 index 0000000..8075703 --- /dev/null +++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy current the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.tamaya.model.internal.ConfiguredTypeEventsModelPopulator http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi new file mode 100644 index 0000000..b394c17 --- /dev/null +++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi @@ -0,0 +1,22 @@ +# +# 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.model.internal.ConfiguredPropertiesModelProviderSpi +org.apache.tamaya.model.internal.ConfiguredInlineModelProviderSpi +org.apache.tamaya.model.internal.ConfiguredResourcesModelProviderSpi +org.apache.tamaya.model.internal.ConfiguredTypeEventsModelProvider \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter new file mode 100644 index 0000000..dee62d6 --- /dev/null +++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy current the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.tamaya.usagetracker.internal.UsageTrackerFilter \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi ---------------------------------------------------------------------- diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi new file mode 100644 index 0000000..2ba5789 --- /dev/null +++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy current the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.tamaya.usagetracker.internal.DefaultConfigUsage \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java b/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java new file mode 100644 index 0000000..a16a62e --- /dev/null +++ b/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java @@ -0,0 +1,75 @@ +/* + * 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.model; + +import org.apache.tamaya.Configuration; +import org.apache.tamaya.ConfigurationProvider; +import org.apache.tamaya.usagetracker.ConfigUsage; +import org.junit.Test; +import test.model.TestConfigAccessor; + +import static org.junit.Assert.*; + +/** + * Created by Anatole on 09.08.2015. + */ +public class ConfigUsageStatsTest { + + @Test + public void testUsageWhenEnabled(){ + ConfigUsage.enableUsageTracking(true); + TestConfigAccessor.readConfiguration(); + Configuration config = ConfigurationProvider.getConfiguration(); + String info = ConfigUsage.getUsageInfo(); + assertFalse(info.contains("java.version")); + assertNotNull(info); + config = TestConfigAccessor.readConfiguration(); + config.getProperties(); + TestConfigAccessor.readProperty(config, "java.locale"); + TestConfigAccessor.readProperty(config, "java.version"); + TestConfigAccessor.readProperty(config, "java.version"); + config.get("java.version"); + info = ConfigUsage.getUsageInfo(); + System.out.println(info); + assertTrue(info.contains("java.version")); + assertNotNull(info); + ConfigUsage.enableUsageTracking(false); + } + + @Test + public void testUsageWhenDisabled(){ + ConfigUsage.enableUsageTracking(false); + ConfigUsage.clearUsageStats(); + TestConfigAccessor.readConfiguration(); + Configuration config = ConfigurationProvider.getConfiguration(); + String info = ConfigUsage.getUsageInfo(); + assertNotNull(info); + assertFalse(info.contains("java.version")); + config = TestConfigAccessor.readConfiguration(); + config.getProperties(); + TestConfigAccessor.readProperty(config, "java.locale"); + TestConfigAccessor.readProperty(config, "java.version"); + TestConfigAccessor.readProperty(config, "java.version"); + config.get("java.version"); + info = ConfigUsage.getUsageInfo(); + assertFalse(info.contains("java.version")); + assertNotNull(info); + ConfigUsage.enableUsageTracking(false); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/java/test/model/TestConfigAccessor.java ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/java/test/model/TestConfigAccessor.java b/usagetracker/src/test/java/test/model/TestConfigAccessor.java new file mode 100644 index 0000000..498d2b6 --- /dev/null +++ b/usagetracker/src/test/java/test/model/TestConfigAccessor.java @@ -0,0 +1,45 @@ +/* + * 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 test.model; + +import org.apache.tamaya.Configuration; +import org.apache.tamaya.ConfigurationProvider; + +import java.util.Map; + +/** + * Created by atsticks on 30.04.16. + */ +public final class TestConfigAccessor { + + private TestConfigAccessor(){} + + public static Map<String,String> readAllProperties(){ + return ConfigurationProvider.getConfiguration() + .getProperties(); + } + + public static Configuration readConfiguration(){ + return ConfigurationProvider.getConfiguration(); + } + + public static String readProperty(Configuration config, String key){ + return config.get(key); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/META-INF/configmodel.properties ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/resources/META-INF/configmodel.properties b/usagetracker/src/test/resources/META-INF/configmodel.properties new file mode 100644 index 0000000..a7956dc --- /dev/null +++ b/usagetracker/src/test/resources/META-INF/configmodel.properties @@ -0,0 +1,96 @@ +# +# 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. +# + +################################################################################### +# Example of a configuration metamodel expressed via properties. +#################################################################################### + +# Metamodel information +_model.provider=ConfigModel Extension + +# reusable parameter definition, referenceable as MyNumber +_MyNumber.model.target=Parameter +_MyNumber.model.type=Integer +_MyNumber.model.description=a (reusable) number type parameter (optional) + +#################################################################################### +# Description of Configuration Sections (minimal, can be extended by other modules). +# By default its interpreted as a section ! +#################################################################################### + +# a (section) +_a.model.target=Section +_a.params2.model.target=Parameter +_a.params2.model.type=String +_a.params2.model.required=true +_a.params2.model.description=a required parameter + +_a.paramInt.model.target=Parameter +_a.paramInt.model.type=ref:MyNumber +_a.paramInt.model.description=an optional parameter (default) + +_a._number.model.target=Parameter +_a._number.model.type=Integer +_a._number.model.deprecated=true +_a._number.model.mappedTo=a.paramInt + +# a.b.c (section) +_a.b.c.model.target=Section +_a.b.c.model.description=Just a test section + +# a.b.c.aRequiredSection (section) +_a.b.c.aRequiredSection.model.target=Section +_a.b.c.aRequiredSection.model.required=true +_a.b.c.aRequiredSection.model.description=A section containing required parameters is called a required section.\ + Sections can also explicitly be defined to be required, but without\ + specifying the paramteres to be contained., + +# a.b.c.aRequiredSection.subsection (section) +_a.b.c.aRequiredSection.subsection.model.target=Section + +_a.b.c.aRequiredSection.subsection.param0.model.model.target=Parameter +_a.b.c.aRequiredSection.subsection.param0.type=String +_a.b.c.aRequiredSection.subsection.param0.model.description=a minmally documented String parameter +# A minmal String parameter +_a.b.c.aRequiredSection.subsection.param00.model.target=Parameter +_a.b.c.aRequiredSection.subsection.param00.model.type=String + +# a.b.c.aRequiredSection.subsection (section) +_a.b.c.aRequiredSection.subsection.param1.model.target=Parameter +_a.b.c.aRequiredSection.subsection.param1.model.type = String +_a.b.c.aRequiredSection.subsection.param1.model.required = true +_a.b.c.aRequiredSection.subsection.intParam.model.target=Parameter +_a.b.c.aRequiredSection.subsection.intParam.model.type = Integer +_a.b.c.aRequiredSection.subsection.intParam.model.description=an optional parameter (default) + +# a.b.c.aRequiredSection.nonempty-subsection (section) +_a.b.c.aRequiredSection.nonempty-subsection.model.target=Section +_a.b.c.aRequiredSection.nonempty-subsection.model.required=true + +# a.b.c.aRequiredSection.optional-subsection (section) +_a.b.c.aRequiredSection.optional-subsection.model.target=Section + +# a.b.c.aValidatedSection (section) +_a.b.c.aValidatedSection.model.target=Section +_a.b.c.aValidatedSection.model.description=A validated section. +_a.b.c.aValidatedSection.model.validator=org.apache.tamaya.model.TestValidator + + + + http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/META-INF/javaconfiguration.properties ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/resources/META-INF/javaconfiguration.properties b/usagetracker/src/test/resources/META-INF/javaconfiguration.properties new file mode 100644 index 0000000..b0b8c22 --- /dev/null +++ b/usagetracker/src/test/resources/META-INF/javaconfiguration.properties @@ -0,0 +1,22 @@ +# +# 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. +# +a.test.existing.aParam=existingValue +a.test.existing.optionalParam=optionalValue +a.test.existing.aABCParam=ABCparam +a.test.existing.aABCParam2=MMM http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi b/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi new file mode 100644 index 0000000..9b29fda --- /dev/null +++ b/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy current the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.tamaya.model.ConfigModelProviderTest \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/examples/configmodel.ini ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/resources/examples/configmodel.ini b/usagetracker/src/test/resources/examples/configmodel.ini new file mode 100644 index 0000000..0e10cc1 --- /dev/null +++ b/usagetracker/src/test/resources/examples/configmodel.ini @@ -0,0 +1,76 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy 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. +# + +################################################################################### +# Example of a configuration metamodel expressed via ini(tm). +#################################################################################### + +#################################################################################### +# Description of Configuration Sections (minimal, can be extended by other modules). +# By default its interpreted as a section ! +#################################################################################### +[_a.model] +class = Section +params2.type = String +params2.required = true +params2.description = "a required parameter" +paramInt.ref = MyNumber +paramInt.description = "an optional parameter (default)" +_number.type = Integer +_number.deprecated = true +_number.mappedTo = "a.paramInt" + +[_a.b.c.model] +class = Section +description = Just a test section + +[_a.b.c.aRequiredSection.model] +class = Section +required = true +description = A section containing required parameters is called a required section.\ + Sections can also explicitly be defined to be required, but without\ + specifying the paramteres to be contained., + +[_a.b.c.aRequiredSection.subsection.model] +class = Section +param0.type = String +param0.description = "a minmally documented String parameter" +# A minmal String parameter +param00.type = String +# description is optional +param1.type = String +param1.required = true +intParam.type = Integer +intParam.description = "an optional parameter (default)" + +[_a.b.c.aRequiredSection.nonempty-subsection.model] +class = Section +required = true + +[_a.b.c.aRequiredSection.optional-subsection.model] +class = Section + +[_a.b.c.aValidatedSection.model] +class = Section +description = "A configModel section." +configModels = org.apache.tamaya.model.TestValidator?max=3 + + + + http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/examples/configmodel.json ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/resources/examples/configmodel.json b/usagetracker/src/test/resources/examples/configmodel.json new file mode 100644 index 0000000..529f26e --- /dev/null +++ b/usagetracker/src/test/resources/examples/configmodel.json @@ -0,0 +1,108 @@ +/* +* 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. +*/ + +//################################################################################## +// Example of a configuration metamodel expressed via YAML(tm). +// Structure is shown through indentation (one or more spaces). +// Sequence items are denoted by a dash, +// key value pairs within a map are separated by a colon. +//################################################################################## + +//################################################################################## +// Metamodel information +//################################################################################## +{ + "_model": { + "provider": "ConfigModel Extension", + // reusable parameter definition + }, + "_MyNumber.model": { + "class": "Parameter", + "type": "Integer", + "template": true, + "description": "an (reusable) number type parameter (optional)" + }, + //################################################################################## + // Description of Configuration Sections (minimal, can be extended by other modules). + //################################################################################## + "_a.model": { + "class": "Section", + // required, default is parameter! + }, + "_a.params2.model": { + "required": true, + "description": "a required parameter" + }, + "_a.paramInt.model": { + // references a shared parameter definition. + "ref": "MyNumber", + "description": "an optional parameter (default)" + }, + "_a.number.model": { + "type": "Integer", + "deprecated": true, + // references a deprecated parameter, now mapped to 'a.paramInt'. + "mappedto": "a.paramInt" + }, + "_a.b.c.model": { + "class": "Section", + "description": "Just a test section." + // a subsection, directly configured as child element. + }, + "_a.b.c.aRequiredSection.model": { + "class": "Section", + "required": true, + "description": "A section containing required parameters is called a required section." + }, + // a subsection, configured in its own section. + "_a.b.c.aRequiredSection.subsection.model": { + "class": "Section" + } + "_a.b.c.param0-model": { + "type": "String", + "description": "a minimally documented String parameter" + }, + // A minimally defined String parameter + "_a.b.c.param00": {}, + "_a.b.c.param1": { + "type": "String", + "required": true, + "description": "a required parameter" + }, + "_a.b.c.intParam": { + "type": "Integer", + "required": true, + "description": "an optional parameter (default)" + }, + "_a.b.c.aRequiredSection.nonempty-subsection.model": { + "class": "Section", + "required": true + }, + "_a.b.c.aRequiredSection.optional-subsection.model": { + "class": "Section" + }, + "_a.b.c.aRequiredSection.aValidatedSection.model": { + "class": "Section", + "description": "A validated section.", + "validations": "org.apache.tamaya.model.validation.MaxItemValidator?max=3" + } + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/examples/configmodel.properties ---------------------------------------------------------------------- diff --git a/usagetracker/src/test/resources/examples/configmodel.properties b/usagetracker/src/test/resources/examples/configmodel.properties new file mode 100644 index 0000000..b61695b --- /dev/null +++ b/usagetracker/src/test/resources/examples/configmodel.properties @@ -0,0 +1,96 @@ +# +# 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. +# + +################################################################################### +# Example of a configuration metamodel expressed via properties. +#################################################################################### + +# Metamodel information +_model.provider=ConfigModel Extension + +# reusable parameter definition, referenceable as MyNumber +_MyNumber.model.class=Parameter +_MyNumber.model.type=Integer +_MyNumber.model.description=a (reusable) number type parameter (optional) + +#################################################################################### +# Description of Configuration Sections (minimal, can be extended by other modules). +# By default its interpreted as a section ! +#################################################################################### + +# a (section) +_a.model.class=Section +_a.params2.model.class=Parameter +_a.params2.model.type=String +_a.params2.model.required=true +_a.params2.model.description=a required parameter + +_a.paramInt.model.class=Parameter +_a.paramInt.model.type=ref:MyNumber +_a.paramInt.model.description=an optional parameter (default) + +_a._number.model.class=Parameter +_a._number.model.type=Integer +_a._number.model.deprecated=true +_a._number.model.mappedTo=a.paramInt + +# a.b.c (section) +_a.b.c.class=Section +_a.b.c.description=Just a test section + +# a.b.c.aRequiredSection (section) +_a.b.c.aRequiredSection.model.class=Section +_a.b.c.aRequiredSection.model.required=true +_a.b.c.aRequiredSection.model.description=A section containing required parameters is called a required section.\ + Sections can also explicitly be defined to be required, but without\ + specifying the paramteres to be contained., + +# a.b.c.aRequiredSection.subsection (section) +_a.b.c.aRequiredSection.model.subsection.class=Section + +_a.b.c.aRequiredSection.subsection.param0.model.class=Parameter +_a.b.c.aRequiredSection.subsection.param0.model.type=String +_a.b.c.aRequiredSection.subsection.param0.model.description=a minmally documented String parameter +# A minmal String parameter +_a.b.c.aRequiredSection.subsection.param00.model.class=Parameter +_a.b.c.aRequiredSection.subsection.param00.model.type=String + +# a.b.c.aRequiredSection.subsection (section) +_a.b.c.aRequiredSection.subsection.param1.model.class=Parameter +_a.b.c.aRequiredSection.subsection.param1.model.type = String +_a.b.c.aRequiredSection.subsection.param1.model.required = true +_a.b.c.aRequiredSection.subsection.intParam.model.class=Parameter +_a.b.c.aRequiredSection.subsection.intParam.model.type = Integer +_a.b.c.aRequiredSection.subsection.intParam.model.description=an optional parameter (default) + +# a.b.c.aRequiredSection.nonempty-subsection (section) +_a.b.c.aRequiredSection.nonempty-subsection.model.class=Section +_a.b.c.aRequiredSection.nonempty-subsection.model.required=true + +# a.b.c.aRequiredSection.optional-subsection (section) +_a.b.c.aRequiredSection.optional-subsection.model.class=Section + +# a.b.c.aValidatedSection (section) +_a.b.c.aValidatedSection.model.class=Section +_a.b.c.aValidatedSection.model.description=A validated section. +_a.b.c.aValidatedSection.model.configModels=org.apache.tamaya.model.TestValidator + + + +
