Example usage for java.util ArrayList ensureCapacity

List of usage examples for java.util ArrayList ensureCapacity

Introduction

In this page you can find the example usage for java.util ArrayList ensureCapacity.

Prototype

public void ensureCapacity(int minCapacity) 

Source Link

Document

Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.

Usage

From source file:nz.co.jsrsolutions.tideservice.scraper.provider.EasyTideTideDataProvider.java

@Override
public List<Port> getPorts(SubArea subArea) throws TideDataProviderException {

    HttpPost postRequest = null;//from w w  w. j ava  2 s .  c om
    try {

        // Initial GET
        EasyTidePageState pageState = getAreasPage();

        // Select area tab POST
        postRequest = new EasyTideAreaButtonClickHttpPost(mUriBuilder.build(mGetAreasUrlSuffix),
                pageState.getViewState(), pageState.getEventValidation());
        HttpResponse response = mHttpClient.execute(postRequest);

        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            throw new TideDataProviderException("Couldn't simulate click on area button...");
        }
        pageState = getPageState(getHtmlParser(response));
        EntityUtils.consume(response.getEntity());
        if (postRequest != null) {
            postRequest.releaseConnection();
        }

        // Select area POST
        postRequest = new EasyTideAreaSelectClickHttpPost(mUriBuilder.build(mGetAreasUrlSuffix),
                pageState.getViewState(), pageState.getEventValidation(), subArea.getArea().getExternalId());
        response = mHttpClient.execute(postRequest);

        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            throw new TideDataProviderException("Couldn't simulate click on area select...");
        }
        pageState = getPageState(getHtmlParser(response));
        EntityUtils.consume(response.getEntity());
        if (postRequest != null) {
            postRequest.releaseConnection();
        }

        // Select region POST
        postRequest = new EasyTideRegionSelectClickHttpPost(mUriBuilder.build(mGetAreasUrlSuffix),
                pageState.getViewState(), pageState.getEventValidation(), subArea.getArea().getExternalId(),
                subArea.getExternalId());
        response = mHttpClient.execute(postRequest);

        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            throw new TideDataProviderException("Couldn't simulate click on show ports button...");
        }
        Parser parser = getHtmlParser(response);
        pageState = getPageState(parser);

        EntityUtils.consume(response.getEntity());
        if (postRequest != null) {
            postRequest.releaseConnection();
        }

        // ......
        ArrayList<Port> ports = new ArrayList<Port>();

        // Parse the pager links from the port selection table
        NodeList pagerNodeList = new NodeList();
        NodeFilter filter = new AndFilter(new TagNameFilter("A"),
                new HasParentFilter(new HasAttributeFilter("ID", "PSL_dlPager"), true));

        parser.reset();
        for (NodeIterator e = parser.elements(); e.hasMoreNodes();) {
            e.nextNode().collectInto(pagerNodeList, filter);
        }

        // remove the first pager link because we
        // assume (!) that we already have the
        // links for the first page
        if (pagerNodeList.size() > 1) {
            // throw away the result
            pagerNodeList.remove(0);
        }

        // Do this for each page of port links
        do {
            // Parse the links from the port selection table
            NodeList list = new NodeList();
            filter = new AndFilter(new TagNameFilter("A"),
                    new HasParentFilter(new HasAttributeFilter("ID", "PSL_dl"), true));

            parser.reset();
            for (NodeIterator e = parser.elements(); e.hasMoreNodes();) {
                e.nextNode().collectInto(list, filter);
            }

            Node[] nodes = list.toNodeArray();
            ports.ensureCapacity(ports.size() + list.size());

            for (int i = 0; i < list.size(); ++i) {

                mLogger.debug(nodes[i]);
                final TagNode tagNode = (TagNode) nodes[i];
                final String link = tagNode.getAttribute("HREF");
                final Matcher matcher = mPostbackRegexPattern.matcher(link);

                String controlId;
                if (matcher.matches()) {
                    controlId = matcher.group(1);
                } else {
                    throw new TideDataProviderException(
                            "Couldn't match control Id when retrieving port link: ".concat(tagNode.toString()));
                }

                String name = tagNode.getChildren().elementAt(0).getText();
                Port port = new Port();

                port.setName(name);
                port.setDescription(name);

                // Send the port link POST and interpret the response (HTTP 302)
                postRequest = new EasyTidePortLinkClickHttpPost(mUriBuilder.build(mGetAreasUrlSuffix),
                        pageState.getViewState(), pageState.getEventValidation(),
                        subArea.getArea().getExternalId(), subArea.getExternalId(), controlId);
                response = mHttpClient.execute(postRequest);

                if (response.getStatusLine().getStatusCode() != HttpStatus.SC_MOVED_TEMPORARILY) {
                    throw new TideDataProviderException(
                            "Couldn't simulate click on port link for port: ".concat(name));
                }
                // pageState = getPageState(getHtmlParser(response));
                String location = response.getFirstHeader("Location").getValue();
                Matcher externalIdMatcher = mPortIdRegexPattern.matcher(location);

                if (externalIdMatcher.matches()) {
                    port.setExternalId(externalIdMatcher.group(1));
                } else {
                    throw new TideDataProviderException(
                            "Couldn't match portId from location: ".concat(location));
                }

                EntityUtils.consume(response.getEntity());
                if (postRequest != null) {
                    postRequest.releaseConnection();
                }

                ports.add(port);
            }

            if (pagerNodeList.size() > 0) {
                // Get the next page of port results
                final TagNode tagNode = (TagNode) pagerNodeList.remove(0);
                final String link = tagNode.getAttribute("HREF");
                final Matcher matcher = mPostbackRegexPattern.matcher(link);

                String controlId;
                if (matcher.matches()) {
                    controlId = matcher.group(1);
                } else {
                    throw new TideDataProviderException(
                            "Couldn't match control Id when retrieving port link: ".concat(tagNode.toString()));
                }
                // Select next page POST
                postRequest = new EasyTidePageLinkClickHttpPost(mUriBuilder.build(mGetAreasUrlSuffix),
                        pageState.getViewState(), pageState.getEventValidation(),
                        subArea.getArea().getExternalId(), subArea.getExternalId(), controlId);
                response = mHttpClient.execute(postRequest);

                if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    throw new TideDataProviderException("Couldn't simulate click on port page link...");
                }
                parser = getHtmlParser(response);
                pageState = getPageState(parser);

                EntityUtils.consume(response.getEntity());
                if (postRequest != null) {
                    postRequest.releaseConnection();
                }

            }

        } while (pagerNodeList.size() > 0);

        return ports;

    } catch (URISyntaxException e) {
        throw new TideDataProviderException(e);
    } catch (ClientProtocolException e) {
        throw new TideDataProviderException(e);
    } catch (IOException e) {
        throw new TideDataProviderException(e);
    } catch (ParserException e) {
        throw new TideDataProviderException(e);
    } finally {

        if (postRequest != null) {
            postRequest.releaseConnection();
        }
    }

}

From source file:geogebra.common.kernel.implicit.GeoImplicitPoly.java

private void startPath(int width, int height, double x, double y, GeoLocus loc1) {
    int w = width;
    int h = height;
    double sx = x;
    double sy = y;
    double lx = Double.NaN; //no previous point
    double ly = Double.NaN;
    boolean first = true;

    double stepSize = START_STEP_SIZE * Math.max(scaleX, scaleY);
    double startX = x;
    double startY = y;

    ArrayList<MyPoint> firstDirPoints = new ArrayList<MyPoint>();
    firstDirPoints.add(new MyPoint(x, y, true));

    int s = 0;/*from   w  ww .  j av  a  2s. c o m*/
    int lastW = w;
    int lastH = h;
    int startW = w;
    int startH = h;

    boolean nearSing = false;
    double lastGradX = Double.POSITIVE_INFINITY;
    double lastGradY = Double.POSITIVE_INFINITY;
    while (s < MAX_STEPS) {
        s++;
        boolean reachedSingularity = false;
        boolean reachedEnd = false;
        if (!Double.isNaN(lx) && !Double.isNaN(ly)) {
            if ((scaledNormSquared(startX - sx, startY - sy) < MAX_STEP_SIZE * MAX_STEP_SIZE)
                    && (scaledNormSquared(startX - sx, startY - sy) < scaledNormSquared(startX - lx,
                            startY - ly))) {
                /* loop found */
                if (firstDirPoints != null) {

                    MyPoint firstPoint = firstDirPoints.get(0);
                    firstPoint.lineTo = false;
                    loc1.getPoints().addAll(firstDirPoints);
                }
                loc1.insertPoint(x, y, true);
                return;
            }
        }
        if (w > grid.length || h > grid[w].length || grid[w][h] == null) {
            if (w > grid.length || h > grid[w].length) {
                App.printStacktrace("GRID" + grid.length + "," + w + "," + h);
            } else {
                App.printStacktrace(
                        "GRID NULL" + grid.length + "," + w + "," + h + "," + gridWidth + "," + gridHeight);
            }
        }
        while (sx < grid[w][h].x) {
            if (w > 0)
                w--;
            else {
                reachedEnd = true;
                break;
            }
        }
        while (sx > grid[w][h].x + grid[w][h].width) {
            if (w < grid.length - 1)
                w++;
            else {
                reachedEnd = true;
                break;
            }
        }
        while (sy < grid[w][h].y) {
            if (h > 0)
                h--;
            else {
                reachedEnd = true;
                break;
            }
        }
        while (sy > grid[w][h].y + grid[w][h].height) {
            if (h < grid[w].length - 1)
                h++;
            else {
                reachedEnd = true;
                break;
            }
        }
        if (reachedEnd) { //we reached the boundary
            boundaryIntersectCollection.add(new double[] { sx, sy });
        }
        if (lastW != w || lastH != h) {
            int dw = (int) Math.signum(lastW - w);
            int dh = (int) Math.signum(lastH - h);
            for (int i = 0; i <= Math.abs(lastW - w); i++) {
                for (int j = 0; j <= Math.abs(lastH - h); j++) {
                    remember[lastW - dw * i][lastH - dh * j] = false;
                }
            }
        }
        lastW = w;
        lastH = h;

        double gradX = 0;
        double gradY = 0;
        if (!reachedEnd) {
            gradX = evalDiffXPolyAt(sx, sy, true);
            gradY = evalDiffYPolyAt(sx, sy, true);

            /*
             * Dealing with singularities: tries to reach the singularity but stops there.
             * Assuming that the singularity is on or at least near the curve. (Since first
             * derivative is zero this can be assumed for 'nice' 2nd derivative)
             */

            if (nearSing || (Math.abs(gradX) < NEAR_SING && Math.abs(gradY) < NEAR_SING)) {
                for (double[] pair : singularitiesCollection) { //check if this singularity is already known
                    if ((scaledNormSquared(pair[0] - sx, pair[1] - sy) < SING_RADIUS * SING_RADIUS)) {
                        sx = pair[0];
                        sy = pair[1];
                        reachedSingularity = true;
                        reachedEnd = true;
                        break;
                    }
                }
                if (!reachedEnd) {
                    if (gradX * gradX + gradY * gradY > lastGradX * lastGradX + lastGradY * lastGradY) { //going away from the singularity, stop here
                        singularitiesCollection.add(new double[] { sx, sy });
                        reachedEnd = true;
                        reachedSingularity = true;
                    } else if (Math.abs(gradX) < MIN_GRAD && Math.abs(gradY) < MIN_GRAD) { //singularity
                        singularitiesCollection.add(new double[] { sx, sy });
                        reachedEnd = true;
                        reachedSingularity = true;
                    }
                    lastGradX = gradX;
                    lastGradY = gradY;
                    nearSing = true;
                }
            }
        }
        double a = 0, nX = 0, nY = 0;
        if (!reachedEnd) {
            a = 1 / (Math.abs(gradX) + Math.abs(gradY)); //trying to increase numerical stability
            gradX = a * gradX;
            gradY = a * gradY;
            a = Math.sqrt(gradX * gradX + gradY * gradY);
            gradX = gradX / a; //scale vector
            gradY = gradY / a;
            nX = -gradY;
            nY = gradX;
            if (!Double.isNaN(lx) && !Double.isNaN(ly)) {
                double c = (lx - sx) * nX + (ly - sy) * nY;
                if (c > 0) {
                    nX = -nX;
                    nY = -nY;
                }
            } else {
                if (!first) { //other dir now
                    nX = -nX;
                    nY -= nY;
                }
            }
            lx = sx;
            ly = sy;
        }
        while (!reachedEnd) {
            sx = lx + nX * stepSize; //go in "best" direction
            sy = ly + nY * stepSize;
            int e = epsSignum(evalPolyAt(sx, sy, true));
            if (e == 0) {
                if (stepSize * 2 <= MAX_STEP_SIZE * Math.max(scaleX, scaleY))
                    stepSize *= 2;
                break;
            }
            gradX = evalDiffXPolyAt(sx, sy, true);
            gradY = evalDiffYPolyAt(sx, sy, true);
            if (Math.abs(gradX) < MIN_GRAD && Math.abs(gradY) < MIN_GRAD) { //singularity
                stepSize /= 2;
                if (stepSize > MIN_STEP_SIZE * Math.max(scaleX, scaleY))
                    continue;
                singularitiesCollection.add(new double[] { sx, sy });
                reachedEnd = true;
                break;
            }
            a = Math.sqrt(gradX * gradX + gradY * gradY);
            gradX *= stepSize / a;
            gradY *= stepSize / a;
            if (e > 0) {
                gradX = -gradX;
                gradY = -gradY;
            }
            int e1 = epsSignum(evalPolyAt(sx + gradX, sy + gradY, true));
            if (e1 == 0) {
                sx = sx + gradX;
                sy = sy + gradY;
                break;
            }
            if (e1 != e) {
                a = bisec(sx, sy, sx + gradX, sy + gradY);
                sx += a * gradX;
                sy += a * gradY;
                break;
            }
            stepSize /= 2;
            if (stepSize > MIN_STEP_SIZE * Math.max(scaleX, scaleY))
                continue;
            reachedEnd = true;
            break;
        }
        if (!reachedEnd || reachedSingularity) {
            if (reachedSingularity || ((lx - sx) * (lx - sx) + (ly - sy) * (ly - sy) > minGap * minGap)) {
                if (firstDirPoints != null) {
                    firstDirPoints.add(new MyPoint(sx, sy, true));
                } else {
                    loc1.insertPoint(sx, sy, true);
                }
            }
        }
        if (reachedEnd) {
            if (!first) {
                return; //reached the end two times
            }
            lastGradX = Double.POSITIVE_INFINITY;
            lastGradY = Double.POSITIVE_INFINITY;

            /* we reached end for the first time and now save the points into the locus */
            ArrayList<MyPoint> pointList = loc1.getPoints();
            if (firstDirPoints.size() > 0) {
                MyPoint lastPoint = firstDirPoints.get(firstDirPoints.size() - 1);
                lastPoint.lineTo = false;
                pointList.ensureCapacity(pointList.size() + firstDirPoints.size());
                for (int i = firstDirPoints.size() - 1; i >= 0; i--) {
                    pointList.add(firstDirPoints.get(i));
                }
            }
            firstDirPoints = null;
            sx = startX;
            sy = startY;
            lx = Double.NaN;
            ly = Double.NaN;
            w = startW;
            h = startH;
            lastW = w;
            lastH = h;
            first = false;//start again with other direction
            reachedEnd = false;
            reachedSingularity = false;
            nearSing = false;
        }
    }
}

From source file:org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.java

public void processAnnotations(DescriptorPolicy descriptorPolicy, ScoreDefinition deprecatedScoreDefinition,
        List<Class<?>> entityClassList) {
    processSolutionAnnotations(descriptorPolicy);
    ArrayList<Method> potentiallyOverwritingMethodList = new ArrayList<>();
    // Iterate inherited members too (unlike for EntityDescriptor where each one is declared)
    // to make sure each one is registered
    for (Class<?> lineageClass : ConfigUtils.getAllAnnotatedLineageClasses(solutionClass,
            PlanningSolution.class)) {
        List<Member> memberList = ConfigUtils.getDeclaredMembers(lineageClass);
        for (Member member : memberList) {
            if (member instanceof Method && potentiallyOverwritingMethodList.stream()
                    .anyMatch(m -> member.getName().equals(m.getName()) // Short cut to discard negatives faster
                            && ReflectionHelper.isMethodOverwritten((Method) member, m.getDeclaringClass()))) {
                // Ignore member because it is an overwritten method
                continue;
            }//  w ww  . j av a2  s. c  o  m
            processValueRangeProviderAnnotation(descriptorPolicy, member);
            processFactEntityOrScoreAnnotation(descriptorPolicy, member, deprecatedScoreDefinition,
                    entityClassList);
        }
        potentiallyOverwritingMethodList
                .ensureCapacity(potentiallyOverwritingMethodList.size() + memberList.size());
        memberList.stream().filter(member -> member instanceof Method)
                .forEach(member -> potentiallyOverwritingMethodList.add((Method) member));
    }
    if (entityCollectionMemberAccessorMap.isEmpty() && entityMemberAccessorMap.isEmpty()) {
        throw new IllegalStateException(
                "The solutionClass (" + solutionClass + ") must have at least 1 member with a "
                        + PlanningEntityCollectionProperty.class.getSimpleName() + " annotation or a "
                        + PlanningEntityProperty.class.getSimpleName() + " annotation.");
    }
    if (Solution.class.isAssignableFrom(solutionClass)) {
        processLegacySolution(descriptorPolicy, deprecatedScoreDefinition);
        return;
    }
    // Do not check if problemFactCollectionMemberAccessorMap and problemFactMemberAccessorMap are empty
    // because they are only required for Drools score calculation.
    if (scoreMemberAccessor == null) {
        throw new IllegalStateException("The solutionClass (" + solutionClass + ") must have 1 member with a "
                + PlanningScore.class.getSimpleName() + " annotation.\n"
                + "Maybe add a getScore() method with a " + PlanningScore.class.getSimpleName()
                + " annotation.");
    }
}

From source file:edu.unc.lib.dl.util.ContainerContentsHelper.java

/**
 * Adds new children to the content index. If there is an order specified for a new child, then it will insert the
 * child at the specified position. Any existing children after the specified position will be shifted if neccessary.
 * // w  ww . j  av  a  2  s.c o  m
 * @param reordered
 * 
 * @param oldContents
 *           bytes for the old XML CONTENTS stream
 * @param topPid
 *           new child pid
 * @param containerOrder
 * @return
 * @throws JDOMException
 * @throws IOException
 */
public static Document addChildContentAIPInCustomOrder(Document result, PID containerPID,
        Collection<ContainerPlacement> placements, List<PID> reordered) {
    log.debug("adding child content to MD_CONTENTS XML doc");

    // first build a list of existing pid order in the container
    Element parentDiv = result.getRootElement().getChild("div", JDOMNamespaceUtil.METS_NS);
    List<Element> childDivs = parentDiv.getContent(Filters.element());
    int maxExistingOrder = 5;
    if (childDivs.size() > 0) {
        maxExistingOrder = Integer.parseInt(childDivs.get(childDivs.size() - 1).getAttributeValue("ORDER"));
    }
    ArrayList<PID> order = new ArrayList<PID>(maxExistingOrder + 1);
    try {
        for (Element child : childDivs) {
            int ord = Integer.parseInt(child.getAttributeValue("ORDER"));
            PID pid = new PID(child.getAttributeValue("ID"));
            if (ord >= order.size()) {
                while (ord > order.size()) { // insert nulls
                    order.add(null);
                }
                order.add(pid);
            } else {
                order.add(ord, pid);
            }
        }
    } catch (NullPointerException e) {
        throw new IllegalRepositoryStateException("Invalid container contents XML (MD_CONTENTS) on: ", e);
    }

    // FIXME: put all the old children in reordered pile, for now
    for (PID p : order) {
        if (p != null) {
            reordered.add(p);
        }
    }

    // clear out the current children
    parentDiv.removeContent();

    // build a list of things with designated order and things with only sip
    // order
    List<ContainerPlacement> designatedOrder = new ArrayList<ContainerPlacement>();
    List<ContainerPlacement> sipOrdered = new ArrayList<ContainerPlacement>();
    List<ContainerPlacement> unordered = new ArrayList<ContainerPlacement>();
    for (ContainerPlacement place : placements) {
        if (containerPID.equals(place.parentPID)) { // only place those objects that go in this container
            if (place.designatedOrder != null) {
                designatedOrder.add(place);
            } else if (place.sipOrder != null) {
                sipOrdered.add(place);
            } else {
                unordered.add(place);
            }
        }
    }
    // order.ensureCapacity(order.size() + designatedOrder.size() +
    // sipOrdered.size());

    // sort designated ordered stuff by that order
    Comparator<ContainerPlacement> designatedSort = new Comparator<ContainerPlacement>() {
        @Override
        public int compare(ContainerPlacement o1, ContainerPlacement o2) {
            if (o1.designatedOrder > o2.designatedOrder) {
                return 1;
            } else if (o1.designatedOrder < o2.designatedOrder) {
                return -1;
            }
            return 0;
        }
    };
    // ensure capacity for max of designated and existing, plus count of
    // sipOrdered and a buffer for collisions
    int maxDesignatedOrder = 0;
    if (designatedOrder.size() > 0) {
        Collections.sort(designatedOrder, designatedSort);
        maxDesignatedOrder = designatedOrder.get(designatedOrder.size() - 1).designatedOrder.intValue();
    }
    int capacityEstimate = Math.max(maxDesignatedOrder, maxExistingOrder) + sipOrdered.size() + 10;
    order.ensureCapacity(capacityEstimate);
    // insert the objects with designated order
    for (ContainerPlacement place : designatedOrder) {
        int pos = place.designatedOrder.intValue();
        if (pos >= order.size()) {
            while (pos > order.size()) { // index out of bounds, insert nulls
                order.add(null);
            }
            order.add(place.pid);
        } else {
            order.add(pos, place.pid);
        }
    }

    // append the objects with sip sibling order
    // sort sip ordered stuff by that order
    Comparator<ContainerPlacement> sipSort = new Comparator<ContainerPlacement>() {
        @Override
        public int compare(ContainerPlacement o1, ContainerPlacement o2) {
            if (o2.sipOrder == null || o1.sipOrder > o2.sipOrder) {
                return 1;
            } else if (o1.sipOrder == null || o1.sipOrder < o2.sipOrder) {
                return -1;
            }
            return 0;
        }
    };
    Collections.sort(sipOrdered, sipSort);
    // add SIP ordered
    for (ContainerPlacement place : sipOrdered) {
        order.add(place.pid);
    }
    // add unordered
    for (ContainerPlacement place : unordered) {
        order.add(place.pid);
    }

    for (ListIterator<PID> li = order.listIterator(); li.hasNext();) {
        int ord = li.nextIndex();
        PID pid = li.next();
        if (pid != null) {
            Element el = new Element("div", parentDiv.getNamespace()).setAttribute("ID", pid.getPid())
                    .setAttribute("ORDER", String.valueOf(ord));
            parentDiv.addContent(el);
        }
    }
    return result;
}

From source file:org.cruk.genologics.api.impl.GenologicsAPIImpl.java

/**
 * Perform a list operation for obtaining links to entities using a specific
 * batch fetch class. These lists may  be a simple "list all in system" call
 * or from a "find" operation.//  w ww  .  ja v  a  2 s. c  o  m
 *
 * <p>
 * Deals with the pagination mechanism employed by the API to bring
 * back the required number of links regardless of the number of "pages"
 * the API returns them in.
 * </p>
 *
 * @param uri The URI to use for the list.
 * @param entityClass The type of entities required (or rather links to such entities).
 * @param batchClass The type of object to use for fetching the links.
 * @param number The maximum number of entities required. Calling code should
 * use {@code Integer.MAX_VALUE} to return all.
 *
 * @param <E> The type of the entity.
 * @param <BH> The type of the batch fetch object that holds the list of links
 * to these entities.
 *
 * @return A list of links to the entities found.
 *
 * @throws IllegalArgumentException if {@code entityClass} is annotated to be
 * a part of another entity (its {@code primaryEntity} attribute is set).
 */
private <E extends Locatable, BH extends Batch<? extends LimsLink<E>>> List<LimsLink<E>> doList(String uri,
        Class<E> entityClass, Class<BH> batchClass, int number) {
    GenologicsEntity entityAnno = checkEntityAnnotated(entityClass);

    String entityClassName = getShortClassName(entityClass);

    if (entityAnno.primaryEntity() != void.class) {
        String primaryName = getShortClassName(entityAnno.primaryEntity());

        throw new IllegalArgumentException(
                "Cannot list all " + entityClassName + "s as they are part of " + primaryName + ". " + "A "
                        + primaryName + " should supply a list of its relevant " + entityClassName + "s.");
    }

    ArrayList<LimsLink<E>> allLinks = new ArrayList<LimsLink<E>>(1024);

    // Note that it is important here to prevent the Spring escaping system
    // from encoding subsequent page URIs and turning, for example, plus signs
    // into %2B escaped characters. So for subsequent pages, take the URI
    // as given from the response.

    URI nextPageUri = null;
    do {
        ResponseEntity<BH> response;
        if (nextPageUri == null) {
            logger.debug("Fetching first batch of {} links from {}", entityClassName, uri);

            // First page
            response = restClient.getForEntity(uri, batchClass);
        } else {
            logger.debug("Fetching further batch of {} links from {}", entityClassName, nextPageUri);

            // Later batches.
            response = restClient.getForEntity(nextPageUri, batchClass);
        }

        BH batch = response.getBody();

        Iterator<? extends LimsLink<E>> iter = batch.iterator();
        int toAdd = Math.min(batch.getSize(), number - allLinks.size());

        allLinks.ensureCapacity(allLinks.size() + toAdd);

        for (; iter.hasNext() && toAdd > 0; toAdd--) {
            allLinks.add(iter.next());
        }

        nextPageUri = null;
        if (PaginatedBatch.class.isAssignableFrom(batchClass)) {
            PaginatedBatch<?> paginatedBatch = (PaginatedBatch<?>) batch;
            if (paginatedBatch.getNextPage() != null) {
                nextPageUri = paginatedBatch.getNextPage().getUri();
            }
        }
    } while (nextPageUri != null && allLinks.size() < number);

    allLinks.trimToSize();
    return allLinks;
}