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

org.eclipse.dirigible.components.odata.handler.ScriptingOData2EventHandler Maven / Gradle / Ivy

There is a newer version: 10.6.37
Show newest version
/*
 * Copyright (c) 2023 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: 2023 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.dirigible.components.odata.handler;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.apache.olingo.odata2.api.ep.EntityProvider;
import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
import org.eclipse.dirigible.commons.config.Configuration;
import org.eclipse.dirigible.components.engine.javascript.service.JavascriptService;
import org.eclipse.dirigible.components.odata.api.ODataHandlerMethods;
import org.eclipse.dirigible.components.odata.api.ODataHandlerTypes;
import org.eclipse.dirigible.components.odata.domain.ODataHandler;
import org.eclipse.dirigible.components.odata.service.ODataHandlerService;
import org.eclipse.dirigible.engine.odata2.sql.api.OData2EventHandler;
import org.eclipse.dirigible.repository.api.RepositoryPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class ScriptingOData2EventHandler.
 */
public class ScriptingOData2EventHandler implements OData2EventHandler {

    /** The Constant DIRIGIBLE_ODATA_HANDLER_EXECUTOR_TYPE. */
    private static final String DIRIGIBLE_ODATA_HANDLER_EXECUTOR_TYPE = "DIRIGIBLE_ODATA_HANDLER_EXECUTOR_TYPE";
    
    /** The Constant DIRIGIBLE_ODATA_HANDLER_EXECUTOR_ON_EVENT. */
    private static final String DIRIGIBLE_ODATA_HANDLER_EXECUTOR_ON_EVENT = "DIRIGIBLE_ODATA_HANDLER_EXECUTOR_ON_EVENT";

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

    /** The Constant DIRIGIBLE_ODATA_WRAPPER_MODULE_ON_EVENT. */
    private static final String DIRIGIBLE_ODATA_WRAPPER_MODULE_ON_EVENT = "odata/wrappers/onEvent";

    /** The Constant ERROR_EXECUTING_SCRIPTING_HANDLER. */
    private static final String ERROR_EXECUTING_SCRIPTING_HANDLER = "Error executing scripting handler: ";

    /**
     * Before create entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param contentType the content type
     * @param entry the entry
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse beforeCreateEntity(PostUriInfo uriInfo, String requestContentType,
                                            String contentType, ODataEntry entry, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.create.name();
            String type = ODataHandlerTypes.before.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("requestContentType", requestContentType);
            context.put("contentType", contentType);
            context.put("entry", entry);
            executeHandlers(handlers, context);
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * After create entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param contentType the content type
     * @param entry the entry
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse afterCreateEntity(PostUriInfo uriInfo, String requestContentType,
                                           String contentType, ODataEntry entry, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.create.name();
            String type = ODataHandlerTypes.after.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("requestContentType", requestContentType);
            context.put("contentType", contentType);
            context.put("entry", entry);
            executeHandlers(handlers, context);
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * Checks if is using on create entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param contentType the content type
     * @return true, if is using on create entity
     */
    @Override
    public boolean isUsingOnCreateEntity(PostUriInfo uriInfo, String requestContentType,
                                         String contentType) {
        return isUsingEvent((UriInfo) uriInfo, ODataHandlerMethods.create.name(), ODataHandlerTypes.on.name());
    }

    /**
     * Checks if is using after create entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param contentType the content type
     * @return true, if is using after create entity
     */
    @Override
    public boolean isUsingAfterCreateEntity(PostUriInfo uriInfo, String requestContentType,
                                         String contentType) {
        return isUsingEvent((UriInfo) uriInfo, ODataHandlerMethods.create.name(), ODataHandlerTypes.after.name());
    }

    /**
     * On create entity.
     *
     * @param uriInfo the uri info
     * @param content the content
     * @param requestContentType the request content type
     * @param contentType the content type
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse onCreateEntity(PostUriInfo uriInfo, InputStream content, String requestContentType,
                                        String contentType, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.create.name();
            String type = ODataHandlerTypes.on.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("requestContentType", requestContentType);
            context.put("contentType", contentType);
            context.put("content", content);
            String responseMessage = executeHandler(handlers, context);
            ODataResponse response = EntityProvider.writeText(responseMessage);
            return response;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * Forbid create entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param contentType the content type
     * @return true, if successful
     */
    @Override
    public boolean forbidCreateEntity(PostUriInfo uriInfo, String requestContentType,
                                      String contentType) {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.create.name();
            String type = ODataHandlerTypes.forbid.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            return handlers.size() > 0;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        }
        return false;
    }

    /**
     * Before update entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param merge the merge
     * @param contentType the content type
     * @param entry the entry
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse beforeUpdateEntity(PutMergePatchUriInfo uriInfo, String requestContentType,
                                            boolean merge, String contentType, ODataEntry entry, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.update.name();
            String type = ODataHandlerTypes.before.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("requestContentType", requestContentType);
            context.put("merge", merge);
            context.put("contentType", contentType);
            context.put("entry", entry);
            executeHandlers(handlers, context);
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * After update entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param merge the merge
     * @param contentType the content type
     * @param entry the entry
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse afterUpdateEntity(PutMergePatchUriInfo uriInfo, String requestContentType,
                                           boolean merge, String contentType, ODataEntry entry, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.update.name();
            String type = ODataHandlerTypes.after.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("requestContentType", requestContentType);
            context.put("merge", merge);
            context.put("contentType", contentType);
            context.put("entry", entry);
            executeHandlers(handlers, context);
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * Checks if is using on update entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param merge the merge
     * @param contentType the content type
     * @return true, if is using on update entity
     */
    @Override
    public boolean isUsingOnUpdateEntity(PutMergePatchUriInfo uriInfo, String requestContentType,
                                         boolean merge, String contentType) {
        return isUsingEvent((UriInfo) uriInfo, ODataHandlerMethods.update.name(), ODataHandlerTypes.on.name());
    }

    /**
     * On update entity.
     *
     * @param uriInfo the uri info
     * @param content the content
     * @param requestContentType the request content type
     * @param merge the merge
     * @param contentType the content type
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse onUpdateEntity(PutMergePatchUriInfo uriInfo, InputStream content, String requestContentType,
                                        boolean merge, String contentType, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.update.name();
            String type = ODataHandlerTypes.on.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("requestContentType", requestContentType);
            context.put("merge", merge);
            context.put("contentType", contentType);
            context.put("content", content);
            String responseMessage = executeHandler(handlers, context);
            ODataResponse response = EntityProvider.writeText(responseMessage);
            return response;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * Forbid update entity.
     *
     * @param uriInfo the uri info
     * @param requestContentType the request content type
     * @param merge the merge
     * @param contentType the content type
     * @return true, if successful
     */
    @Override
    public boolean forbidUpdateEntity(PutMergePatchUriInfo uriInfo, String requestContentType,
                                      boolean merge, String contentType) {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.update.name();
            String type = ODataHandlerTypes.forbid.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            return handlers.size() > 0;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        }
        return false;
    }

    /**
     * Before delete entity.
     *
     * @param uriInfo the uri info
     * @param contentType the content type
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse beforeDeleteEntity(DeleteUriInfo uriInfo, String contentType, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.delete.name();
            String type = ODataHandlerTypes.before.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("contentType", contentType);
            executeHandlers(handlers, context);
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * After delete entity.
     *
     * @param uriInfo the uri info
     * @param contentType the content type
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse afterDeleteEntity(DeleteUriInfo uriInfo, String contentType, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.delete.name();
            String type = ODataHandlerTypes.after.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("contentType", contentType);
            executeHandlers(handlers, context);
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * Checks if is using on delete entity.
     *
     * @param uriInfo the uri info
     * @param contentType the content type
     * @return true, if is using on delete entity
     */
    @Override
    public boolean isUsingOnDeleteEntity(DeleteUriInfo uriInfo, String contentType) {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.delete.name();
            String type = ODataHandlerTypes.on.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            return handlers.size() > 0;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        }
        return false;
    }

    /**
     * On delete entity.
     *
     * @param uriInfo the uri info
     * @param contentType the content type
     * @param context the context
     * @return the o data response
     * @throws ODataException the o data exception
     */
    @Override
    public ODataResponse onDeleteEntity(DeleteUriInfo uriInfo, String contentType, Map context) throws ODataException {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.delete.name();
            String type = ODataHandlerTypes.on.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            context.put("uriInfo", uriInfo);
            context.put("contentType", contentType);
            String responseMessage = executeHandler(handlers, context);
            ODataResponse response = EntityProvider.writeText(responseMessage);
            return response;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        } catch (Exception e) {
            throw new ODataException(ERROR_EXECUTING_SCRIPTING_HANDLER + e.getMessage(), e);
        }
        return null;
    }

    /**
     * Forbid delete entity.
     *
     * @param uriInfo the uri info
     * @param contentType the content type
     * @return true, if successful
     */
    @Override
    public boolean forbidDeleteEntity(DeleteUriInfo uriInfo, String contentType) {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            String method = ODataHandlerMethods.delete.name();
            String type = ODataHandlerTypes.forbid.name();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            return handlers.size() > 0;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        }
        return false;
    }

    /**
     * Gets the name.
     *
     * @return the name
     */
    @Override
    public String getName() {
        return DEFAULT_ODATA_EVENT_HANDLER_NAME;
    }

    /**
     * Execute handlers.
     *
     * @param handlers the handlers
     * @param context the context
     */
    private void executeHandlers(List handlers, Map context) {
        handlers.forEach(handler -> {
            setHandlerParametersInContext(context, handler);
            try {
				executeHandlerByExecutor(context);
			} catch (Exception e) {
				if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
			}
        });
    }

    /**
     * Execute handler.
     *
     * @param handlers the handlers
     * @param context the context
     * @return the string
     * @throws Exception 
     */
    private String executeHandler(List handlers, Map context) throws Exception {
        if (handlers.size() > 0) {
            ODataHandler handler = handlers.get(0);
            setHandlerParametersInContext(context, handler);
            Object response = executeHandlerByExecutor(context);
            return response != null ? response.toString() : "Empty response.";
        }
        return "No response.";
    }

    /**
     * Execute handler by executor.
     *
     * @param context the context
     * @return the object
     * @throws Exception the scripting exception
     */
    private Object executeHandlerByExecutor(Map context) throws Exception {
        String odataHandlerExecutorType = Configuration.get(DIRIGIBLE_ODATA_HANDLER_EXECUTOR_TYPE);
        String odataHandlerExecutorOnEvent = Configuration.get(DIRIGIBLE_ODATA_HANDLER_EXECUTOR_ON_EVENT);
        
        
        if (odataHandlerExecutorType != null && odataHandlerExecutorOnEvent != null) {
        	
			RepositoryPath path = new RepositoryPath(odataHandlerExecutorOnEvent);
	    	return getJavascriptService().handleRequest(path.getSegments()[0], path.constructPathFrom(1), null, context, false);
        }
		RepositoryPath path = new RepositoryPath(DIRIGIBLE_ODATA_WRAPPER_MODULE_ON_EVENT);
    	return getJavascriptService().handleRequest(path.getSegments()[0], path.constructPathFrom(1), null, context, false);
    }

    /**
     * Sets the handler parameters in context.
     *
     * @param context the context
     * @param handler the handler
     */
    private void setHandlerParametersInContext(Map context, ODataHandler handler) {
        context.put("location", handler.getLocation());
        context.put("namespace", handler.getNamespace());
        context.put("name", handler.getName());
        context.put("method", handler.getMethod());
        context.put("type", handler.getType());
        context.put("handler", handler.getHandler());
    }

    /**
     * Checks if is using event.
     *
     * @param uriInfo the uri info
     * @param method the method
     * @param type the type
     * @return true, if is using event
     */
    private boolean isUsingEvent(UriInfo uriInfo, String method, String type) {
        try {
            String namespace = uriInfo.getTargetType().getNamespace();
            String name = uriInfo.getTargetType().getName();
            List handlers = ODataHandlerService.get().getByNamespaceNameMethodAndKind(namespace, name, method, type);
            return handlers.size() > 0;
        } catch (ODataException e) {
        	if (logger.isErrorEnabled()) {logger.error(e.getMessage(), e);}
        }
        return false;
    }
    
    /**
	 * Gets the javascript service.
	 *
	 * @return the javascript service
	 */
	public JavascriptService getJavascriptService() {
		return JavascriptService.get();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy