// the performance?
List<DefinesRoot> reps = resRegister
.getVirtualRepositories(false);
// Sort the DefinesRoots to let the host web bundle's web
// Content root be the first be search.
WebComActivator hostBundleActivator = FwkRuntime.getInstance()
.getHostBundleActivator();
if (hostBundleActivator != null) {
for (int i = 0; i < reps.size(); i++) {
DefinesRoot root = reps.get(i);
if (hostBundleActivator.getBundle().equals(
root.getSourceBundle())) {
if (root.getResources().size() == 1) {
if (root.getResources().get(0).getPath()
.equals(
hostBundleActivator
.getWebContextPath())) {
DefinesRoot tmp = reps.get(0);
reps.set(0, root);
reps.set(i, tmp);
break;
}
}
}
}
}
boolean hostWebRootProecessed = false;
Iterator<DefinesRoot> it = reps.iterator();
while (it.hasNext()) {
DefinesRoot curResRoot = it.next();
// Buffer the context bundle to thread local variant map.
Bundle contextBundle = curResRoot.getSourceBundle();
threadScope.get().put(RESPONSE_CUR_BUNDLE, contextBundle);
// Get the resource visit controller and judge the
// authority.
IResourceVisitController controller = curResRoot
.getVisitControler();
// Buffer the current Resource Define Root to thread local
// variant map. Do not
// need to judge null.
threadScope.get().put(RESPONSE_CUR_VISIT_CTRL, controller);
if (controller == null || controller.canRead(req)) {
// Search the published resource root in a tree
// construct for the
// resource presented by the request path. The result
// will buffered into
// thread local variants map.
if (hostWebRootProecessed && !path.equals(originalPath))
searchForRes(curResRoot, originalPath);
else
searchForRes(curResRoot, path);
// Check if found a dynimic file and processed by jasper
// jsp serlvet.
if (Boolean.TRUE.equals(threadScope.get().get(
RESPONSE_DYNIMIC_FILE))) {
// Jsp file not add to found resource buffer and not
// set last modified time. This means each jsp file
// request will do a new search.
return;
}
// Check if need to update to client by the thread local
// mark RES_NO_MODIFIED. The mark was set during search
// process. If true, no need to consider the found
// RESPONSE_INPUT variant, coz it's null in this case.
if (Boolean.TRUE.equals(threadScope.get().get(
RES_NO_MODIFIED))) {
// Also need to set Response Mime Type if
// RES_NO_MODIFIED status.
String findFileName = originalPath;
if (findFileName != null) {
ServletContext ctx = FwkRuntime.getInstance()
.getWebContainer().findServletContext(
contextBundle);
// Set cache header again.
maybeSetCacheHeaders(resp);
resp.setContentType(ctx
.getMimeType(findFileName));
resp
.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
}
// If the response content returned in a input stream,
// write it to HttpResponse. Otherwise, the resource
// cann't be found and sent CANCEL status.
InputStream resSrcInput = (InputStream) threadScope
.get().get(RESPONSE_INPUT);
if (resSrcInput != null) {
// Set MIME type before write data.
// Set mine type of http head according to the file
// name found.
// Check if found a directory and its sub resource
// be reported as a string.
if (Boolean.TRUE.equals(threadScope.get().get(
RESPONSE_IS_FOLDER))) {
resp.setContentType(FOLDER_CONTENT_TYPE
+ ";charset=" + TEXT_CHARSET);
} else {
String findFileName = (String) threadScope
.get().get(STATIC_FILE_NAME);
if (findFileName != null) {
ServletContext ctx = FwkRuntime
.getInstance().getWebContainer()
.findServletContext(contextBundle);
resp.setContentType(ctx
.getMimeType(findFileName));
}
}
try {
// Set the last modified response head. This
// method should be done before the response be
// write out.
maybeSetCacheHeaders(resp);
int availableByteCount = resSrcInput
.available();
if (availableByteCount > 0) {
try {
ServletOutputStream output = resp
.getOutputStream();
while ((availableByteCount = resSrcInput
.available()) > 0) {
byte[] data = new byte[availableByteCount];
resSrcInput.read(data);
output.write(data);
}
} catch (IOException e) {
// If client abort, Socket Reset
// Exception
// ocurres and ingore
// it.
// e.printStackTrace();
}
} else {
resp
.setStatus(HttpServletResponse.SC_NO_CONTENT);
// FIXME: If folder or file empty, here
// write a NULL char to client ,this may
// cause some exception.
// if
// (Boolean.TRUE.equals(threadScope.get().get(RESPONSE_IS_FOLDER)))
// resp.getWriter().write(0);
resp.setContentLength(0);
}
} finally {
resSrcInput.close();
resSrcInput = null;
}
return;
} else {
// If result inputstream is null because the found
// folder not allowed to
// browse. Return 404 error status.
Boolean isForbbidenBrowsingFolder = (Boolean) threadScope
.get().get(RESPONSE_IS_FOLDER);
if (isForbbidenBrowsingFolder) {
// Send the 404 status
resp
.sendError(
HttpServletResponseWrapper.SC_UNAUTHORIZED,
"not found resource for path:"
+ req.getRequestURI());
return;
}
}
}
hostWebRootProecessed = true;
}
}
// Search all WebComponent's ServletContext by call its
// getResource(path)
Collection<ComActivator> activators = FwkRuntime.getInstance()
.getAllComponentActivators();
for (Iterator<ComActivator> it = activators.iterator(); it
.hasNext();) {
ComActivator activator = it.next();
if (!(activator instanceof WebResComActivator)
&& activator instanceof WebComActivator) {
WebComActivator webComActivator = ((WebComActivator) activator);
String resPath = originalPath;
if (originalPath.startsWith("/"
+ webComActivator.getServiceNSPrefix() + "/")) {
// No need to remove the current web bundle's prefix,
// BundledServletContext
// will do it for us. And the processDynimicFile()
// method also need this
// prefix to identifing the jsp file.