View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2008 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  // utgb-core Project
18  //
19  // DefaultRequestMap.java
20  // Since: 2008/08/04
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.server;
26  
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.List;
30  
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  
34  import org.xerial.util.FileResource;
35  import org.xerial.util.ResourceFilter;
36  import org.xerial.util.io.VirtualFile;
37  import org.xerial.util.log.Logger;
38  
39  /**
40   * DefaultRequestMap provides a search function to find a request handler that matches the given web request.
41   * 
42   * When the request URL is "refseq/human/hg18/list.json", and there is an action handler, refseq.list,
43   * 
44   * <li>actionHandlername = "list" <li>actionSuffix = "json" <li>actionPrefix = "refseq/human/hg18"
45   * 
46   * @author leo
47   * 
48   */
49  public class DefaultRequestMap implements RequestMap {
50  
51  	private static Logger _logger = Logger.getLogger(DefaultRequestMap.class);
52  
53  	private static HashMap<String, Class<RequestHandler>> requestHandlerTable = new HashMap<String, Class<RequestHandler>>();
54  
55  	@SuppressWarnings("unchecked")
56  	public static void loadActionPackage(ClassLoader classLoader, String packageName, String actionPrefix) {
57  		_logger.info("load action package: " + packageName + " alias=" + actionPrefix);
58  
59  		// list up all classed in the package
60  		ResourceFilter filter = new ResourceFilter() {
61  			public boolean accept(String resourcePath) {
62  				return resourcePath.endsWith(".class");
63  			}
64  		};
65  		ArrayList<Class<?>> classList = new ArrayList<Class<?>>();
66  		List<VirtualFile> javaClassFileList = FileResource.listResources(classLoader, packageName, filter);
67  		for (VirtualFile vf : javaClassFileList) {
68  			Class<?> c = getJavaClass(classLoader, vf, packageName);
69  			if (c == null)
70  				continue;
71  			classList.add(c);
72  		}
73  
74  		String prefix = (actionPrefix.length() > 0) ? actionPrefix + "." : "";
75  		// find request handlers
76  		for (Class<?> c : classList) {
77  			if (!c.isInterface() && RequestHandler.class.isAssignableFrom(c)) {
78  				String className = c.getName();
79  				_logger.trace("found a web action: " + className);
80  
81  				if (className.startsWith(packageName)) {
82  					String shortHandlerName = prefix + className.substring(packageName.length() + 1);
83  					String handlerKey = shortHandlerName.toLowerCase();
84  					if (!requestHandlerTable.containsKey(handlerKey)) {
85  						_logger.info("added web action: " + handlerKey.replaceAll("\\.", "/"));
86  						requestHandlerTable.put(handlerKey, (Class<RequestHandler>) c);
87  					}
88  				}
89  			}
90  		}
91  
92  	}
93  
94  	public static Class<?> getJavaClass(ClassLoader classLoader, VirtualFile vf, String baseJavaPackage) {
95  		String logicalPath = vf.getLogicalPath();
96  		int dot = logicalPath.lastIndexOf(".");
97  		if (dot <= 0)
98  			return null;
99  		String className = baseJavaPackage + "." + logicalPath.substring(0, dot).replaceAll("/", ".");
100 
101 		try {
102 			Class<?> c = Class.forName(className, false, classLoader);
103 			return c;
104 		}
105 		catch (ClassNotFoundException e) {
106 			_logger.error(e);
107 		}
108 		catch (UnsatisfiedLinkError e) {
109 			_logger.error(e);
110 		}
111 		catch (VerifyError e) {
112 			_logger.error(e);
113 		}
114 		catch (NoClassDefFoundError e) {
115 			_logger.error(e);
116 		}
117 		return null;
118 	}
119 
120 	protected static Class<RequestHandler> findRequestHandlerClass(String handlerName) {
121 		_logger.trace("requested handler package: " + handlerName);
122 		Class<RequestHandler> requestHandlerClass = requestHandlerTable.get(handlerName.toLowerCase());
123 		return requestHandlerClass;
124 	}
125 
126 	protected static RequestHandler findRequestHandler(String handlerName) {
127 		Class<RequestHandler> requestHandlerClass = findRequestHandlerClass(handlerName);
128 		if (requestHandlerClass == null)
129 			return null;
130 		try {
131 			return requestHandlerClass.newInstance();
132 		}
133 		catch (InstantiationException e) {
134 			_logger.error(e);
135 			return null;
136 		}
137 		catch (IllegalAccessException e) {
138 			_logger.error(e);
139 			return null;
140 		}
141 	}
142 
143 	public RequestHandler map(RequestURI requestURI, HttpServletRequest request, HttpServletResponse response) {
144 
145 		// Gets the RequestHandler of the specified name
146 		String handlerName = requestURI.getHandlerName();
147 		RequestHandler handler = findRequestHandler(handlerName);
148 		if (handler == null) {
149 			// try to find an action handler using the full handler name
150 			handler = findRequestHandler(requestURI.getFullName());
151 		}
152 
153 		if (handler != null) {
154 			_logger.trace("handler name: " + requestURI);
155 			// set prefix & suffix
156 			request.setAttribute("actionPrefix", requestURI.getPrefix());
157 			request.setAttribute("actionSuffix", requestURI.getSuffix());
158 		}
159 
160 		return handler;
161 	}
162 
163 }