8f05e76e1839d9c10d630635f2e4d160b43a9908
[controller.git] / opendaylight / northbound / networkconfiguration / neutron / src / main / java / org / opendaylight / controller / networkconfig / neutron / northbound / PaginatedRequestFactory.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc.
3  *
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
7  *
8  *  Authors : Dave Tucker
9  */
10
11 package org.opendaylight.controller.networkconfig.neutron.northbound;
12
13 import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
14 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
15 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
16 import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
17 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
18 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
19
20 import javax.ws.rs.core.UriInfo;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.List;
25
26 public class PaginatedRequestFactory {
27
28     public static class PaginationResults<T extends INeutronObject> {
29         List<T> collection;
30         List<NeutronPageLink> links;
31
32         public PaginationResults(List<T> collection, List<NeutronPageLink> links) {
33             this.collection = collection;
34             this.links = links;
35         }
36     }
37
38     public static <T extends INeutronObject> INeutronRequest createRequest(Integer limit, String marker,
39                                                                            Boolean pageReverse,
40                                                                            UriInfo uriInfo,
41                                                                            List<T> collection,
42                                                                            Class<T> clazz) {
43         PaginationResults results = _paginate(limit, marker, pageReverse, uriInfo, collection);
44
45         if (clazz.equals(NeutronNetwork.class)){
46             return new NeutronNetworkRequest(results.collection, results.links);
47         }
48         if (clazz.equals(NeutronSubnet.class)){
49             return new NeutronSubnetRequest(results.collection, results.links);
50         }
51         if (clazz.equals(NeutronPort.class)){
52             return new NeutronPortRequest(results.collection, results.links);
53         }
54         return null;
55     }
56
57     private static <T extends INeutronObject> PaginationResults _paginate(Integer limit, String marker, Boolean pageReverse, UriInfo uriInfo, List<T> collection) {
58         List<NeutronPageLink> links = new ArrayList<>();
59         Integer startPos = null;
60         String startMarker;
61         String endMarker;
62         Boolean firstPage = false;
63         Boolean lastPage = false;
64
65         Comparator<INeutronObject> neutronObjectComparator = new Comparator<INeutronObject>() {
66             @Override
67             public int compare(INeutronObject o1, INeutronObject o2) {
68                 return o1.getID().compareTo(o2.getID());
69             }
70         };
71
72         Collections.sort(collection, neutronObjectComparator);
73
74         if (marker == null) {
75             startPos = 0;
76         }
77
78         else {
79
80             class MarkerObject implements INeutronObject {
81                 private String id;
82
83                 public String getID() {
84                     return id;
85                 }
86
87                 public void setID(String id) {
88                     this.id = id;
89                 }
90             }
91
92             INeutronObject markerObject = new MarkerObject();
93
94             markerObject.setID(marker);
95
96             startPos = Collections.binarySearch(collection, markerObject, neutronObjectComparator);
97
98             if (!pageReverse){
99                 startPos = startPos + 1;
100             }
101             else {
102                 startPos = startPos - limit;
103             }
104
105         }
106
107         if (startPos == null) {
108             throw new ResourceNotFoundException("UUID for marker:" + marker + " could not be found");
109         }
110
111         if (startPos == 0){
112             firstPage = true;
113         }
114
115         if (startPos + limit >= collection.size()) {
116             collection = collection.subList(startPos, collection.size());
117             startMarker = collection.get(0).getID();
118             endMarker = collection.get(collection.size() - 1).getID();
119             lastPage = true;
120         }
121         else if (startPos < 0) {
122             if (startPos + limit > 0) {
123                 collection = collection.subList(0, startPos + limit);
124                 startMarker = collection.get(0).getID();
125                 endMarker = collection.get(collection.size() - 1).getID();
126                 firstPage = true;
127             }
128             else {
129                 throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker");
130             }
131         }
132         else {
133             collection = collection.subList(startPos, startPos + limit);
134             startMarker = collection.get(0).getID();
135             endMarker = collection.get(limit-1).getID();
136         }
137
138         if (!lastPage) {
139             NeutronPageLink next = new NeutronPageLink();
140             next.setRef("next");
141             next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker);
142             links.add(next);
143         }
144
145         if (!firstPage) {
146             NeutronPageLink previous = new NeutronPageLink();
147             previous.setRef("previous");
148             previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True");
149             links.add(previous);
150         }
151
152         return new PaginationResults(collection, links);
153     }
154 }