| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.lib.rop; |
| |
| import java.util.NoSuchElementException; |
| |
| import org.apache.openjpa.lib.util.Localizer; |
| |
| /** |
| * Prevents a view of a given range of indices from the delegate |
| * result object provider. |
| * |
| * @author Abe White |
| */ |
| public class RangeResultObjectProvider implements ResultObjectProvider { |
| |
| private static final Localizer _loc = Localizer.forPackage |
| (RangeResultObjectProvider.class); |
| |
| private final ResultObjectProvider _delegate; |
| private final int _startIdx; |
| private final int _endIdx; |
| private int _idx = -1; |
| |
| /** |
| * Constructor. Because this is a wrapper around some delegate, |
| * and result object providers work with int indexes, neither the start |
| * or end index can be greater than Integer.MAX_VALUE(with the exception |
| * of Long.MAX_VALUE, which is used to indicate no limit). |
| * |
| * @param delegate the result object provider to delegate to |
| * @param startIdx 0-based inclusive start index of the range |
| * to present; must be < Integer.MAX_VALUE |
| * @param endIdx 0-based exclusive end index of the range to |
| * present; must be < Integer.MAX_VALUE, or Long.MAX_VALUE for no limit |
| */ |
| public RangeResultObjectProvider(ResultObjectProvider delegate, |
| long startIdx, long endIdx) { |
| // use Integer.MAX_VALUE for no limit internally |
| if (endIdx == Long.MAX_VALUE) |
| endIdx = Integer.MAX_VALUE; |
| |
| _delegate = delegate; |
| if (startIdx > Integer.MAX_VALUE || endIdx > Integer.MAX_VALUE) |
| throw new IllegalArgumentException(_loc.get("range-too-high", |
| String.valueOf(startIdx), String.valueOf(endIdx)).getMessage()); |
| |
| _startIdx = (int) startIdx; |
| _endIdx = (int) endIdx; |
| } |
| |
| public boolean supportsRandomAccess() { |
| return _delegate.supportsRandomAccess(); |
| } |
| |
| public void open() throws Exception { |
| _delegate.open(); |
| } |
| |
| public Object getResultObject() throws Exception { |
| if (_idx < _startIdx || _idx >= _endIdx) |
| throw new NoSuchElementException(String.valueOf(_idx)); |
| return _delegate.getResultObject(); |
| } |
| |
| public boolean next() throws Exception { |
| // advance up to just behind _startIdx if we haven't already |
| while (_idx < _startIdx - 1) { |
| if (_delegate.supportsRandomAccess()) { |
| _idx = _startIdx - 1; |
| if (!_delegate.absolute(_startIdx - 1)) |
| return false; |
| } else { |
| _idx++; |
| if (!_delegate.next()) |
| return false; |
| } |
| } |
| |
| // make sure we're not falling off the end of the range |
| if (_idx >= _endIdx - 1) |
| return false; |
| |
| _idx++; |
| return _delegate.next(); |
| } |
| |
| public boolean absolute(int pos) throws Exception { |
| _idx = pos + _startIdx; |
| if (_idx >= _endIdx) |
| return false; |
| return _delegate.absolute(_idx); |
| } |
| |
| public int size() throws Exception { |
| int size = _delegate.size(); |
| if (size == Integer.MAX_VALUE) |
| return size; |
| size = Math.min(_endIdx, size) - _startIdx; |
| return (size < 0) ? 0 : size; |
| } |
| |
| public void reset() throws Exception { |
| _idx = -1; |
| _delegate.reset(); |
| } |
| |
| public void close() throws Exception { |
| _delegate.close(); |
| } |
| |
| public void handleCheckedException(Exception e) { |
| _delegate.handleCheckedException(e); |
| } |
| |
| public ResultObjectProvider getDelegate() { |
| return _delegate; |
| } |
| } |
| |