View Javadoc

1   /*
2    * Copyright 2009, Josh Devins, Jitr.org.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.jitr;
18  
19  import org.apache.log4j.Logger;
20  import org.jitr.annotation.JitrConfiguration;
21  import org.jitr.container.JettyContainer;
22  import org.jitr.core.ConfigurationModel;
23  import org.jitr.core.Container;
24  import org.jitr.core.Defaults;
25  import org.jitr.core.JitrException;
26  import org.jitr.core.OperationalMode;
27  
28  /**
29   * A simple factory for creating {@link ConfigurationModel}s. This takes into account any
30   * {@link JitrConfiguration} annotations as well as any overriding system properties.
31   * 
32   * @author Josh Devins (info@joshdevins.net)
33   */
34  public final class JitrConfigurationFactory {
35  
36      private static enum From {
37          SYSTEM_PROPERTY("system property"), ANNOTATION("annotation"), DEFAULT("default"), OTHER;
38  
39          private final String str;
40  
41          private From() {
42              str = null;
43          }
44  
45          private From(final String str) {
46              this.str = str;
47          }
48  
49          @Override
50          public String toString() {
51              return str == null ? super.toString() : str;
52          }
53      }
54  
55      /**
56       * Prefix string used for all Jitr system properties.
57       */
58      public static final String SP_KEY_PREFIX = "jitr.";
59  
60      /**
61       * The system property key to use when setting the base URI from the command line. This is
62       * mostly useful when disabling the container from the command line and you are taking care of
63       * running the container yourself.
64       * 
65       * {@value #BASE_URI_SP_KEY}
66       * 
67       * @see #MODE_SP_KEY
68       */
69      public static final String BASE_URI_SP_KEY = SP_KEY_PREFIX + "baseUri";
70  
71      /**
72       * The system property key to use when setting the container class from the command line.
73       * 
74       * {@value #MODE_SP_KEY}
75       */
76      public static final String CONTAINER_CLASS_SP_KEY = SP_KEY_PREFIX + "containerClass";
77  
78      /**
79       * The system property key to use when setting the operational mode from the command line.
80       * 
81       * {@value #MODE_SP_KEY}
82       */
83      public static final String MODE_SP_KEY = SP_KEY_PREFIX + "mode";
84  
85      /**
86       * The system property key to use when setting the port from the command line. This is mostly
87       * useful when disabling the container from the command line and you are taking care of running
88       * the container yourself.
89       * 
90       * {@value #PORT_SP_KEY}
91       * 
92       * @see #MODE_SP_KEY
93       */
94      public static final String PORT_SP_KEY = SP_KEY_PREFIX + "port";
95  
96      private static final Logger LOG = Logger.getLogger(JitrConfigurationFactory.class);
97  
98      private JitrConfigurationFactory() {
99          // do not instantiate
100     }
101 
102     public static ConfigurationModel createConfigurationFromAnnotation(final JitrConfiguration annot) {
103 
104         final Class<?> containerClass = determineContainerClass(annot);
105         final String containerWorkPath = determineContainerWorkPath(annot);
106         final String contextPath = determineContextPath(annot);
107         final OperationalMode mode = determineOperationalMode(annot);
108         final int port = determinePort(annot);
109         final String warPath = determineWarPath(annot);
110 
111         // determine after port and context path
112         final String baseUri = determineBaseUri(port, contextPath);
113 
114         ConfigurationModel config =
115                 new ConfigurationModel(baseUri, containerClass, containerWorkPath, contextPath,
116                         mode, port, warPath);
117 
118         return config;
119     }
120 
121     static String determineBaseUri(final int port, final String contextPath) {
122 
123         final From from;
124         final String baseUri;
125 
126         // always use system property first
127         final String baseUriSp = System.getProperty(BASE_URI_SP_KEY);
128         if (baseUriSp != null) {
129 
130             baseUri = baseUriSp;
131             from = From.SYSTEM_PROPERTY;
132         }
133 
134         // otherwise use the port and context path parameters
135         else {
136             baseUri = "http://localhost:" + port + contextPath;
137             from = From.OTHER;
138         }
139 
140         logSettingConfigValue("base URI", from, baseUri);
141 
142         return baseUri;
143     }
144 
145     static Class<?> determineContainerClass(final JitrConfiguration annot) {
146 
147         final From from;
148         final Class<?> containerClass;
149 
150         // always use system property first
151         final String containerClassSp = System.getProperty(CONTAINER_CLASS_SP_KEY);
152         if (containerClassSp != null) {
153             try {
154                 containerClass = Class.forName(containerClassSp);
155                 from = From.SYSTEM_PROPERTY;
156             } catch (final ClassNotFoundException cnfe) {
157                 throw new JitrException(
158                         "Could not load specified container class (" + containerClassSp
159                                 + "). Make sure you use the fully qualified class name.", cnfe);
160             }
161         }
162 
163         // otherwise use value from annotation (if it exists)
164         else if (annot != null) {
165             if (annot.containerClass() != Object.class) {
166                 containerClass = annot.containerClass();
167             } else {
168                 containerClass = JettyContainer.class;
169             }
170 
171             from = From.ANNOTATION;
172         } else {
173             containerClass = JettyContainer.class;
174             from = From.DEFAULT;
175         }
176 
177         // make sure the class is of type Container
178         if (!Container.class.isAssignableFrom(containerClass)) {
179             throw new JitrException("Container class is not of type Container: "
180                     + containerClass.toString());
181         }
182 
183         logSettingConfigValue("container class", from, containerClass.toString());
184 
185         return containerClass;
186     }
187 
188     static String determineContainerWorkPath(final JitrConfiguration annot) {
189 
190         final From from;
191         final String containerWorkPath;
192 
193         // if no annotation, use default value
194         if (annot == null) {
195             containerWorkPath = Defaults.DEFAULT_CONTAINER_WORK_PATH;
196             from = From.DEFAULT;
197         } else {
198             containerWorkPath = annot.containerWorkPath();
199             from = From.ANNOTATION;
200         }
201 
202         logSettingConfigValue("container work path", from, containerWorkPath);
203 
204         return containerWorkPath;
205     }
206 
207     static String determineContextPath(final JitrConfiguration annot) {
208 
209         final From from;
210         final String contextPath;
211 
212         // if no annotation, use default value
213         if (annot == null) {
214             contextPath = Defaults.DEFAULT_CONTEXT_PATH;
215             from = From.DEFAULT;
216         } else {
217             contextPath = annot.contextPath();
218             from = From.ANNOTATION;
219         }
220 
221         logSettingConfigValue("context path", from, contextPath);
222 
223         return contextPath;
224     }
225 
226     static OperationalMode determineOperationalMode(final JitrConfiguration annot) {
227 
228         final From from;
229         final OperationalMode mode;
230 
231         // always use system property first
232         final String modeSp = System.getProperty(MODE_SP_KEY);
233         if (modeSp != null) {
234             mode = OperationalMode.valueOf(modeSp);
235             from = From.SYSTEM_PROPERTY;
236         }
237 
238         // otherwise use value from annotation (if it exists)
239         else if (annot != null) {
240             mode = annot.mode();
241             from = From.ANNOTATION;
242         } else {
243             mode = Defaults.DEFAULT_MODE;
244             from = From.DEFAULT;
245         }
246 
247         logSettingConfigValue("operational mode", from, mode.toString());
248 
249         return mode;
250     }
251 
252     static int determinePort(final JitrConfiguration annot) {
253 
254         final From from;
255         final int port;
256 
257         // always use system property first
258         final String portSp = System.getProperty(PORT_SP_KEY);
259         if (portSp != null) {
260             port = Integer.parseInt(portSp);
261             from = From.SYSTEM_PROPERTY;
262         }
263 
264         // if the annotation is there and the port has been set
265         else if (annot != null && annot.port() != Defaults.DEFAULT_PORT) {
266 
267             if (annot.port() <= 0) {
268                 throw new JitrException("Configured Jitr port must be greater than 0.");
269             }
270 
271             port = annot.port();
272             from = From.ANNOTATION;
273         }
274 
275         // if there is no annotation or if the port has not been explicitly set, pick a random port
276         else {
277             port = JitrUtils.getRandomUnusedPort();
278             from = From.OTHER;
279         }
280 
281         logSettingConfigValue("port", from, Integer.toString(port));
282 
283         return port;
284     }
285 
286     static String determineWarPath(final JitrConfiguration annot) {
287 
288         final From from;
289         final String warPath;
290 
291         // if no annotation, use default value
292         if (annot == null) {
293             warPath = Defaults.DEFAULT_WAR_PATH;
294             from = From.DEFAULT;
295         } else {
296             warPath = annot.warPath();
297             from = From.ANNOTATION;
298         }
299 
300         logSettingConfigValue("war path", from, warPath);
301 
302         return warPath;
303     }
304 
305     private static void logSettingConfigValue(final String key, final From from, final String value) {
306 
307         if (!LOG.isInfoEnabled()) {
308             return;
309         }
310 
311         if (from == From.DEFAULT) {
312             LOG.info(key + " (" + from + "): " + value);
313         } else if (from != From.OTHER) {
314             LOG.info(key + " (from " + from + "): " + value);
315         } else {
316             LOG.info(key + ": " + value);
317         }
318     }
319 }