com.sap.cds.adapter.odata.v2.CdsODataV2Servlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cds-adapter-odata-v2 Show documentation
Show all versions of cds-adapter-odata-v2 Show documentation
OData V2 adapter for CDS Services Java
/**************************************************************************
* (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
**************************************************************************/
package com.sap.cds.adapter.odata.v2;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Locale;
import java.util.Optional;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.olingo.odata2.api.ODataServiceFactory;
import org.apache.olingo.odata2.core.commons.ContentType;
import org.apache.olingo.odata2.core.servlet.ODataServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sap.cds.services.ErrorStatuses;
import com.sap.cds.services.ServiceException;
import com.sap.cds.services.request.ParameterInfo;
import com.sap.cds.services.runtime.CdsRuntime;
import com.sap.cds.services.utils.ErrorStatusException;
import com.sap.cds.services.utils.path.UrlPathUtil;
@SuppressWarnings("serial")
public class CdsODataV2Servlet extends ODataServlet {
public static final String ATTRIBUTE_REQUEST_GLOBALS = "requestGlobals";
private static final Logger logger = LoggerFactory.getLogger(CdsODataV2Servlet.class);
private static final String UNEXPECTED_ERROR_MESSAGE = "An unexpected error occurred during servlet processing";
private final CdsRuntime runtime;
private final CdsODataV2ServiceFactory serviceFactory;
public CdsODataV2Servlet(CdsRuntime runtime) {
this.runtime = runtime;
this.serviceFactory = new CdsODataV2ServiceFactory(runtime);
}
@Override
protected ODataServiceFactory getServiceFactory(HttpServletRequest request) {
return serviceFactory;
}
@Override
public String getInitParameter(String name) {
return null;
}
@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(request) {
@Override
public String getServletPath() {
String pathInfo = getPathInfo();
// try to find the best matching service path
Optional servicePath = serviceFactory.getServicePath(pathInfo);
if (servicePath.isPresent()) {
return "/" + servicePath.get();
}
// fall back to just the first path element
pathInfo = pathInfo.substring(1);
return pathInfo.indexOf("/") != -1 ? ("/" + pathInfo.substring(0, pathInfo.indexOf("/"))) : ("/" + pathInfo);
}
@Override
public String getContextPath() {
return UrlPathUtil.normalizeBasePath(runtime.getEnvironment().getCdsProperties().getOdataV2().getEndpoint().getPath());
}
};
// extract the locale according to request parameters
ParameterInfo parameterInfo = runtime.getProvidedParameterInfo();
Locale locale = parameterInfo.getLocale();
try {
runtime.requestContext().parameters(parameterInfo).run((context) -> {
CdsRequestGlobals requestGlobals = new CdsRequestGlobals(runtime, context.getModel());
wrappedRequest.setAttribute(ATTRIBUTE_REQUEST_GLOBALS, requestGlobals);
try {
super.service(wrappedRequest, response);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
} catch (ServiceException e) {
int httpStatus = e.getErrorStatus().getHttpStatus();
if(httpStatus >= 500 && httpStatus < 600) {
logger.error(UNEXPECTED_ERROR_MESSAGE, e);
} else {
logger.debug(UNEXPECTED_ERROR_MESSAGE, e);
}
writeErrorResponse(request, response, httpStatus, e.getLocalizedMessage(locale));
} catch (Exception e) { // NOSONAR
logger.error(UNEXPECTED_ERROR_MESSAGE, e);
writeErrorResponse(request, response, 500, new ErrorStatusException(ErrorStatuses.SERVER_ERROR).getLocalizedMessage(locale));
}
}
private void writeErrorResponse(HttpServletRequest req, HttpServletResponse resp, int httpStatus, String message) throws IOException {
String responseContent = "" + httpStatus + "
" + message + " ";
// TODO can we do better here in guessing the content type?
resp.setHeader("Content-Type", ContentType.APPLICATION_XML.toContentTypeString());
resp.setStatus(httpStatus);
resp.getWriter().println(responseContent);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy