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

org.eclipse.persistence.queries.ConstructorResult Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2012, 2019 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:
//     02/08/2012-2.4 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     08/24/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     02/06/2013-2.5 Guy Pelletier
//       - 382503: Use of @ConstructorResult with createNativeQuery(sqlString, resultSetMapping) results in NullPointerException
package org.eclipse.persistence.queries;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.sessions.DatabaseRecord;

/**
 * 

Purpose: * Concrete class to represent the ConstructorResult structure as defined by * the JPA 2.1 Persistence specification. * * @author Guy Pelletier * @since EclipseLink 2.4 */ public class ConstructorResult extends SQLResult { /** Stores the class of result */ protected String targetClassName; protected transient Class targetClass; /** Stored the column results of this constructor result */ protected List columnResults; protected transient Constructor constructor; protected Class[] constructorArgTypes; /** * Default constructor is protected. Users must initialize the constructor * result with a target class. */ protected ConstructorResult() { columnResults = new ArrayList<>(); } /** * Constructor accepting target class. */ public ConstructorResult(Class targetClass){ this(); if (targetClass == null) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_value_for_constructor_result")); } this.targetClass = targetClass; this.targetClassName = targetClass.getName(); } /** * Constructor accepting target class name. */ public ConstructorResult(String targetClassName){ this(); if (targetClassName == null) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_value_for_constructor_result")); } this.targetClassName = targetClassName; } /** * Add a column result to this constructor result. */ public void addColumnResult(ColumnResult columnResult) { columnResults.add(columnResult); } /** * INTERNAL: * Convert all the class-name-based settings in this query to actual class-based * settings. This method is used when converting a project that has been built * with class names to a project with classes. * @param classLoader */ @Override public void convertClassNamesToClasses(ClassLoader classLoader){ super.convertClassNamesToClasses(classLoader); // Make sure the column results have been converted. for (ColumnResult columnResult : columnResults) { columnResult.convertClassNamesToClasses(classLoader); } //no need to get the class if we already have it if (targetClass == null && targetClassName!=null) { try{ if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { try { targetClass = AccessController.doPrivileged(new PrivilegedClassForName(targetClassName, true, classLoader)); } catch (PrivilegedActionException exception) { throw ValidationException.classNotFoundWhileConvertingClassNames(targetClassName, exception.getException()); } } else { targetClass = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(targetClassName, true, classLoader); } } catch (ClassNotFoundException exc){ throw ValidationException.classNotFoundWhileConvertingClassNames(targetClassName, exc); } } } /** * Return the columns result of this constructor result. */ public List getColumnResults() { return columnResults; } /** * INTERNAL: * This method is a convenience method for extracting values from results/ */ @Override public Object getValueFromRecord(DatabaseRecord record, ResultSetMappingQuery query) { if (constructor == null) { initialize(record, query); } int columnResultsSize = getColumnResults().size(); Object[] constructorArgs = new Object[columnResultsSize]; for (int i = 0; i < columnResultsSize; i++) { constructorArgs[i] = ConversionManager.getDefaultManager().convertObject(record.get(getColumnResults().get(i).getColumn()), constructorArgTypes[i]); } try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { try { return AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, constructorArgs)); } catch (PrivilegedActionException exception) { throw QueryException.exceptionWhileInitializingConstructor(exception.getException(), query, targetClass); } } else { return PrivilegedAccessHelper.invokeConstructor(constructor, constructorArgs); } } catch (IllegalAccessException exception) { throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass); } catch (java.lang.reflect.InvocationTargetException exception) { throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass); } catch (InstantiationException exception) { throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass); } } /** * INTERNAL: */ protected void initialize(DatabaseRecord record, ResultSetMappingQuery query) { int columnResultsSize = getColumnResults().size(); constructorArgTypes = new Class[columnResultsSize]; for (int i = 0; i < columnResultsSize; i++) { ColumnResult result = getColumnResults().get(i); DatabaseField resultField = result.getColumn(); if (resultField.getType() == null) { Object recordResultField = record.get(resultField); if (recordResultField == null) { throw QueryException.columnResultNotFound(resultField); } else { constructorArgTypes[i] = recordResultField.getClass(); } } else { constructorArgTypes[i] = resultField.getType(); } } try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { try { constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(targetClass, constructorArgTypes, true)); } catch (PrivilegedActionException exception) { throw QueryException.exceptionWhileInitializingConstructor(exception.getException(), query, targetClass); } } else { constructor = PrivilegedAccessHelper.getConstructorFor(targetClass, constructorArgTypes, true); } } catch (NoSuchMethodException exception) { throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass); } } /** * Return true if this is a constructor result. */ @Override public boolean isConstructorResult(){ return true; } /** * Set columns result of this constructor result. */ public void setColumnResults(List columnResults) { this.columnResults = columnResults; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy