View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2007 utgenome.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  // GenomeBrowser Project
18  //
19  // UTGB.java
20  // Since: May 29, 2007
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.server;
26  
27  import java.io.BufferedReader;
28  import java.io.File;
29  import java.io.IOException;
30  import java.io.InputStreamReader;
31  import java.net.MalformedURLException;
32  import java.net.URL;
33  import java.util.HashMap;
34  
35  import javax.naming.Context;
36  import javax.naming.InitialContext;
37  import javax.naming.NamingException;
38  import javax.servlet.ServletContextEvent;
39  import javax.servlet.ServletContextListener;
40  import javax.servlet.ServletException;
41  import javax.servlet.http.HttpServletRequest;
42  
43  import org.apache.log4j.BasicConfigurator;
44  import org.utgenome.UTGBErrorCode;
45  import org.utgenome.UTGBException;
46  import org.utgenome.config.UTGBConfig;
47  import org.utgenome.config.UTGBConfig.Database;
48  import org.utgenome.config.UTGBConfig.WebAction;
49  import org.xerial.core.XerialException;
50  import org.xerial.db.DBException;
51  import org.xerial.db.sql.DatabaseAccess;
52  import org.xerial.lens.SilkLens;
53  import org.xerial.util.log.Logger;
54  
55  /**
56   * UTGB Master loads the configuration files, and set up shared variables, database access, etc.
57   * 
58   * 
59   * @author leo
60   * 
61   */
62  public class UTGBMaster implements ServletContextListener {
63  	private static Logger _logger = Logger.getLogger(UTGBMaster.class);
64  	private static UTGBMaster _instance = new UTGBMaster();
65  
66  	private UTGBConfig config = null;
67  	private HashMap<String, Object> _glovalVariableHolder = new HashMap<String, Object>();
68  	private HashMap<String, DatabaseAccess> _dbAccessTable = new HashMap<String, DatabaseAccess>();
69  
70  	public static UTGBMaster getInstance() {
71  		return _instance;
72  	}
73  
74  	@SuppressWarnings("unchecked")
75  	public static <T> T getVariable(String name) {
76  		return (T) _instance._glovalVariableHolder.get(name);
77  	}
78  
79  	public static void setVariable(String name, Object value) {
80  		_instance._glovalVariableHolder.put(name, value);
81  	}
82  
83  	public static UTGBConfig getUTGBConfig() {
84  		UTGBMaster master = getInstance();
85  		if (master.config != null)
86  			return master.config;
87  
88  		try {
89  			master.config = loadUTGBConfig();
90  		}
91  		catch (UTGBException e) {
92  			_logger.error(e);
93  			// use the default configuration
94  			master.config = new UTGBConfig();
95  		}
96  
97  		assert (master.config != null);
98  		return master.config;
99  	}
100 
101 	public static String getProjectRootFolder() throws UTGBException {
102 		String projectRootFolder = (String) getVariable("projectRoot");
103 		if (projectRootFolder == null)
104 			throw new UTGBException("not in the project root folder, or a file 'config/common.silk' is not found");
105 		return projectRootFolder;
106 	}
107 
108 	protected static UTGBConfig loadUTGBConfig() throws UTGBException {
109 
110 		// load the configuration file
111 		String projectRootFolder = getProjectRootFolder();
112 
113 		String env = (String) getVariable("environment");
114 		if (env == null) {
115 			_logger.warn("no environment (development, test, production) is specified. Use develoment.silk as a default");
116 			env = "development";
117 		}
118 		String configFile = String.format("config/%s.silk", env);
119 		;
120 		try {
121 			_logger.info(String.format("loading %s", configFile));
122 			UTGBConfig config = SilkLens.loadSilk(UTGBConfig.class, new File(projectRootFolder, configFile).toURI().toURL());
123 			return config;
124 		}
125 		catch (XerialException e) {
126 			throw new UTGBException(String.format("syntax error in %s file: %s", configFile, e.getMessage()));
127 		}
128 		catch (IOException e) {
129 			throw new UTGBException(String.format("failed to load %s: %s", configFile, e.getMessage()));
130 		}
131 	}
132 
133 	protected static String getContextProperty(String key, String defaultValue) {
134 		String value = null;
135 		try {
136 			// read the environment variable from the JNDI,
137 			// the parmeters of which are configured in META-INF/context.xml in
138 			// the Tomcat server.
139 			Context initContext = new InitialContext();
140 			Context envContext = (Context) initContext.lookup("java:comp/env");
141 			value = (String) envContext.lookup(key);
142 			System.setProperty(key, value);
143 			return value;
144 		}
145 		catch (NamingException e) {
146 			if (!RequestDispatcher.isGWTHostedMode()) {
147 				_logger.warn("error while reading an environment context: " + key + ". " + e.getMessage());
148 				_logger.warn("using the default value: " + defaultValue);
149 			}
150 			System.setProperty(key, defaultValue);
151 			return defaultValue;
152 		}
153 	}
154 
155 	public static DatabaseAccess getDatabaseAccess(String databaseID) throws UTGBException {
156 		return getInstance().getDatabaseAccessInternal(databaseID);
157 	}
158 
159 	protected DatabaseAccess getDatabaseAccessInternal(String databaseID) throws UTGBException {
160 		if (_dbAccessTable.containsKey(databaseID))
161 			return _dbAccessTable.get(databaseID);
162 
163 		String projectRootFolder = (String) getVariable("projectRoot");
164 		if (projectRootFolder == null)
165 			throw new UTGBException("not in the project root folder, or a file 'config/track-config.xml' is not found");
166 
167 		if (config == null) {
168 			config = getUTGBConfig();
169 
170 		}
171 
172 		Database dbInfo = config.getDatabase(databaseID);
173 		if (dbInfo == null)
174 			throw new UTGBException(UTGBErrorCode.DatabaseError, "no database ID " + databaseID + " was found");
175 
176 		DatabaseAccess dbAccess = JDBCService.getDatabaseAccess(projectRootFolder, dbInfo);
177 		_dbAccessTable.put(databaseID, dbAccess);
178 		return dbAccess;
179 	}
180 
181 	public void contextDestroyed(ServletContextEvent event) {
182 
183 		// dispose database connections
184 
185 		for (String key : _dbAccessTable.keySet()) {
186 			DatabaseAccess query = _dbAccessTable.get(key);
187 			if (query != null)
188 				try {
189 					// close JDBC connections
190 					query.dispose();
191 				}
192 				catch (DBException e) {
193 					_logger.warn(e);
194 				}
195 		}
196 	}
197 
198 	// @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
199 	public void contextInitialized(ServletContextEvent event) {
200 
201 		// start-up codes
202 
203 		// initialize log4j
204 		BasicConfigurator.configure();
205 
206 		setVariable("query", new HashMap<String, DatabaseAccess>());
207 		// scan resource folder
208 		String configFolderName = getContextProperty("projectRoot", new File(".").getAbsolutePath());
209 		setVariable("projectRoot", configFolderName);
210 		_logger.info("project root folder: " + configFolderName);
211 
212 		String environment = getContextProperty("environment", System.getProperty("utgb.env", "development"));
213 		setVariable("environment", environment);
214 		_logger.info("environment: " + environment);
215 
216 		loadProject();
217 	}
218 
219 	private void loadProject() {
220 		// load track config
221 		config = getUTGBConfig();
222 
223 		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
224 
225 		// load the default action package
226 		DefaultRequestMap.loadActionPackage(contextClassLoader, config.javaPackage + ".app", "");
227 
228 		// load the imported packages
229 
230 		for (WebAction each : config.webAction) {
231 			String actionPackage = each.javaPackage;
232 			String actionPrefix = each.alias;
233 
234 			_logger.info(String.format("import %s (alias = %s)", actionPackage, actionPrefix));
235 			DefaultRequestMap.loadActionPackage(contextClassLoader, actionPackage, actionPrefix);
236 		}
237 
238 		// search database resources specified in the track-config.xml
239 
240 		// search SQLite database files
241 		for (Database dbInfo : config.database) {
242 			_logger.info("-database(" + dbInfo + ")");
243 		}
244 	}
245 
246 	public static BufferedReader openServletReader(HttpServletRequest request, String path) throws ServletException, IOException {
247 		if (!path.startsWith("/"))
248 			path = "/" + path;
249 
250 		String servletURL = request.getLocalAddr() + ":" + request.getLocalPort() + request.getContextPath() + path;
251 		URL url;
252 		try {
253 			url = new URL("http://" + servletURL);
254 			return new BufferedReader(new InputStreamReader(url.openStream()));
255 		}
256 		catch (MalformedURLException e) {
257 			throw new ServletException(e);
258 		}
259 	}
260 
261 }