| /* |
| * 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()); |
| } |
| } |
| } |
| } |
| |
| } |