blob: 305cb76ccf4d7b9734907728177f37447ab29ff1 [file] [log] [blame]
/*
* Copyright (c) 1998, 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:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.queries;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Comparator;
import java.lang.reflect.Constructor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
/**
* <p><b>Purpose</b>: A SortedCollectionContainerPolicy is ContainerPolicy whose
* container class implements the SortedInterface interface.
* Added for BUG # 3233263
* </p>
* <p><b>Responsibilities</b>:
* Provide the functionality to operate on an instance of a SortedSet.</p>
*
* @see ContainerPolicy
* @see MapContainerPolicy
*/
public class SortedCollectionContainerPolicy extends CollectionContainerPolicy {
protected Comparator m_comparator = null;
protected Class comparatorClass = null ;
protected String comparatorClassName = null;
/**
* INTERNAL:
* Construct a new policy.
*/
public SortedCollectionContainerPolicy() {
super();
}
/**
* INTERNAL:
* Construct a new policy for the specified class.
*/
public SortedCollectionContainerPolicy(Class containerClass) {
super(containerClass);
}
/**
* INTERNAL:
* Construct a new policy for the specified class name.
*/
public SortedCollectionContainerPolicy(String containerClassName) {
super(containerClassName);
}
/**
* INTERNAL:
* Sets a comparator object for this policy to use when instantiating
* a new SortedSet object.
*/
public void setComparator(Comparator comparator) {
m_comparator = comparator;
}
/**
* INTERNAL:
* Sets a comparator class for this policy to use when instantiating
* a new SortedSet object.
*/
public void setComparatorClass(Class comparatorClass) {
if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
}else{
throw ValidationException.invalidComparatorClass(comparatorClass.getName());
}
this.comparatorClass=comparatorClass;
}
/**
* INTERNAL:
* Sets a comparator class name for this policy to use when instantiating
* a new SortedSet object.
*/
public void setComparatorClassName(String comparatorClassName) {
this.comparatorClassName=comparatorClassName;
}
/**
* INTERNAL:
* Return the stored comparator
*/
public Comparator getComparator() {
return m_comparator;
}
/**
* INTERNAL:
* Return the stored comparator class
*/
public Class getComparatorClass() {
return comparatorClass;
}
/**
* INTERNAL:
* return stored comparator class name
*/
public String getComparatorClassName() {
if (this.m_comparator!=null){
return this.m_comparator.getClass().getName();
}else if (this.comparatorClass!=null){
return this.comparatorClass.getName();
}else if (this.comparatorClassName!=null){
return this.comparatorClassName;
}else{
return null;
}
}
/**
* INTERNAL
* Override from ContainerPolicy. Need to maintain the comparator in the
* new instance
*/
@Override
public Object containerInstance() {
try {
if(m_comparator==null && comparatorClass!=null){
if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
}else{
throw ValidationException.invalidComparatorClass(comparatorClass.getName());
}
}
if (m_comparator != null) {
Object[] arguments = new Object[] { m_comparator };
Class[] constructClass = new Class[] { Comparator.class };
Constructor constructor = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(getContainerClass(), constructClass, false));
return AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, arguments));
} catch (PrivilegedActionException exception) {
throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), exception.getException());
}
} else {
constructor = PrivilegedAccessHelper.getConstructorFor(getContainerClass(), constructClass, false);
return PrivilegedAccessHelper.invokeConstructor(constructor, arguments);
}
} else {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
return AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(getContainerClass()));
} catch (PrivilegedActionException exception) {
throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), exception.getException());
}
} else {
return PrivilegedAccessHelper.newInstanceFromClass(getContainerClass());
}
}
} catch (Exception ex) {
throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), ex);
}
}
/**
* INTERNAL:
* Convert all the class-name-based settings in this SortedCollectionContainerPolicy 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.
*/
@Override
public void convertClassNamesToClasses(ClassLoader classLoader){
super.convertClassNamesToClasses(classLoader);
if(m_comparator==null){
if(comparatorClass==null){
if(comparatorClassName!=null){
Class comparatorClass = Helper.getClassFromClasseName(comparatorClassName, classLoader);
if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
}else{
throw ValidationException.invalidComparatorClass(comparatorClassName);
}
}
}else{
if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
}else{
throw ValidationException.invalidComparatorClass(comparatorClass.getName());
}
}
}
}
}