| /* |
| * 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.queries; |
| |
| import java.util.*; |
| import org.eclipse.persistence.internal.queries.*; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent; |
| import org.eclipse.persistence.exceptions.*; |
| |
| /** |
| * <p><b>Purpose</b>: |
| * Abstract class for all Cursor-related policy objects |
| */ |
| public abstract class CursorPolicy extends ContainerPolicy { |
| protected int pageSize; |
| protected ReadQuery query; |
| |
| /** |
| * INTERNAL: |
| * default constructor |
| */ |
| protected CursorPolicy() { |
| super(); |
| setPageSize(10); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| protected CursorPolicy(ReadQuery query, int pageSize) { |
| super(); |
| setQuery(query); |
| setPageSize(pageSize); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| @Override |
| public ContainerPolicy clone(ReadQuery query) { |
| CursorPolicy clone = (CursorPolicy)super.clone(query); |
| clone.setQuery(query); |
| |
| return clone; |
| } |
| |
| /** |
| * INTERNAL: |
| * Creates a CollectionChangeEvent for the container |
| */ |
| @Override |
| public CollectionChangeEvent createChangeEvent(Object collectionOwner, String propertyName, Object collectionChanged, Object elementChanged, int changeType, Integer index, boolean isChangeApplied){ |
| throw ValidationException.operationNotSupported("createChangeEvent"); |
| } |
| |
| /** |
| * INTERNAL: |
| * Execute the cursored select and build the stream. |
| */ |
| @Override |
| public abstract Object execute(); |
| |
| /** |
| * Return the number of elements to be read into a cursored stream |
| * when more elements are needed from the database. |
| */ |
| public int getPageSize() { |
| return pageSize; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the query. |
| */ |
| public ReadQuery getQuery() { |
| return query; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return whether the iterator has more objects. |
| * |
| * @param iterator java.lang.Object |
| * @return boolean true if iterator has more objects |
| */ |
| @Override |
| public boolean hasNext(Object iterator) { |
| return ((Enumeration)iterator).hasMoreElements(); |
| } |
| |
| @Override |
| public boolean isCursorPolicy() { |
| return true; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return an iterator for the given container. |
| * This iterator can then be used as a parameter to #hasNext() |
| * and #next(). |
| * |
| * @see ContainerPolicy#hasNext(java.lang.Object) |
| * @see ContainerPolicy#next(java.lang.Object) |
| */ |
| @Override |
| public Object iteratorFor(Object container) { |
| return container; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the next object on the queue. The iterator is the one |
| * returned from #iteratorFor(). |
| * |
| * @see ContainerPolicy#iteratorFor(java.lang.Object) |
| */ |
| @Override |
| protected Object next(Object iterator) { |
| return ((Enumeration)iterator).nextElement(); |
| } |
| |
| /** |
| * INTERNAL: |
| * This can be used by collection such as cursored stream to gain control over execution. |
| */ |
| @Override |
| public boolean overridesRead() { |
| return true; |
| } |
| |
| /** |
| * INTERNAL: |
| * Prepare and validate. |
| */ |
| @Override |
| public void prepare(DatabaseQuery query, AbstractSession session) throws QueryException { |
| super.prepare(query, session); |
| setQuery((ReadQuery)query); |
| |
| ClassDescriptor descriptor = query.getDescriptor(); |
| |
| // ReadAllQuery has a descriptor, DataReadQuery does not. |
| if (descriptor != null) { |
| // Interface queries cannot use cursors. |
| if (descriptor.isDescriptorForInterface()) { |
| throw QueryException.noCursorSupport(query); |
| } |
| // Ensure inheritance queries outer join subclasses. |
| if (query.isObjectLevelReadQuery() && descriptor.hasInheritance()) { |
| ((ObjectLevelReadQuery) query).setShouldOuterJoinSubclasses(true); |
| } |
| } |
| query.getQueryMechanism().prepareCursorSelectAllRows(); |
| } |
| |
| /** |
| * INTERNAL: |
| * Execute the cursored select and build the stream. |
| */ |
| @Override |
| public abstract Object remoteExecute(); |
| |
| /** |
| * Set the number of elements to be read into a cursored stream |
| * when more elements are needed from the database. |
| */ |
| public void setPageSize(int pageSize) { |
| this.pageSize = pageSize; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set the query. |
| */ |
| public void setQuery(ReadQuery query) { |
| this.query = query; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the size of container. |
| */ |
| @Override |
| public int sizeFor(Object container) { |
| return ((Cursor)container).size(); |
| } |
| |
| @Override |
| protected Object toStringInfo() { |
| return "page size = " + getPageSize(); |
| } |
| } |