2 * Copyright (C) 2014 Red Hat, Inc.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 * Authors : Dave Tucker
11 package org.opendaylight.controller.networkconfig.neutron.northbound;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.Comparator;
16 import java.util.List;
17 import javax.ws.rs.core.UriInfo;
18 import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
19 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
20 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
21 import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
22 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
23 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
25 public class PaginatedRequestFactory {
26 private static final Comparator<INeutronObject> NEUTRON_OBJECT_COMPARATOR = new Comparator<INeutronObject>() {
28 public int compare(INeutronObject o1, INeutronObject o2) {
29 return o1.getID().compareTo(o2.getID());
33 public static class PaginationResults<T extends INeutronObject> {
35 List<NeutronPageLink> links;
37 public PaginationResults(List<T> collection, List<NeutronPageLink> links) {
38 this.collection = collection;
43 private static final class MarkerObject implements INeutronObject {
44 private final String id;
46 MarkerObject(String id) {
51 public String getID() {
56 public void setID(String id) {
57 throw new UnsupportedOperationException("Marker has constant ID");
62 * SuppressWarnings is needed because the compiler does not understand that we
63 * are actually safe here.
65 * FIXME: the only caller performs a cast back, so this is not actually necessary.
67 @SuppressWarnings("unchecked")
68 public static <T extends INeutronObject> INeutronRequest<T> createRequest(Integer limit, String marker,
73 PaginationResults<T> results = _paginate(limit, marker, pageReverse, uriInfo, collection);
75 if (clazz.equals(NeutronNetwork.class)){
76 return (INeutronRequest<T>) new NeutronNetworkRequest((List<NeutronNetwork>) results.collection, results.links);
78 if (clazz.equals(NeutronSubnet.class)){
79 return (INeutronRequest<T>) new NeutronSubnetRequest((List<NeutronSubnet>) results.collection, results.links);
81 if (clazz.equals(NeutronPort.class)){
82 return (INeutronRequest<T>) new NeutronPortRequest((List<NeutronPort>) results.collection, results.links);
87 private static <T extends INeutronObject> PaginationResults<T> _paginate(Integer limit, String marker, Boolean pageReverse, UriInfo uriInfo, List<T> collection) {
88 List<NeutronPageLink> links = new ArrayList<>();
92 Boolean firstPage = false;
93 Boolean lastPage = false;
95 Collections.sort(collection, NEUTRON_OBJECT_COMPARATOR);
98 int offset = Collections.binarySearch(collection, new MarkerObject(marker), NEUTRON_OBJECT_COMPARATOR);
100 throw new ResourceNotFoundException("UUID for marker: " + marker + " could not be found");
104 startPos = offset + 1;
107 startPos = offset - limit;
118 if (startPos + limit >= collection.size()) {
119 collection = collection.subList(startPos, collection.size());
120 startMarker = collection.get(0).getID();
121 endMarker = collection.get(collection.size() - 1).getID();
124 else if (startPos < 0) {
125 if (startPos + limit > 0) {
126 collection = collection.subList(0, startPos + limit);
127 startMarker = collection.get(0).getID();
128 endMarker = collection.get(collection.size() - 1).getID();
132 throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker");
136 collection = collection.subList(startPos, startPos + limit);
137 startMarker = collection.get(0).getID();
138 endMarker = collection.get(limit-1).getID();
142 NeutronPageLink next = new NeutronPageLink();
144 next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker);
149 NeutronPageLink previous = new NeutronPageLink();
150 previous.setRef("previous");
151 previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True");
155 return new PaginationResults<T>(collection, links);