All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.dirigible.engine.web.service.AbstractWebEngineRestService Maven / Gradle / Ivy

There is a newer version: 7.2.0
Show newest version
/*
 * Copyright (c) 2022 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.dirigible.engine.web.service;

import java.nio.charset.StandardCharsets;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.eclipse.dirigible.commons.api.helpers.ContentTypeHelper;
import org.eclipse.dirigible.commons.api.service.AbstractRestService;
import org.eclipse.dirigible.commons.api.service.IRestService;
import org.eclipse.dirigible.commons.config.Configuration;
import org.eclipse.dirigible.commons.config.ResourcesCache;
import org.eclipse.dirigible.commons.config.ResourcesCache.Cache;
import org.eclipse.dirigible.engine.web.processor.WebEngineProcessor;
import org.eclipse.dirigible.repository.api.IRepositoryStructure;
import org.eclipse.dirigible.repository.api.IResource;
import org.eclipse.dirigible.repository.api.RepositoryNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Front facing REST service serving the raw web content from the registry/public space.
 */
public abstract class AbstractWebEngineRestService extends AbstractRestService implements IRestService {

	/** The Constant WEB_CACHE. */
	private static final Cache WEB_CACHE = ResourcesCache.getWebCache();

	/** The Constant logger. */
	private static final Logger logger = LoggerFactory.getLogger(AbstractWebEngineRestService.class);

	/** The Constant INDEX_HTML. */
	private static final String INDEX_HTML = "index.html";

	/** The processor. */
	private WebEngineProcessor processor = new WebEngineProcessor();

	/** The request. */
	@Context
	private HttpServletRequest request;

	/** The response. */
	@Context
	private HttpServletResponse response;

	/**
	 * Gets the request.
	 *
	 * @return the request
	 */
	protected HttpServletRequest getRequest() {
		return request;
	}

	/**
	 * Gets the response.
	 *
	 * @return the response
	 */
	protected HttpServletResponse getResponse() {
		return response;
	}

	/**
	 * Gets the resource.
	 *
	 * @param path
	 *            the path
	 * @return the resource
	 */
	public Response getResource(@PathParam("path") String path) {
		if ("".equals(path.trim())) {
			return Response.status(Status.FORBIDDEN).entity("Listing of web folders is forbidden.").build();
		} else if (path.trim().endsWith(IRepositoryStructure.SEPARATOR)) {
			return getResourceByPath(path + INDEX_HTML);
		}
		Response resourceResponse = getResourceByPath(path);
		if (!Configuration.isProductiveIFrameEnabled()) {
			resourceResponse.getHeaders().add("X-Frame-Options", "Deny");
		}
		return resourceResponse;
	}

	/**
	 * Gets the resource by path.
	 *
	 * @param path
	 *            the path
	 * @return the resource by path
	 */
	private Response getResourceByPath(String path) {
		if (isCached(path)) {
			return sendResourceNotModified();
		}

		if (processor.existResource(path)) {
			IResource resource = processor.getResource(path);
			if (resource == null) {
				throw new RepositoryNotFoundException("Resource requested is not exposed.");
			}
			String contentType = resource.getContentType();
			return sendResource(path, resource.isBinary(), resource.getContent(), contentType);
		}

		String errorMessage = "Resource not found: " + path;
		try {
			byte[] content = processor.getResourceContent(path);
			if (content != null) {
				String contentType = ContentTypeHelper.getContentType(ContentTypeHelper.getExtension(path));
				return sendResource(path, ContentTypeHelper.isBinary(contentType), content, contentType);
			} else {
				throw new RepositoryNotFoundException("Resource requested is not exposed.");
			}
		} catch (RepositoryNotFoundException e) {
			throw new RepositoryNotFoundException(errorMessage, e);
		}
	}

	/**
	 * Send resource not modified.
	 *
	 * @return the response
	 */
	private Response sendResourceNotModified() {
		return Response
				.notModified()
				.header("ETag", getTag())
				.build();
	}

	/**
	 * Send resource.
	 *
	 * @param path the path
	 * @param isBinary the is binary
	 * @param content the content
	 * @param contentType the content type
	 * @return the response
	 */
	private Response sendResource(String path, boolean isBinary, byte[] content, String contentType) {
		String tag = cacheResource(path);
		Object responseContent = isBinary ? content : new String(content, StandardCharsets.UTF_8);
		return Response
				.ok(responseContent)
				.type(contentType)
				.header("Cache-Control", "public, must-revalidate, max-age=0")
				.header("ETag", tag)
				.build();
	}

	/**
	 * Cache resource.
	 *
	 * @param path the path
	 * @return the string
	 */
	private String cacheResource(String path) {
		String tag = WEB_CACHE.generateTag();
		WEB_CACHE.setTag(path, tag);
		return tag;
	}

	/**
	 * Checks if is cached.
	 *
	 * @param path the path
	 * @return true, if is cached
	 */
	private boolean isCached(String path) {
		String tag = getTag();
		String cachedTag = WEB_CACHE.getTag(path);
		return tag == null || cachedTag == null ? false : tag.equals(cachedTag); 
		
	}

	/**
	 * Gets the tag.
	 *
	 * @return the tag
	 */
	private String getTag() {
		return getRequest().getHeader("If-None-Match");
	}

	/**
	 * Gets the logger.
	 *
	 * @return the logger
	 */
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.dirigible.commons.api.service.AbstractRestService#getLogger()
	 */
	@Override
	protected Logger getLogger() {
		return logger;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy