blob: 1ff7b0bf815626d4b3e18579516e3e3d4633c328 [file] [log] [blame]
/*
* Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// gonural - Initial implementation
// 2014-09-01-2.6.0 Dmitry Kornilov
// - JPARS v2.0 related changes
package org.eclipse.persistence.jpa.rs.resources.common;
import org.eclipse.persistence.internal.jpa.EJBQueryImpl;
import org.eclipse.persistence.internal.queries.ReportItem;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
import org.eclipse.persistence.jpa.rs.exceptions.JPARSException;
import org.eclipse.persistence.jpa.rs.features.FeatureResponseBuilder;
import org.eclipse.persistence.jpa.rs.features.FeatureSet.Feature;
import org.eclipse.persistence.jpa.rs.util.JPARSLogger;
import org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller;
import org.eclipse.persistence.jpa.rs.util.list.SingleResultQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReportQuery;
import jakarta.persistence.Query;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import jakarta.xml.bind.JAXBElement;
import java.util.List;
/**
* Base class for all single result query resources.
*
* @author gonural
*/
public abstract class AbstractSingleResultQueryResource extends AbstractResource {
private static final String CLASS_NAME = AbstractSingleResultQueryResource.class.getName();
/**
* Named query single result.
*
* @param version the version
* @param persistenceUnit the persistence unit
* @param queryName the query name
* @param headers the http headers
* @param uriInfo the uriInfo
* @return the response
*/
@SuppressWarnings("rawtypes")
protected Response namedQuerySingleResultInternal(String version, String persistenceUnit, String queryName, HttpHeaders headers, UriInfo uriInfo) {
JPARSLogger.entering(CLASS_NAME, "namedQuerySingleResultInternal", new Object[] { "GET", version, persistenceUnit, queryName, uriInfo.getRequestUri().toASCIIString() });
try {
final PersistenceContext context = getPersistenceContext(persistenceUnit, null, uriInfo.getBaseUri(), version, null);
final Query query = context.buildQuery(getMatrixParameters(uriInfo, persistenceUnit), queryName, getMatrixParameters(uriInfo, queryName), getQueryParameters(uriInfo));
final DatabaseQuery dbQuery = ((EJBQueryImpl<?>) query).getDatabaseQuery();
final FeatureResponseBuilder responseBuilder = context.getSupportedFeatureSet().getResponseBuilder(Feature.NO_PAGING);
if (dbQuery instanceof ReportQuery) {
final List<ReportItem> reportItems = ((ReportQuery) dbQuery).getItems();
final Object queryResults = query.getSingleResult();
final Object response = responseBuilder.buildSingleResultQueryResponse(context, getQueryParameters(uriInfo), queryResults, reportItems, uriInfo);
if (response != null && response instanceof SingleResultQuery) {
final SingleResultQuery singleResultQuery = (SingleResultQuery) response;
final List<JAXBElement<?>> item = singleResultQuery.getFields();
if ((item != null) && (item.size() == 1)) {
// Fix for Bug 393320 - JPA-RS: Respect the Accept Header for a singleResultQuery
// If there is only one item in the select clause and if value of that item is binary, we will create a response with
// that binary data without converting its to Base64.
JAXBElement element = item.get(0);
Object elementValue = element.getValue();
if (elementValue instanceof byte[]) {
List<MediaType> acceptableMediaTypes = headers.getAcceptableMediaTypes();
if (acceptableMediaTypes.contains(MediaType.APPLICATION_OCTET_STREAM_TYPE)) {
return Response.ok(new StreamingOutputMarshaller(context, elementValue, headers.getAcceptableMediaTypes())).build();
}
}
}
return Response.ok(new StreamingOutputMarshaller(context, response, headers.getAcceptableMediaTypes())).build();
} else {
// something went wrong with the descriptors, return error
throw JPARSException.responseCouldNotBeBuiltForNamedQueryRequest(queryName, context.getName());
}
}
final Object queryResult = query.getSingleResult();
return Response.ok(new StreamingOutputMarshaller(context, responseBuilder.buildSingleEntityResponse(context, getQueryParameters(uriInfo), queryResult, uriInfo), headers.getAcceptableMediaTypes())).build();
} catch (Exception ex) {
throw JPARSException.exceptionOccurred(ex);
}
}
}