View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.monitoring.configuration;
18  
19  import org.apache.commons.monitoring.MonitoringException;
20  import org.apache.commons.monitoring.util.ClassLoaders;
21  
22  import java.io.File;
23  import java.io.FileInputStream;
24  import java.io.FileNotFoundException;
25  import java.io.InputStream;
26  import java.lang.annotation.ElementType;
27  import java.lang.annotation.Retention;
28  import java.lang.annotation.RetentionPolicy;
29  import java.lang.annotation.Target;
30  import java.lang.reflect.Method;
31  import java.util.ArrayList;
32  import java.util.Collection;
33  import java.util.Properties;
34  import java.util.logging.Level;
35  import java.util.logging.Logger;
36  
37  public final class Configuration {
38      private static final Logger LOGGER = Logger.getLogger(Configuration.class.getName());
39  
40      private static final Collection<ToDestroy> INSTANCES = new ArrayList<ToDestroy>();
41  
42      public static final String COMMONS_MONITORING_PREFIX = "org.apache.commons.monitoring.";
43      private static final String DEFAULT_CONFIGURATION_FILE = "commons-monitoring.properties";
44  
45      private static Thread shutdownHook = null;
46  
47      private static final Properties PROPERTIES = new Properties(System.getProperties());
48      static {
49          try {
50              final InputStream is = findConfiguration();
51              if (is != null) {
52                  PROPERTIES.load(is);
53              }
54          } catch (final Exception e) {
55              LOGGER.log(Level.SEVERE, e.getMessage(), e);
56          }
57      }
58      private static InputStream findConfiguration() throws FileNotFoundException {
59          final String filename = System.getProperty(COMMONS_MONITORING_PREFIX + "configuration", DEFAULT_CONFIGURATION_FILE);
60          if (new File(filename).exists()) {
61              return new FileInputStream(filename);
62          }
63  
64          return ClassLoaders.current().getResourceAsStream(filename);
65      }
66  
67      public static synchronized <T> T newInstance(final Class<T> clazz) {
68          try {
69              String config = PROPERTIES.getProperty(clazz.getName());
70              if (config == null) {
71                  config = clazz.getPackage().getName() + ".Default" + clazz.getSimpleName();
72              }
73  
74              Class<?> loadedClass;
75              try {
76                  loadedClass = ClassLoaders.current().loadClass(config);
77              } catch (final Throwable throwable) { // NoClassDefFoundError or Exception
78                  loadedClass = clazz;
79              }
80  
81              final Object instance = loadedClass.newInstance();
82              for (final Method m : loadedClass.getMethods()) {
83                  if (m.getAnnotation(Created.class) != null) {
84                      m.invoke(instance);
85                  } else if (m.getAnnotation(Destroying.class) != null) {
86                      if (shutdownHook == null == is(COMMONS_MONITORING_PREFIX + "shutdown.hook", true)) {
87                          shutdownHook = new Thread() {
88                              @Override
89                              public void run() {
90                                  shutdown();
91                              }
92                          };
93                          Runtime.getRuntime().addShutdownHook(shutdownHook);
94                      }
95                      INSTANCES.add(new ToDestroy(m, instance));
96                  }
97              }
98  
99              return clazz.cast(instance);
100         } catch (final Exception e) {
101             throw new MonitoringException(e);
102         }
103     }
104 
105     public static boolean is(final String key, final boolean defaultValue) {
106         return Boolean.parseBoolean(getProperty(key, Boolean.toString(defaultValue)));
107     }
108 
109     public static int getInteger(final String key, final int defaultValue) {
110         return Integer.parseInt(getProperty(key, Integer.toString(defaultValue)));
111     }
112 
113     public static String getProperty(final String key, final String defaultValue) {
114         return PROPERTIES.getProperty(key, defaultValue);
115     }
116 
117     public static void shutdown() {
118         for (final ToDestroy c : INSTANCES) {
119             c.destroy();
120         }
121         INSTANCES.clear();
122     }
123 
124     private Configuration() {
125         // no-op
126     }
127 
128     @Retention(RetentionPolicy.RUNTIME)
129     @Target(ElementType.METHOD)
130     public static @interface Created {
131     }
132 
133     @Retention(RetentionPolicy.RUNTIME)
134     @Target(ElementType.METHOD)
135     public static @interface Destroying {
136     }
137 
138     private static class ToDestroy {
139         private final Method method;
140         private final Object target;
141 
142         public ToDestroy(final Method m, final Object instance) {
143             this.method = m;
144             this.target = instance;
145         }
146 
147         public void destroy() {
148             try {
149                 method.invoke(target);
150             } catch (final Exception e) {
151                 // no-op
152             }
153         }
154     }
155 }