Process the request

@param requestedPath
the requested path
@param request
the request
@param response
the response
@param bundleHashcodeType
the bundle hashcode type
@throws IOException
if an IOException occurs
438029
@Override
	protected void processRequest(String requestedPath, HttpServletRequest request, HttpServletResponse response,
			BundleHashcodeType bundleHashcodeType) throws IOException {

		boolean responseHeaderWritten = false;
		boolean validBundle = true;
		if (!jawrConfig.isDebugModeOn() && jawrConfig.isStrictMode()
				&& bundleHashcodeType.equals(BundleHashcodeType.INVALID_HASHCODE)) {
			validBundle = false;
		}

		// If debug mode is off, check for If-Modified-Since and
		// If-none-match headers and set response caching headers.
		if (!this.jawrConfig.isDebugModeOn()) {
			// If a browser checks for changes, always respond 'no changes'.
			if (validBundle && (null != request.getHeader(IF_MODIFIED_SINCE_HEADER)
					|| null != request.getHeader(IF_NONE_MATCH_HEADER))) {
				response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
				if (LOGGER.isDebugEnabled())
					LOGGER.debug("Returning 'not modified' header. ");
				return;
			}

			if (validBundle) {
				// Add caching headers
				setResponseHeaders(response);
			} else {

				responseHeaderWritten = illegalBundleRequestHandler.writeResponseHeader(requestedPath, request,
						response);
				if (!responseHeaderWritten) {
					// Add caching headers
					setResponseHeaders(response);
				}
			}
		}

		// Returns the real file path
		String filePath = getRealFilePath(requestedPath, bundleHashcodeType);

		try {
			if (isValidRequestedPath(filePath)
					&& (validBundle || illegalBundleRequestHandler.canWriteContent(requestedPath, request))) {

				// Set the content type
				response.setContentType(getContentType(requestedPath, request));
				writeContent(filePath, request, response);

			} else {
				if (!responseHeaderWritten) {
					LOGGER.error("Unable to load the image for the request URI : " + request.getRequestURI());
					response.sendError(HttpServletResponse.SC_NOT_FOUND);
				}
			}
		} catch (EOFException eofex) {
			LOGGER.info("Browser cut off response", eofex);
		} catch (ResourceNotFoundException e) {
			LOGGER.info("Unable to write resource " + request.getRequestURI(), e);
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
		} catch (IOException ex) {
			LOGGER.error("Unable to write resource " + request.getRequestURI(), ex);
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
		}

		if (LOGGER.isDebugEnabled())
			LOGGER.debug("request succesfully attended");
	}
456261
@Override
	protected StringBuffer doPostProcessBundle(BundleProcessingStatus status, StringBuffer bundleData)
			throws IOException {
		LOGGER.info("Post processing file '" + status.getLastPathAdded() + "'");

		String bundleMediaTypePropertyName = "jawr.css.bundle." + status.getCurrentBundle().getName() + ".media";
		JawrConfig config = status.getJawrConfig();
		String bundleMediaType = (String) config.getProperty(bundleMediaTypePropertyName);
		if (bundleMediaType == null) {
			LOGGER.warn("no bundle media type provided; use 'screen'");
			bundleMediaType = "screen";
		}

		LOGGER.info("bundle media type: " + bundleMediaType);

		StringBuffer sb = new StringBuffer(
				CSS_MEDIA_RULE + " " + bundleMediaType + " " + CSS_MEDIA_RULE_OPEN + StringUtils.STR_LINE_FEED);
		sb.append(bundleData);
		sb.append(CSS_MEDIA_RULE_CLOSE + StringUtils.STR_LINE_FEED + StringUtils.STR_LINE_FEED);

		LOGGER.info("Postprocessing finished");
		return sb;
	}
838992
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        String url = this.getURL(req);

        LOGGER.debug("Started processing request : {}", url);

        List<String> resourcesToMerge = findResourcesToMerge(req.getContextPath(), url);
        String extensionOrPath = detectExtension(url);//in case of non js/css files it null
        if (extensionOrPath.isEmpty()) {
            extensionOrPath = resourcesToMerge.get(0);//non grouped i.e. non css/js file, we refer it's path in that case
        }

        //If not modified, return 304 and stop
        ResourceStatus status = JSCSSMergeServlet.isNotModified(this.getServletContext(), req, resourcesToMerge, this.turnOffETag);
        if (status.isNotModified()) {
            LOGGER.trace("Resources Not Modified. Sending 304.");
            String ETag = !this.turnOffETag ? status.getActualETag() : null;
            JSCSSMergeServlet.sendNotModified(resp, extensionOrPath, ETag, this.expiresMinutes, this.cacheControl, this.overrideExistingHeaders);
            return;
        }


        //Add appropriate headers
        this.addAppropriateResponseHeaders(extensionOrPath, resourcesToMerge, status.getActualETag(), resp);

        OutputStream outputStream = resp.getOutputStream();
        String contextPathForCss = customContextPathForCSSUrls != null ?
                customContextPathForCSSUrls : req.getContextPath();
        ProcessedResult processedResult = this.processResources(contextPathForCss, outputStream, resourcesToMerge);
        int resourcesNotFound = processedResult.getNumberOfMissingResources();

        if (resourcesNotFound > 0 && resourcesNotFound == resourcesToMerge.size()) { //all resources not found
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            LOGGER.warn("All resources are not found. Sending 404.");
            return;
        }
        if (outputStream != null) {
            try {
                resp.setStatus(HttpServletResponse.SC_OK);
                outputStream.close();
            } catch (Exception e) {
                // ignore
            }
        }
        resp.setHeader("Content-Length", String.valueOf(processedResult.contentLength));
        LOGGER.debug("Finished processing Request : {}", url);
    }
446541
private void respondWithFile(ChannelHandlerContext ctx, HttpRequest request, String requestPath)
		throws IOException, ParseException {

		// make sure we request the "index.html" in case there is a directory request
		if (requestPath.endsWith("/")) {
			requestPath = requestPath + "index.html";
		}

		if (!requestPath.contains(".")) { // we assume that the path ends in either .html or .js
			requestPath = requestPath + ".json";
		}

		// convert to absolute path
		final File file = new File(rootPath, requestPath);

		if (!file.exists()) {
			// file does not exist. Try to load it with the classloader
			ClassLoader cl = HistoryServerStaticFileServerHandler.class.getClassLoader();

			try (InputStream resourceStream = cl.getResourceAsStream("web" + requestPath)) {
				boolean success = false;
				try {
					if (resourceStream != null) {
						URL root = cl.getResource("web");
						URL requested = cl.getResource("web" + requestPath);

						if (root != null && requested != null) {
							URI rootURI = new URI(root.getPath()).normalize();
							URI requestedURI = new URI(requested.getPath()).normalize();

							// Check that we don't load anything from outside of the
							// expected scope.
							if (!rootURI.relativize(requestedURI).equals(requestedURI)) {
								LOG.debug("Loading missing file from classloader: {}", requestPath);
								// ensure that directory to file exists.
								file.getParentFile().mkdirs();
								Files.copy(resourceStream, file.toPath());

								success = true;
							}
						}
					}
				} catch (Throwable t) {
					LOG.error("error while responding", t);
				} finally {
					if (!success) {
						LOG.debug("Unable to load requested file {} from classloader", requestPath);
						HandlerUtils.sendErrorResponse(
							ctx,
							request,
							new ErrorResponseBody("File not found."),
							NOT_FOUND,
							Collections.emptyMap());
						return;
					}
				}
			}
		}

		if (!file.exists() || file.isHidden() || file.isDirectory() || !file.isFile()) {
			HandlerUtils.sendErrorResponse(
				ctx,
				request,
				new ErrorResponseBody("File not found."),
				NOT_FOUND,
				Collections.emptyMap());
			return;
		}

		if (!file.getCanonicalFile().toPath().startsWith(rootPath.toPath())) {
			HandlerUtils.sendErrorResponse(
				ctx,
				request,
				new ErrorResponseBody("File not found."),
				NOT_FOUND,
				Collections.emptyMap());
			return;
		}

		// cache validation
		final String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE);
		if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
			SimpleDateFormat dateFormatter = new SimpleDateFormat(StaticFileServerHandler.HTTP_DATE_FORMAT, Locale.US);
			Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);

			// Only compare up to the second because the datetime format we send to the client
			// does not have milliseconds
			long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
			long fileLastModifiedSeconds = file.lastModified() / 1000;
			if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
				if (LOG.isDebugEnabled()) {
					LOG.debug("Responding 'NOT MODIFIED' for file '" + file.getAbsolutePath() + '\'');
				}

				StaticFileServerHandler.sendNotModified(ctx);
				return;
			}
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("Responding with file '" + file.getAbsolutePath() + '\'');
		}

		// Don't need to close this manually. Netty's DefaultFileRegion will take care of it.
		final RandomAccessFile raf;
		try {
			raf = new RandomAccessFile(file, "r");
		} catch (FileNotFoundException e) {
			HandlerUtils.sendErrorResponse(
				ctx,
				request,
				new ErrorResponseBody("File not found."),
				NOT_FOUND,
				Collections.emptyMap());
			return;
		}

		try {
			long fileLength = raf.length();

			HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
			StaticFileServerHandler.setContentTypeHeader(response, file);

			// the job overview should be updated as soon as possible
			if (!requestPath.equals("/joboverview.json")) {
				StaticFileServerHandler.setDateAndCacheHeaders(response, file);
			}
			if (HttpHeaders.isKeepAlive(request)) {
				response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
			}
			HttpHeaders.setContentLength(response, fileLength);

			// write the initial line and the header.
			ctx.write(response);

			// write the content.
			ChannelFuture lastContentFuture;
			if (ctx.pipeline().get(SslHandler.class) == null) {
				ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
				lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
			} else {
				lastContentFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)),
					ctx.newProgressivePromise());
				// HttpChunkedInput will write the end marker (LastHttpContent) for us.
			}

			// close the connection, if no keep-alive is needed
			if (!HttpHeaders.isKeepAlive(request)) {
				lastContentFuture.addListener(ChannelFutureListener.CLOSE);
			}
		} catch (Exception e) {
			raf.close();
			LOG.error("Failed to serve file.", e);
			HandlerUtils.sendErrorResponse(
				ctx,
				request,
				new ErrorResponseBody("Internal server error."),
				INTERNAL_SERVER_ERROR,
				Collections.emptyMap());
		}
	}
1180832
public String processHTTPAPIRequest(
			String urlString,
			JSONObject request,
			GenericUser authenticationUser,
			String requestType, 
			String[] requestParameters,
			String... requestHedaers) throws CertificateException, IOException, JSONException {
		
		log.debug("API request: " + request.toString(4));
		String jsonRequest = request.toString();
		
		HttpURLConnection ucon = null;
		
		if("POST".equals(requestType)) {
			
			URL url = new URL(urlString);		
			log.debug("API request: " + url);
			
			ucon = (HttpURLConnection) url.openConnection();

			ucon.setRequestMethod("POST");
			ucon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
						
			setRequestHeaders(ucon, authenticationUser, requestHedaers);
				
			for(int i = 0 ; i < requestParameters.length; i = i + 2) {
				ucon.setRequestProperty(getReferenceService().namespaceString(requestParameters[i]), getReferenceService().namespaceString(requestParameters[i+1]));
			}
			
			ucon.setUseCaches (false);
			ucon.setDoInput(true);
			ucon.setDoOutput(true);

		    //Send request
			String encodedPostRequest = "json=" + URLEncoder.encode(jsonRequest, "UTF-8");
			ucon.setRequestProperty("Content-Length", Integer.toString(encodedPostRequest.getBytes().length));
		    DataOutputStream wr = new DataOutputStream (ucon.getOutputStream ());
			wr.writeBytes(encodedPostRequest);
		    wr.flush ();
		    wr.close ();
		}
		else if ("GET".equals(requestType)) {
			log.debug("API request: " + request.toString());
			
			
			StringBuilder builder = new StringBuilder();
			builder.append(urlString + "?json=" + URLEncoder.encode(request.toString(), "UTF-8").replaceAll("\"", "%22"));
			for(int i = 0 ; i < requestParameters.length; i = i + 2) {
				builder.append("&" + getReferenceService().namespaceString(requestParameters[i]) + "=" + getReferenceService().namespaceString(requestParameters[i+1]));
			}
			
			URL url = new URL(builder.toString());		
			log.debug("API request: " + url);

			ucon = (HttpURLConnection) url.openConnection();
			setRequestHeaders(ucon, authenticationUser, requestHedaers);
			
			ucon.setConnectTimeout(5000);
			ucon.setFollowRedirects(true);
			ucon.setDoOutput(true);
		}
		else {
			throw new IllegalArgumentException("Only POST and GET API requests are supported at this stage");
		}

		
		//Obtain the response
		StringBuilder responseBuilder = new StringBuilder();
		try{			
			InputStream inputStream = ucon.getInputStream();
			
			BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
			String pre = null;                       
			while ((pre = in.readLine()) != null){
				responseBuilder.append(pre);
				responseBuilder.append("\n");
			}
			in.close();
		}
		catch (IOException e) {
			//on error codes we should not fail but just capture the response code
			log.debug("Genarating the API call response caused: ", e);
		}
		String response = responseBuilder.toString();
		
		log.debug("The generated API call response: " + response);
		
		getScenarioGlobals().setAttribute(LAST_SCENARIO_HTTP_RESPONSE_CODE_KEY, ucon.getResponseCode());
		
		return response;
	}
1107248
public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpServletRequest = WebFilter.request.get();
		
		try {
			WebFilter.request.set((HttpServletRequest) request);
			chain.doFilter(request, response);
		} finally {
			WebFilter.request.set(httpServletRequest);
		}
	}
912192
protected void doRequest (HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException
    {
        InvocationContext context = null;
        try {
            context =  new InvocationContext(request, response);
            setContentType(request, response);

            Template template = handleRequest(request, response, context);
            if (template != null) {
                mergeTemplate(template, context);
            }

        } catch (Exception e) {
            log.warning("doRequest failed", "uri", request.getRequestURI(), e);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }
78432
public BundleHashcodeType getBundleHashcodeType(String requestedPath) {

		if (binaryResourcePathMap.containsValue(requestedPath)) {
			return BundleHashcodeType.VALID_HASHCODE;
		}

		BundleHashcodeType bundleHashcodeType = BundleHashcodeType.UNKNOW_BUNDLE;
		String[] resourceInfo = PathNormalizer.extractBinaryResourceInfo(requestedPath);
		String binaryRequest = resourceInfo[0];
		if (resourceInfo[1] != null) { // an hashcode is defined in the path
			try {
				String cacheBustedPath = CheckSumUtils.getCacheBustedUrl(binaryRequest, getRsReaderHandler(),
						jawrConfig);
				addMapping(binaryRequest, cacheBustedPath);

				if (requestedPath.equals(cacheBustedPath)) {
					bundleHashcodeType = BundleHashcodeType.VALID_HASHCODE;
				} else {
					bundleHashcodeType = BundleHashcodeType.INVALID_HASHCODE;
				}
			} catch (IOException | ResourceNotFoundException e) {
				// Nothing to do
			}

		}
		return bundleHashcodeType;
	}
1195818
@Override
	public void setBundleDataHashCode(String variantKey, String bundleDataHashCode) {

		String prefix = bundleDataHashCode;

		if (StringUtils.isEmpty(variantKey)) {
			this.urlPrefix = prefix;
		} else {
			prefixMap.put(variantKey, prefix);
		}
	}
943525
@Override
	public void writeBundleTo(String bundlePath, Writer writer) throws ResourceNotFoundException {

		Reader rd = null;

		try {

			// If debug mode is on, resources are retrieved one by one.
			if (config.isDebugModeOn()) {

				rd = resourceHandler.getResource(null, bundlePath);
			} else {

				for (String prefix : bundlePrefixes) {
					if (bundlePath.startsWith(prefix)) {
						bundlePath = bundlePath.substring(prefix.length());
						break;
					}
				}

				// Prefixes are used only in production mode
				String path = PathNormalizer.removeVariantPrefixFromPath(bundlePath);
				rd = resourceBundleHandler.getResourceBundleReader(path);
				if (liveProcessBundles.contains(path)) {
					rd = processInLive(rd);
				}
			}

			IOUtils.copy(rd, writer);
			writer.flush();
		} catch (IOException e) {
			throw new BundlingProcessException("Unexpected IOException writing bundle[" + bundlePath + "]", e);
		} finally {
			IOUtils.close(rd);
			IOUtils.close(writer);
		}
	}
650030
@Override
	public void renderBundleLinks(String requestedPath, BundleRendererContext ctx, Writer out) throws IOException {

		boolean debugOn = bundler.getConfig().isDebugModeOn();
		JoinableResourceBundle bundle = bundler.resolveBundleForPath(requestedPath);

		if (null == bundle) {

			LOGGER.warn("No bundle found for path : " + requestedPath);
			return;
		}

		// If the global bundles had been added before, it will not be included
		// again.
		if (!ctx.isGlobalBundleAdded()) {
			renderGlobalBundleLinks(ctx, out, debugOn);
		}

		renderBundleLinks(bundle, requestedPath, ctx, out, debugOn, true);

		if (debugOn) {
			addComment("Finished adding members resolved by " + requestedPath, out);
		}
	}
939490
@Override
	protected StringBuffer doPostProcessBundle(BundleProcessingStatus status, StringBuffer bundleData)
			throws IOException {
		return customPostProcessor.postProcessBundle(status, bundleData);
	}
416720
@Override
	public void processBundles(GlobalPreprocessingContext ctx, List<JoinableResourceBundle> bundles) {

		ResourceReaderHandler rsHandler = ctx.getRsReaderHandler();

		Set<String> resourcePaths = getResourcePaths(bundles);
		JawrConfig jawrConfig = ctx.getJawrConfig();
		Charset charset = jawrConfig.getResourceCharset();

		BinaryResourcesHandler binaryRsHandler = (BinaryResourcesHandler) jawrConfig.getContext()
				.getAttribute(JawrConstant.BINARY_CONTEXT_ATTRIBUTE);

		generateSprites(rsHandler, binaryRsHandler, resourcePaths, jawrConfig, charset);

		// Update CSS resource handler
		CssSmartSpritesResourceReader cssSpriteResourceReader = new CssSmartSpritesResourceReader(
				rsHandler.getWorkingDirectory(), jawrConfig);

		updateBundlesDirtyState(bundles, cssSpriteResourceReader);

		ctx.getRsReaderHandler().addResourceReader(cssSpriteResourceReader);

		// Update image resource handler
		ResourceReaderHandler imgStreamRsHandler = binaryRsHandler.getRsReaderHandler();
		imgStreamRsHandler.addResourceReader(cssSpriteResourceReader);
	}
340046
@Override
	public void writeBundleTo(String bundlePath, Writer writer) throws ResourceNotFoundException {
		
		String text = (String) cacheMgr.get(TEXT_CACHE_PREFIX + bundlePath);
		try {
			// If it's not cached yet
			if (null == text) {
				String charsetName = rsHandler.getConfig().getResourceCharset().name();
				ByteArrayOutputStream baOs = new ByteArrayOutputStream();
				WritableByteChannel wrChannel = Channels.newChannel(baOs);
				Writer tempWriter = Channels.newWriter(wrChannel, charsetName);
				rsHandler.writeBundleTo(bundlePath, tempWriter);
				text = baOs.toString(charsetName);
				cacheMgr.put(TEXT_CACHE_PREFIX + bundlePath, text);
			}

			// Write the text to the outputstream
			writer.write(text);
			writer.flush();

		} catch (IOException e) {
			throw new BundlingProcessException("Unexpected IOException writing bundle[" + bundlePath + "]", e);
		}finally {
			IOUtils.close(writer);
		}
	}
455160
void processServerContentRequest() {

        File installRoot = new File(locationService.resolveString("${wlp.install.dir}"));

        final Set<String> absPathsForLibertyContent = new HashSet<String>();
        final Map<String, List<String>> specificPlatformPathsByPlatform = new HashMap<String, List<String>>();
        Set<String> discoveredFeatures = new HashSet<String>();
        Collection<FeatureResource> fixes = new ArrayList<FeatureResource>();

        // We need ALL Kernel features (even the ones that aren't active in the system)
        // as well as all installed features.
        List<ProvisioningFeatureDefinition> allFeatureDefs = new ArrayList<ProvisioningFeatureDefinition>();
        allFeatureDefs.addAll(KernelFeatureDefinitionImpl.getAllKernelFeatures(bundleContext, locationService));
        allFeatureDefs.addAll(featureResolver.getInstalledFeatureDefinitions());

        //keep a list of product extensions being used in the server
        List<String> extensionRepos = new ArrayList<String>();

        for (ProvisioningFeatureDefinition fd : allFeatureDefs) {

            BundleRepositoryHolder brh = BundleRepositoryRegistry.getRepositoryHolder(fd.getBundleRepositoryType());
            ContentBasedLocalBundleRepository br = brh.getBundleRepository();
            Collection<FeatureResource> frs = fd.getConstituents(null);

            /*
             * lib/fixes processing needs to happen here, to filter the xml down to just the current in use set.
             * made slightly more complex, because the locations tracked for minify are absolute, so we have to identify and trim installroot
             * to identify lib/fixes/* content, which we process afterward
             */
            File libFixes = new File(installRoot, "lib/fixes");

            for (FeatureResource fr : frs) {
                switch (fr.getType()) {
                    case FEATURE_TYPE: {
                        //type = feature, no paths to worry about, we are processing the list of all installed features
                        //                which will include nested features.
                        discoveredFeatures.add(fr.getSymbolicName());
                        break;
                    }

                    case BUNDLE_TYPE:
                    case JAR_TYPE:
                    case BOOT_JAR_TYPE: {
                        //type = bundle, need to query the bundle repository for this feature def, to find which
                        //               files are being used.
                        //type = jar, basically same as type=bundle.. for minify purposes.
                        //type = boot.jar, basically same as type=bundle.. for minify purposes.
                        File b = br.selectBundle(fr.getLocation(), fr.getSymbolicName(), fr.getVersionRange());
                        File bb = br.selectBaseBundle(fr.getLocation(), fr.getSymbolicName(), fr.getVersionRange());
                        //b & bb will be the same bundle if the base was the selected.. 
                        if (b != null && bb != null) {
                            boolean pathsSame = b.getAbsolutePath().equals(bb.getAbsolutePath());
                            absPathsForLibertyContent.add(b.getAbsolutePath());
                            if (!pathsSame) {
                                absPathsForLibertyContent.add(bb.getAbsolutePath());
                            }
                            List<String> osList = fr.getOsList();
                            if (osList != null) {
                                for (String os : osList) {
                                    List<String> pathsForOs = specificPlatformPathsByPlatform.get(os);
                                    if (pathsForOs == null) {
                                        pathsForOs = new ArrayList<String>();
                                        specificPlatformPathsByPlatform.put(os, pathsForOs);
                                    }
                                    pathsForOs.add(b.getAbsolutePath());
                                    if (!pathsSame) {
                                        pathsForOs.add(bb.getAbsolutePath());
                                    }
                                }
                            }
                        } else {
                            //b & bb were null, we have no match for this resource.. 
                            //maybe the resource was minfiied out?
                            List<String> osList = fr.getOsList();
                            if (osList != null) {
                                //ignore the missing resource, as the file is tagged for specific os's,
                                //and will be reported missing based on the os filters later.
                                //(if the user has no os filter set, they meant 'all currently supported by the install')
                                //(so this can still be ignored).
                            } else {
                                //use match string for error message, it provides best chance for being helpful.
                                Tr.warning(tc, "ERROR_MISSING_FEATURE_RESOURCE", new Object[] { fd.getFeatureName(), fr.getMatchString() });
                            }
                        }
                        break;
                    }

                    case FILE_TYPE: {
                        //file uses loc as a relative path from install root.
                        String locString = fr.getLocation();
                        if (locString != null) {
                            String[] locs;
                            if (locString.contains(",")) {
                                locs = locString.split(",");
                            } else {
                                locs = new String[] { locString };
                            }

                            for (String loc : locs) {
                                File test = new File(loc);
                                if (!test.isAbsolute()) {
                                    test = new File(brh.getInstallDir(), loc);
                                }
                                loc = test.getAbsolutePath();
                                //filter fixes content into the fixes set, all other content is remembered.
                                if (loc.startsWith(libFixes.getAbsolutePath() + File.separator)) {
                                    fixes.add(fr);
                                } else {
                                    absPathsForLibertyContent.add(loc);
                                }

                                List<String> osList = fr.getOsList();
                                if (osList != null) {
                                    for (String os : osList) {
                                        List<String> pathsForOs = specificPlatformPathsByPlatform.get(os);
                                        if (pathsForOs == null) {
                                            pathsForOs = new ArrayList<String>();
                                            specificPlatformPathsByPlatform.put(os, pathsForOs);
                                        }
                                        pathsForOs.add(loc);
                                    }
                                }
                            }
                        } else {
                            //a file type without a loc is bad, means misuse of the type.
                            Tr.warning(tc, "ERROR_UNKNOWN_FEATURE_RESOURCE_TYPE", new Object[] { fd.getFeatureName(), fr.getSymbolicName(), "file" });
                        }
                        break;
                    }

                    case UNKNOWN: {
                        //if its not jar,bundle,feature, or file.. then something is wrong.
                        Tr.warning(tc, "ERROR_UNKNOWN_FEATURE_RESOURCE_TYPE", new Object[] { fd.getFeatureName(),
                                                                                            fr.getSymbolicName(),
                                                                                            fr.getRawType() });
                        //we assume that other types will use the location field as something useful.
                        String loc = fr.getLocation();
                        if (loc != null) {
                            File test = new File(loc);
                            if (!test.isAbsolute()) {
                                test = new File(installRoot, loc);
                            }
                            absPathsForLibertyContent.add(test.getAbsolutePath());

                            List<String> osList = fr.getOsList();
                            if (osList != null) {
                                for (String os : osList) {
                                    List<String> pathsForOs = specificPlatformPathsByPlatform.get(os);
                                    if (pathsForOs == null) {
                                        pathsForOs = new ArrayList<String>();
                                        specificPlatformPathsByPlatform.put(os, pathsForOs);
                                    }
                                    pathsForOs.add(test.getAbsolutePath());
                                }
                            }
                        }
                        break;
                    }
                    default:
                        break;
                }
            }
            //add in (all) the NLS files for this featuredef.. if any..
            for (File nls : fd.getLocalizationFiles()) {
                if (nls.exists()) {
                    absPathsForLibertyContent.add(nls.getAbsolutePath());
                }
            }

            //add in the manifest for the feature itself .. 
            File featureFile = fd.getFeatureDefinitionFile();
            if (featureFile != null) {
                absPathsForLibertyContent.add(featureFile.getAbsolutePath());
            }
            File checksumFile = fd.getFeatureChecksumFile();
            if (checksumFile != null) {
                absPathsForLibertyContent.add(checksumFile.getAbsolutePath());
            }

            String repoType = fd.getBundleRepositoryType();
            //work out if this content is a product extension and if it is include its properties file
            if (repoType != null && !ExtensionConstants.CORE_EXTENSION.equals(repoType)
                && !ExtensionConstants.USER_EXTENSION.equals(repoType)) {
                //not core or user, must be a product extension
                extensionRepos.add(repoType);
            }

            // Add in any Icon files
            File featureDefinitionFile = fd.getFeatureDefinitionFile();
            if (featureDefinitionFile != null) {
                File featureDefinitionParent = featureDefinitionFile.getParentFile();
                Collection<String> expectedIcons = fd.getIcons();
                if (featureDefinitionParent != null && expectedIcons != null) {
                    File iconsFolder = new File(featureDefinitionParent, "icons/" + fd.getSymbolicName());
                    scanFolderForIcons(absPathsForLibertyContent, iconsFolder.getAbsolutePath(), iconsFolder, expectedIcons);
                }
            }

        }

        //if there are any extensions in use we need to bring their wlp/etc/extensions/*.properties file along
        for (String extensionRepo : extensionRepos) {
            WsResource extensionProperties = locationService.getRuntimeResource("etc/extensions/" + extensionRepo + ".properties");
            absPathsForLibertyContent.add(locationService.resolveResource(extensionProperties.toRepositoryPath()).asFile().getAbsolutePath());
        }

        //this odd looking bit of code will take the current list of files identified,
        //and if any are jars, will look in them to see if they have manifest classpaths
        //if so, the jars referenced by the manifest classpaths are added to the manifestJars
        //argument.
        //We have to start by passing both args as the current set of content (but using different set instances).
        Set<String> manifestJars = new HashSet<String>();
        manifestJars.addAll(absPathsForLibertyContent);
        gatherManifestClasspathJars(absPathsForLibertyContent, manifestJars);
        manifestJars.removeAll(absPathsForLibertyContent);

        //now manifestJars contains any jars that we didn't already know about, discovered via manifests.
        absPathsForLibertyContent.addAll(manifestJars);

        //process the fixes set of fix xml's, and add the required ones to the set of files to keep.
        addRequiredFixFiles(installRoot, absPathsForLibertyContent, fixes);

        final String OS_REMOVE_CHAR = "-";

        //publish the service that will be used by the launcher to read back the data.
        final Dictionary<String, Object> d = new Hashtable<String, Object>();
        final String[] pathArray = absPathsForLibertyContent.toArray(new String[] {});

        bundleContext.registerService(ServerContent.class, new ServerContent() {
            @Override
            public String[] getServerContentPaths(String osRequest) throws IOException {
                if (osRequest == null || osRequest.isEmpty() || "all".equals(osRequest))
                    return pathArray;
                else {
                    //filter paths as required.. then return them..                                       
                    String[] osNames = osRequest.split(",");
                    boolean add = true;

                    //check if this is an add, or a remove.
                    //if both are specified, remove wins ;p
                    for (String osName : osNames) {
                        if (osName.startsWith(OS_REMOVE_CHAR)) {
                            add = false;
                        }
                    }

                    if (add) {
                        //someone has named an os (or os's) they want
                        //so we remove everything, and add back just those os's.
                        for (Map.Entry<String, List<String>> me : specificPlatformPathsByPlatform.entrySet()) {
                            absPathsForLibertyContent.removeAll(me.getValue());
                        }
                        for (String osName : osNames) {
                            if (!osName.startsWith(OS_REMOVE_CHAR)) {
                                List<String> osPaths = specificPlatformPathsByPlatform.get(osName);
                                if (osPaths != null && !osPaths.isEmpty()) {
                                    absPathsForLibertyContent.addAll(osPaths);

                                    //verify the requested paths File.exists .. otherwise 
                                    //this could be an error ?
                                    for (String osPath : osPaths) {
                                        if (!FileUtils.fileExists(new File(osPath))) {
                                            throw new FileNotFoundException(osPath);
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        //user request 'all except this platform' type filter..
                        for (String osName : osNames) {
                            if (osName.startsWith(OS_REMOVE_CHAR)) {
                                osName = osName.substring(1);
                                List<String> osPaths = specificPlatformPathsByPlatform.get(osName);
                                if (osPaths != null && !osPaths.isEmpty()) {
                                    absPathsForLibertyContent.removeAll(osPaths);
                                    //in this kind of filter, we don't need to test at all.
                                }
                            } else {
                                List<String> osPaths = specificPlatformPathsByPlatform.get(osName);
                                if (osPaths != null && !osPaths.isEmpty()) {
                                    //verify the requested paths File.exists .. otherwise 
                                    //this could be an error.
                                    for (String osPath : osPaths) {
                                        if (!FileUtils.fileExists(new File(osPath))) {
                                            throw new FileNotFoundException(osPath);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //return newly filtered data
                    return absPathsForLibertyContent.toArray(new String[] {});
                }
            }
        }, d);

        //we're done here.. let liberty proceed to declare itself 'started' =)
    }
1291618
@Override
	public BundleHashcodeType getBundleHashcodeType(String requestedPath) {

		BundleHashcodeType typeBundleHashcode = BundleHashcodeType.UNKNOW_BUNDLE;

		String[] pathInfos = PathNormalizer.extractBundleInfoFromPath(requestedPath, bundlePrefixes);

		if (pathInfos != null) {
			String bundlePrefix = pathInfos[0];

			String bundleId = pathInfos[1];
			String variantKey = pathInfos[2];
			String hashcode = pathInfos[3];

			JoinableResourceBundle bundle = resolveBundleForPath(bundleId);
			if (bundle != null) {
				String bundleHashcode = bundle.getBundleDataHashCode(variantKey);
				if (hashcode == null && bundleHashcode == null || hashcode != null && hashcode.equals(bundleHashcode)
						&& ((bundlePrefix == null && bundle.getBundlePrefix() == null)
								|| (bundlePrefix != null && bundlePrefix.equals(bundle.getBundlePrefix())))) {
					typeBundleHashcode = BundleHashcodeType.VALID_HASHCODE;
				} else {
					typeBundleHashcode = BundleHashcodeType.INVALID_HASHCODE;
				}
			}
		}
		return typeBundleHashcode;
	}
389694
public static void writeClassPathResource(HttpServletResponse response, String path, String contentType) throws IOException
	{
		if (path.startsWith("/"))
		{
			path = path.substring(1);
		}

//		System.out.println(new LogEntry("trying to retrieve " + path + " from classloader");
		InputStream input = ServletSupport.class.getClassLoader().getResourceAsStream(path);
		if (input != null)
		{
			response.setContentType(contentType);
			OutputStream out = response.getOutputStream();
			int available = input.available();
			while (available > 0)
			{
				byte[] buf = new byte[available];
				input.read(buf);
				out.write(buf);
				available = input.available();
			}
		}
		else
		{
			System.out.println(new LogEntry("resource " + path + " not found"));
		}
	}