Add pagination for mounted resources of apidocs 95/83895/7
authorJie Han <han.jie@zte.com.cn>
Thu, 22 Aug 2019 12:06:24 +0000 (20:06 +0800)
committerRobert Varga <nite@hq.sk>
Mon, 9 Sep 2019 05:50:07 +0000 (05:50 +0000)
Only show 20 yang resource for one page when there're
large amount yang resoures from a mount point such that
the explorer would not clash.

Change-Id: I7f7180ae7464407933cee49bd4fe8d24db216f77
Signed-off-by: Jie Han <han.jie@zte.com.cn>
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java
restconf/sal-rest-docgen/src/main/resources/18/explorer/index.html
restconf/sal-rest-docgen/src/main/resources/18/explorer/lib/odl/list_mounts.js
restconf/sal-rest-docgen/src/main/resources/explorer/css/simplePagination.css [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/resources/explorer/index.html
restconf/sal-rest-docgen/src/main/resources/explorer/lib/jquery.simplePagination.js [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/resources/explorer/lib/odl/list_mounts.js
restconf/sal-rest-docgen/src/main/resources/explorer/lib/odl/page.js [new file with mode: 0644]
restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java

index c9726b0e10b1840a20dc74de5b14e1565f65deb4..bce08552d8678ddd4921b8297fe381fb2bb9fb6b 100644 (file)
@@ -35,6 +35,11 @@ import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList;
  */
 public class ApiDocServiceImpl implements ApiDocService {
 
+    public static final int DEFAULT_PAGESIZE = 20;
+    // Query parameter
+    private static final String TOTAL_PAGES = "totalPages";
+    private static final String PAGE_NUM = "pageNum";
+
     private final MountPointSwagger mountPointSwaggerDraft02;
     private final MountPointSwagger mountPointSwaggerRFC8040;
     private final ApiDocGeneratorDraftO2 apiDocGeneratorDraft02;
@@ -108,10 +113,26 @@ public class ApiDocServiceImpl implements ApiDocService {
     @Override
     public synchronized Response getMountRootDoc(final String instanceNum, final UriInfo uriInfo) {
         final ResourceList resourceList;
+
+        if (uriInfo.getQueryParameters().getFirst(TOTAL_PAGES) != null) {
+            if (isNew(uriInfo)) {
+                resourceList = mountPointSwaggerRFC8040.getResourceList(uriInfo, Long.parseLong(instanceNum));
+            } else {
+                resourceList = mountPointSwaggerDraft02.getResourceList(uriInfo, Long.parseLong(instanceNum));
+            }
+            int size = resourceList.getApis().size();
+            return Response.ok(size % DEFAULT_PAGESIZE == 0 ? size / DEFAULT_PAGESIZE
+                    : size / DEFAULT_PAGESIZE + 1).build();
+        }
+
+        final int pageNum = Integer.parseInt(uriInfo.getQueryParameters().getFirst(PAGE_NUM));
+
         if (isNew(uriInfo)) {
-            resourceList = mountPointSwaggerRFC8040.getResourceList(uriInfo, Long.parseLong(instanceNum));
+            resourceList = mountPointSwaggerRFC8040.getResourceList(uriInfo, Long.parseLong(instanceNum), pageNum,
+                    false);
         } else {
-            resourceList = mountPointSwaggerDraft02.getResourceList(uriInfo, Long.parseLong(instanceNum));
+            resourceList = mountPointSwaggerDraft02.getResourceList(uriInfo, Long.parseLong(instanceNum), pageNum,
+                    false);
         }
         return Response.ok(resourceList).build();
     }
index ce41fa0e109baf25c929d6c484a2b1849cfec4b0..e1f6b50cfe253f8881646e061fc4c8d127de6888 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.sal.rest.doc.impl;
 
+import static org.opendaylight.netconf.sal.rest.doc.impl.ApiDocServiceImpl.DEFAULT_PAGESIZE;
 import static org.opendaylight.netconf.sal.rest.doc.util.RestDocgenUtil.resolvePathArgumentsName;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -80,33 +81,47 @@ public abstract class BaseYangSwaggerGenerator {
     public ResourceList getResourceListing(final UriInfo uriInfo) {
         final SchemaContext schemaContext = schemaService.getGlobalContext();
         Preconditions.checkState(schemaContext != null);
-        return getResourceListing(uriInfo, schemaContext, "");
+        return getResourceListing(uriInfo, schemaContext, "", 0, true);
+    }
+
+    public ResourceList getResourceListing(final UriInfo uriInfo, final SchemaContext schemaContext,
+                                           final String context) {
+        return getResourceListing(uriInfo, schemaContext, context, 0, true);
     }
 
     /**
      * Return list of modules converted to swagger compliant resource list.
      */
     public ResourceList getResourceListing(final UriInfo uriInfo, final SchemaContext schemaContext,
-            final String context) {
+            final String context, final int pageNum, boolean all) {
 
         final ResourceList resourceList = createResourceList();
 
         final Set<Module> modules = getSortedModules(schemaContext);
 
-        final List<Resource> resources = new ArrayList<>(modules.size());
+        final List<Resource> resources = new ArrayList<>(DEFAULT_PAGESIZE);
 
         LOG.info("Modules found [{}]", modules.size());
-
+        final int start = DEFAULT_PAGESIZE * pageNum;
+        final int end = start + DEFAULT_PAGESIZE;
+        int count = 0;
         for (final Module module : modules) {
             final String revisionString = module.getQNameModule().getRevision().map(Revision::toString).orElse(null);
-            final Resource resource = new Resource();
+
             LOG.debug("Working on [{},{}]...", module.getName(), revisionString);
             final ApiDeclaration doc =
                     getApiDeclaration(module.getName(), revisionString, uriInfo, schemaContext, context);
-
             if (doc != null) {
-                resource.setPath(generatePath(uriInfo, module.getName(), revisionString));
-                resources.add(resource);
+                count++;
+                if (count >= start && count < end || all) {
+                    final Resource resource = new Resource();
+                    resource.setPath(generatePath(uriInfo, module.getName(), revisionString));
+                    resources.add(resource);
+                }
+
+                if (count >= end && !all) {
+                    break;
+                }
             } else {
                 LOG.warn("Could not generate doc for {},{}", module.getName(), revisionString);
             }
@@ -125,7 +140,7 @@ public abstract class BaseYangSwaggerGenerator {
     }
 
     public String generatePath(final UriInfo uriInfo, final String name, final String revision) {
-        final URI uri = uriInfo.getRequestUriBuilder().path(generateCacheKey(name, revision)).build();
+        final URI uri = uriInfo.getRequestUriBuilder().replaceQuery("").path(generateCacheKey(name, revision)).build();
         return uri.toASCIIString();
     }
 
index ad79f153fe0dd5cf6880ff53308c633060dec936..fe037cf47f323e6f752a7cc646b5eb0224099dae 100644 (file)
@@ -101,6 +101,10 @@ public class MountPointSwagger implements DOMMountPointListener, AutoCloseable {
     }
 
     public ResourceList getResourceList(final UriInfo uriInfo, final Long id) {
+        return getResourceList(uriInfo, id, 0, true);
+    }
+
+    public ResourceList getResourceList(final UriInfo uriInfo, final Long id, final int pageNum, boolean all) {
         final YangInstanceIdentifier iid = getInstanceId(id);
         if (iid == null) {
             return null; // indicating not found.
@@ -115,7 +119,7 @@ public class MountPointSwagger implements DOMMountPointListener, AutoCloseable {
         dataStores.setPath(swaggerGenerator.generatePath(uriInfo, DATASTORES_LABEL, DATASTORES_REVISION));
         resources.add(dataStores);
         final String urlPrefix = getYangMountUrl(iid);
-        final ResourceList list = swaggerGenerator.getResourceListing(uriInfo, context, urlPrefix);
+        final ResourceList list = swaggerGenerator.getResourceListing(uriInfo, context, urlPrefix, pageNum, all);
         resources.addAll(list.getApis());
         list.setApis(resources);
         return list;
index ddb047fc86de00772f5770ad4e09f1ec467726e9..22c728ab4ccd81fff7f555e25d98775fdb947870 100644 (file)
@@ -19,6 +19,8 @@
     <link rel="stylesheet" type="text/css" href="../../explorer/static/opendaylight.css">\r
     <link rel="stylesheet" type="text/css"\r
           href="../../explorer/css/ui-lightness/jquery-ui-1.10.4.custom.min.css">\r
+    <link rel="stylesheet" type="text/css"\r
+          href="../../explorer/css/simplePagination.css">\r
     <script type="text/javascript" src="../../explorer/lib/shred.bundle.js"></script>\r
     <script src='../../explorer/lib/jquery-1.8.0.min.js' type='text/javascript'></script>\r
     <script src='../../explorer/lib/jquery-ui-1.11.0.min.js' type="text/javascript"></script>\r
@@ -33,6 +35,8 @@
     <script src='lib/odl/list_mounts.js' type='text/javascript'></script>\r
     <script src='../../explorer/lib/highlight.7.3.pack.js' type='text/javascript'></script>\r
     <script src='../../explorer/lib/odl/swagger.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/odl/page.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/jquery.simplePagination.js' type='text/javascript'></script>\r
 \r
     <script type="text/javascript">\r
 \r
@@ -42,6 +46,7 @@
         $("#message").append( "<p>Loading...</p>" );\r
         loadSwagger("/apidoc/18/apis/mounts/" + mountIndex,\r
                 "swagger-ui-container");\r
+        loadPagination("/apidoc/18/apis/mounts/", mountIndex, mountPath, "swagger-ui-container");\r
         $("#message").empty();\r
         $("#message").append( "<h2><b>Showing mount points for " + mountPath + "</b></h2>");\r
         }\r
 \r
 <!-- the swagger is always loaded in this div -->\r
 <div id="swagger-ui-container" class="swagger-ui-wrap"></div>\r
-\r
+<div class="pagination-holder clearfix">\r
+    <div id="light-pagination" class="pagination light-theme simple-pagination"></div>\r
+</div>\r
 <div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>\r
 </body>\r
 \r
index 39e26d069f72a3b76598b13574f1267ad3acc4b7..63390c30d5754942594679671fbad516f05b3f55 100644 (file)
@@ -12,7 +12,7 @@ var loadMountList = function( dom ) {
             for( var key in myData )
             {
                 list.append( "<tr><td><a href=\"#\" onclick=\"loadMount(" +
-                        myData[key].id + ", '" + myData[key].instance + "')\">" +
+                        myData[key].id + ", 0, '" + myData[key].instance + "')\">" +
                         myData[key].instance + "</a></td></tr>");
             }
             dom.empty();
diff --git a/restconf/sal-rest-docgen/src/main/resources/explorer/css/simplePagination.css b/restconf/sal-rest-docgen/src/main/resources/explorer/css/simplePagination.css
new file mode 100644 (file)
index 0000000..2b784bc
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+* CSS themes for simplePagination.js
+* Author: Flavius Matis - http://flaviusmatis.github.com/
+* URL: https://github.com/flaviusmatis/simplePagination.js
+*/
+
+ul.simple-pagination {
+       list-style: none;
+}
+
+.simple-pagination {
+       display: block;
+       overflow: hidden;
+       padding: 0 5px 5px 0;
+       margin: 0;
+}
+
+.simple-pagination ul {
+       list-style: none;
+       padding: 0;
+       margin: 20px auto;
+       display:table
+}
+
+.simple-pagination li {
+       list-style: none;
+       padding: 0;
+       margin: 0;
+       float: left;
+       display:table-cell
+}
+span.ellipse.clickable {
+       cursor: pointer;
+}
+
+.ellipse input {
+       width: 3em;
+}
+
+/*------------------------------------*\
+       Compact Theme Styles
+\*------------------------------------*/
+.compact-theme span {
+       cursor:pointer;
+}
+
+.compact-theme a, .compact-theme span {
+       float: left;
+       color: #333;
+       font-size:14px;
+       line-height:24px;
+       font-weight: normal;
+       text-align: center;
+       border: 1px solid #AAA;
+       border-left: none;
+       min-width: 14px;
+       padding: 0 7px;
+       box-shadow: 2px 2px 2px rgba(0,0,0,0.2);
+       background: #efefef; /* Old browsers */
+       background: -moz-linear-gradient(top, #ffffff 0%, #efefef 100%); /* FF3.6+ */
+       background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#efefef)); /* Chrome,Safari4+ */
+       background: -webkit-linear-gradient(top, #ffffff 0%,#efefef 100%); /* Chrome10+,Safari5.1+ */
+       background: -o-linear-gradient(top, #ffffff 0%,#efefef 100%); /* Opera11.10+ */
+       background: -ms-linear-gradient(top, #ffffff 0%,#efefef 100%); /* IE10+ */
+       background: linear-gradient(top, #ffffff 0%,#efefef 100%); /* W3C */
+}
+
+.compact-theme a:hover, .compact-theme li:not(.disabled):not(.active) span:hover {
+       text-decoration: none;
+       background: #efefef; /* Old browsers */
+       background: -moz-linear-gradient(top, #efefef 0%, #bbbbbb 100%); /* FF3.6+ */
+       background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#efefef), color-stop(100%,#bbbbbb)); /* Chrome,Safari4+ */
+       background: -webkit-linear-gradient(top, #efefef 0%,#bbbbbb 100%); /* Chrome10+,Safari5.1+ */
+       background: -o-linear-gradient(top, #efefef 0%,#bbbbbb 100%); /* Opera11.10+ */
+       background: -ms-linear-gradient(top, #efefef 0%,#bbbbbb 100%); /* IE10+ */
+       background: linear-gradient(top, #efefef 0%,#bbbbbb 100%); /* W3C */
+}
+
+.compact-theme li:first-child a, .compact-theme li:first-child span {
+       border-left: 1px solid #AAA;
+       border-radius: 3px 0 0 3px;
+}
+
+.compact-theme li:last-child a, .compact-theme li:last-child span {
+       border-radius: 0 3px 3px 0;
+}
+
+.compact-theme .current {
+       background: #bbbbbb; /* Old browsers */
+       background: -moz-linear-gradient(top, #bbbbbb 0%, #efefef 100%); /* FF3.6+ */
+       background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#bbbbbb), color-stop(100%,#efefef)); /* Chrome,Safari4+ */
+       background: -webkit-linear-gradient(top, #bbbbbb 0%,#efefef 100%); /* Chrome10+,Safari5.1+ */
+       background: -o-linear-gradient(top, #bbbbbb 0%,#efefef 100%); /* Opera11.10+ */
+       background: -ms-linear-gradient(top, #bbbbbb 0%,#efefef 100%); /* IE10+ */
+       background: linear-gradient(top, #bbbbbb 0%,#efefef 100%); /* W3C */
+       cursor: default;
+}
+
+.compact-theme .ellipse {
+       background: #EAEAEA;
+       padding: 0 10px;
+       cursor: default;
+}
+
+/*------------------------------------*\
+       Light Theme Styles
+\*------------------------------------*/
+.light-theme span {
+       cursor:pointer;
+}
+
+.light-theme a, .light-theme span {
+       float: left;
+       color: #666;
+       font-size:14px;
+       line-height:24px;
+       font-weight: normal;
+       text-align: center;
+       border: 1px solid #BBB;
+       min-width: 14px;
+       padding: 0 7px;
+       margin: 0 5px 0 0;
+       border-radius: 3px;
+       box-shadow: 0 1px 2px rgba(0,0,0,0.2);
+       background: #efefef; /* Old browsers */
+       background: -moz-linear-gradient(top, #ffffff 0%, #efefef 100%); /* FF3.6+ */
+       background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#efefef)); /* Chrome,Safari4+ */
+       background: -webkit-linear-gradient(top, #ffffff 0%,#efefef 100%); /* Chrome10+,Safari5.1+ */
+       background: -o-linear-gradient(top, #ffffff 0%,#efefef 100%); /* Opera11.10+ */
+       background: -ms-linear-gradient(top, #ffffff 0%,#efefef 100%); /* IE10+ */
+       background: linear-gradient(top, #ffffff 0%,#efefef 100%); /* W3C */
+}
+
+.light-theme a:hover, .light-theme li:not(.disabled):not(.active) span:hover {
+       text-decoration: none;
+       background: #FCFCFC;
+}
+
+.light-theme .current {
+       background: #666;
+       color: #FFF;
+       border-color: #444;
+       box-shadow: 0 1px 0 rgba(255,255,255,1), 0 0 2px rgba(0, 0, 0, 0.3) inset;
+       cursor: default;
+}
+
+.light-theme .ellipse {
+       background: none;
+       border: none;
+       border-radius: 0;
+       box-shadow: none;
+       font-weight: bold;
+       cursor: default;
+}
+
+/*------------------------------------*\
+       Dark Theme Styles
+\*------------------------------------*/
+.dark-theme span {
+       cursor:pointer;
+}
+
+.dark-theme a, .dark-theme span {
+       float: left;
+       color: #CCC;
+       font-size:14px;
+       line-height:24px;
+       font-weight: normal;
+       text-align: center;
+       border: 1px solid #222;
+       min-width: 14px;
+       padding: 0 7px;
+       margin: 0 5px 0 0;
+       border-radius: 3px;
+       box-shadow: 0 1px 2px rgba(0,0,0,0.2);
+       background: #555; /* Old browsers */
+       background: -moz-linear-gradient(top, #555 0%, #333 100%); /* FF3.6+ */
+       background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#555), color-stop(100%,#333)); /* Chrome,Safari4+ */
+       background: -webkit-linear-gradient(top, #555 0%,#333 100%); /* Chrome10+,Safari5.1+ */
+       background: -o-linear-gradient(top, #555 0%,#333 100%); /* Opera11.10+ */
+       background: -ms-linear-gradient(top, #555 0%,#333 100%); /* IE10+ */
+       background: linear-gradient(top, #555 0%,#333 100%); /* W3C */
+}
+
+.dark-theme a:hover, .dark-theme li:not(.disabled):not(.active) span:hover {
+       text-decoration: none;
+       background: #444;
+}
+
+.dark-theme .current {
+       background: #222;
+       color: #FFF;
+       border-color: #000;
+       box-shadow: 0 1px 0 rgba(255,255,255,0.2), 0 0 1px 1px rgba(0, 0, 0, 0.1) inset;
+       cursor: default;
+}
+
+.dark-theme .ellipse {
+       background: none;
+       border: none;
+       border-radius: 0;
+       box-shadow: none;
+       font-weight: bold;
+       cursor: default;
+}
index b2f76fa6db28e1201c4e8e107c21898e03295d79..5181bdbb9d14fac84a7c54b201a7ad860175b728 100644 (file)
@@ -11,6 +11,8 @@
 <link rel="stylesheet" type="text/css" href="static/opendaylight.css">\r
 <link rel="stylesheet" type="text/css"\r
        href="css/ui-lightness/jquery-ui-1.10.4.custom.min.css">\r
+<link rel="stylesheet" type="text/css" href="css/simplePagination.css">\r
+\r
 <script type="text/javascript" src="lib/shred.bundle.js"></script>\r
 <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>\r
 <script src='lib/jquery-ui-1.11.0.min.js' type="text/javascript"></script>\r
 <script src='lib/odl/list_mounts.js' type='text/javascript'></script>\r
 <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>\r
 <script src='lib/odl/swagger.js' type='text/javascript'></script>\r
+<script src='lib/odl/page.js' type='text/javascript'></script>\r
+<script src='lib/jquery.simplePagination.js' type='text/javascript'></script>\r
 \r
 <script type="text/javascript">\r
        \r
        //reloads the swagger UI documentation for the specified mount.\r
-       var loadMount = function(mountIndex, mountPath) {\r
+       var loadMount = function(mountIndex, pageNum, mountPath) {\r
                $("#message").empty();\r
                $("#message").append( "<p>Loading...</p>" );\r
-               loadSwagger("/apidoc/apis/mounts/" + mountIndex,\r
-                               "swagger-ui-container");\r
+               loadSwagger("/apidoc/apis/mounts/" + mountIndex + "?pageNum=" + pageNum,\r
+                               "swagger-ui-container", mountIndex, mountPath);\r
+               loadPagination("/apidoc/apis/mounts/", mountIndex, mountPath, "swagger-ui-container");\r
                $("#message").empty();\r
                $("#message").append( "<h2><b>Showing mount points for " + mountPath + "</b></h2>");\r
        }\r
@@ -59,6 +64,7 @@
 \r
                loadRootSwagger();\r
        });\r
+\r
 </script>\r
 </head>\r
 \r
        \r
        <!-- the swagger is always loaded in this div -->\r
        <div id="swagger-ui-container" class="swagger-ui-wrap"></div>\r
-\r
+       <div class="pagination-holder clearfix">\r
+               <div id="light-pagination" class="pagination light-theme simple-pagination"></div>\r
+       </div>\r
        <div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>\r
 </body>\r
 \r
diff --git a/restconf/sal-rest-docgen/src/main/resources/explorer/lib/jquery.simplePagination.js b/restconf/sal-rest-docgen/src/main/resources/explorer/lib/jquery.simplePagination.js
new file mode 100644 (file)
index 0000000..1108cdc
--- /dev/null
@@ -0,0 +1,398 @@
+/**
+* simplePagination.js v1.6
+* A simple jQuery pagination plugin.
+* http://flaviusmatis.github.com/simplePagination.js/
+*
+* Copyright 2012, Flavius Matis
+* Released under the MIT license.
+* http://flaviusmatis.github.com/license.html
+*/
+
+(function($){
+
+       var methods = {
+               init: function(options) {
+                       var o = $.extend({
+                               items: 1,
+                               itemsOnPage: 1,
+                               pages: 0,
+                               displayedPages: 5,
+                               edges: 2,
+                               currentPage: 0,
+                               useAnchors: true,
+                               hrefTextPrefix: '#page-',
+                               hrefTextSuffix: '',
+                               prevText: 'Prev',
+                               nextText: 'Next',
+                               ellipseText: '&hellip;',
+                               ellipsePageSet: true,
+                               cssStyle: 'light-theme',
+                               listStyle: '',
+                               labelMap: [],
+                               selectOnClick: true,
+                               nextAtFront: false,
+                               invertPageOrder: false,
+                               useStartEdge : true,
+                               useEndEdge : true,
+                               onPageClick: function(pageNumber, event) {
+                                       // Callback triggered when a page is clicked
+                                       // Page number is given as an optional parameter
+                               },
+                               onInit: function() {
+                                       // Callback triggered immediately after initialization
+                               }
+                       }, options || {});
+
+                       var self = this;
+
+                       o.pages = o.pages ? o.pages : Math.ceil(o.items / o.itemsOnPage) ? Math.ceil(o.items / o.itemsOnPage) : 1;
+                       if (o.currentPage)
+                               o.currentPage = o.currentPage - 1;
+                       else
+                               o.currentPage = !o.invertPageOrder ? 0 : o.pages - 1;
+                       o.halfDisplayed = o.displayedPages / 2;
+
+                       this.each(function() {
+                               self.addClass(o.cssStyle + ' simple-pagination').data('pagination', o);
+                               methods._draw.call(self);
+                       });
+
+                       o.onInit();
+
+                       return this;
+               },
+
+               selectPage: function(page) {
+                       methods._selectPage.call(this, page - 1);
+                       return this;
+               },
+
+               prevPage: function() {
+                       var o = this.data('pagination');
+                       if (!o.invertPageOrder) {
+                               if (o.currentPage > 0) {
+                                       methods._selectPage.call(this, o.currentPage - 1);
+                               }
+                       } else {
+                               if (o.currentPage < o.pages - 1) {
+                                       methods._selectPage.call(this, o.currentPage + 1);
+                               }
+                       }
+                       return this;
+               },
+
+               nextPage: function() {
+                       var o = this.data('pagination');
+                       if (!o.invertPageOrder) {
+                               if (o.currentPage < o.pages - 1) {
+                                       methods._selectPage.call(this, o.currentPage + 1);
+                               }
+                       } else {
+                               if (o.currentPage > 0) {
+                                       methods._selectPage.call(this, o.currentPage - 1);
+                               }
+                       }
+                       return this;
+               },
+
+               getPagesCount: function() {
+                       return this.data('pagination').pages;
+               },
+
+               setPagesCount: function(count) {
+                       this.data('pagination').pages = count;
+               },
+
+               getCurrentPage: function () {
+                       return this.data('pagination').currentPage + 1;
+               },
+
+               destroy: function(){
+                       this.empty();
+                       return this;
+               },
+
+               drawPage: function (page) {
+                       var o = this.data('pagination');
+                       o.currentPage = page - 1;
+                       this.data('pagination', o);
+                       methods._draw.call(this);
+                       return this;
+               },
+
+               redraw: function(){
+                       methods._draw.call(this);
+                       return this;
+               },
+
+               disable: function(){
+                       var o = this.data('pagination');
+                       o.disabled = true;
+                       this.data('pagination', o);
+                       methods._draw.call(this);
+                       return this;
+               },
+
+               enable: function(){
+                       var o = this.data('pagination');
+                       o.disabled = false;
+                       this.data('pagination', o);
+                       methods._draw.call(this);
+                       return this;
+               },
+
+               updateItems: function (newItems) {
+                       var o = this.data('pagination');
+                       o.items = newItems;
+                       o.pages = methods._getPages(o);
+                       this.data('pagination', o);
+                       methods._draw.call(this);
+               },
+
+               updateItemsOnPage: function (itemsOnPage) {
+                       var o = this.data('pagination');
+                       o.itemsOnPage = itemsOnPage;
+                       o.pages = methods._getPages(o);
+                       this.data('pagination', o);
+                       methods._selectPage.call(this, 0);
+                       return this;
+               },
+
+               getItemsOnPage: function() {
+                       return this.data('pagination').itemsOnPage;
+               },
+
+               _draw: function() {
+                       var     o = this.data('pagination'),
+                               interval = methods._getInterval(o),
+                               i,
+                               tagName;
+
+                       methods.destroy.call(this);
+
+                       tagName = (typeof this.prop === 'function') ? this.prop('tagName') : this.attr('tagName');
+
+                       var $panel = tagName === 'UL' ? this : $('<ul' + (o.listStyle ? ' class="' + o.listStyle + '"' : '') + '></ul>').appendTo(this);
+
+                       // Generate Prev link
+                       if (o.prevText) {
+                               methods._appendItem.call(this, !o.invertPageOrder ? o.currentPage - 1 : o.currentPage + 1, {text: o.prevText, classes: 'prev'});
+                       }
+
+                       // Generate Next link (if option set for at front)
+                       if (o.nextText && o.nextAtFront) {
+                               methods._appendItem.call(this, !o.invertPageOrder ? o.currentPage + 1 : o.currentPage - 1, {text: o.nextText, classes: 'next'});
+                       }
+
+                       // Generate start edges
+                       if (!o.invertPageOrder) {
+                               if (interval.start > 0 && o.edges > 0) {
+                                       if(o.useStartEdge) {
+                                               var end = Math.min(o.edges, interval.start);
+                                               for (i = 0; i < end; i++) {
+                                                       methods._appendItem.call(this, i);
+                                               }
+                                       }
+                                       if (o.edges < interval.start && (interval.start - o.edges != 1)) {
+                                               $panel.append('<li class="disabled"><span class="ellipse">' + o.ellipseText + '</span></li>');
+                                       } else if (interval.start - o.edges == 1) {
+                                               methods._appendItem.call(this, o.edges);
+                                       }
+                               }
+                       } else {
+                               if (interval.end < o.pages && o.edges > 0) {
+                                       if(o.useStartEdge) {
+                                               var begin = Math.max(o.pages - o.edges, interval.end);
+                                               for (i = o.pages - 1; i >= begin; i--) {
+                                                       methods._appendItem.call(this, i);
+                                               }
+                                       }
+
+                                       if (o.pages - o.edges > interval.end && (o.pages - o.edges - interval.end != 1)) {
+                                               $panel.append('<li class="disabled"><span class="ellipse">' + o.ellipseText + '</span></li>');
+                                       } else if (o.pages - o.edges - interval.end == 1) {
+                                               methods._appendItem.call(this, interval.end);
+                                       }
+                               }
+                       }
+
+                       // Generate interval links
+                       if (!o.invertPageOrder) {
+                               for (i = interval.start; i < interval.end; i++) {
+                                       methods._appendItem.call(this, i);
+                               }
+                       } else {
+                               for (i = interval.end - 1; i >= interval.start; i--) {
+                                       methods._appendItem.call(this, i);
+                               }
+                       }
+
+                       // Generate end edges
+                       if (!o.invertPageOrder) {
+                               if (interval.end < o.pages && o.edges > 0) {
+                                       if (o.pages - o.edges > interval.end && (o.pages - o.edges - interval.end != 1)) {
+                                               $panel.append('<li class="disabled"><span class="ellipse">' + o.ellipseText + '</span></li>');
+                                       } else if (o.pages - o.edges - interval.end == 1) {
+                                               methods._appendItem.call(this, interval.end);
+                                       }
+                                       if(o.useEndEdge) {
+                                               var begin = Math.max(o.pages - o.edges, interval.end);
+                                               for (i = begin; i < o.pages; i++) {
+                                                       methods._appendItem.call(this, i);
+                                               }
+                                       }
+                               }
+                       } else {
+                               if (interval.start > 0 && o.edges > 0) {
+                                       if (o.edges < interval.start && (interval.start - o.edges != 1)) {
+                                               $panel.append('<li class="disabled"><span class="ellipse">' + o.ellipseText + '</span></li>');
+                                       } else if (interval.start - o.edges == 1) {
+                                               methods._appendItem.call(this, o.edges);
+                                       }
+
+                                       if(o.useEndEdge) {
+                                               var end = Math.min(o.edges, interval.start);
+                                               for (i = end - 1; i >= 0; i--) {
+                                                       methods._appendItem.call(this, i);
+                                               }
+                                       }
+                               }
+                       }
+
+                       // Generate Next link (unless option is set for at front)
+                       if (o.nextText && !o.nextAtFront) {
+                               methods._appendItem.call(this, !o.invertPageOrder ? o.currentPage + 1 : o.currentPage - 1, {text: o.nextText, classes: 'next'});
+                       }
+
+                       if (o.ellipsePageSet && !o.disabled) {
+                               methods._ellipseClick.call(this, $panel);
+                       }
+
+               },
+
+               _getPages: function(o) {
+                       var pages = Math.ceil(o.items / o.itemsOnPage);
+                       return pages || 1;
+               },
+
+               _getInterval: function(o) {
+                       return {
+                               start: Math.ceil(o.currentPage > o.halfDisplayed ? Math.max(Math.min(o.currentPage - o.halfDisplayed, (o.pages - o.displayedPages)), 0) : 0),
+                               end: Math.ceil(o.currentPage > o.halfDisplayed ? Math.min(o.currentPage + o.halfDisplayed, o.pages) : Math.min(o.displayedPages, o.pages))
+                       };
+               },
+
+               _appendItem: function(pageIndex, opts) {
+                       var self = this, options, $link, o = self.data('pagination'), $linkWrapper = $('<li></li>'), $ul = self.find('ul');
+
+                       pageIndex = pageIndex < 0 ? 0 : (pageIndex < o.pages ? pageIndex : o.pages - 1);
+
+                       options = {
+                               text: pageIndex + 1,
+                               classes: ''
+                       };
+
+                       if (o.labelMap.length && o.labelMap[pageIndex]) {
+                               options.text = o.labelMap[pageIndex];
+                       }
+
+                       options = $.extend(options, opts || {});
+
+                       if (pageIndex == o.currentPage || o.disabled) {
+                               if (o.disabled || options.classes === 'prev' || options.classes === 'next') {
+                                       $linkWrapper.addClass('disabled');
+                               } else {
+                                       $linkWrapper.addClass('active');
+                               }
+                               $link = $('<span class="current">' + (options.text) + '</span>');
+                       } else {
+                               if (o.useAnchors) {
+                                       $link = $('<a href="' + o.hrefTextPrefix + (pageIndex + 1) + o.hrefTextSuffix + '" class="page-link">' + (options.text) + '</a>');
+                               } else {
+                                       $link = $('<span >' + (options.text) + '</span>');
+                               }
+                               $link.click(function(event){
+                                       return methods._selectPage.call(self, pageIndex, event);
+                               });
+                       }
+
+                       if (options.classes) {
+                               $link.addClass(options.classes);
+                       }
+
+                       $linkWrapper.append($link);
+
+                       if ($ul.length) {
+                               $ul.append($linkWrapper);
+                       } else {
+                               self.append($linkWrapper);
+                       }
+               },
+
+               _selectPage: function(pageIndex, event) {
+                       var o = this.data('pagination');
+                       o.currentPage = pageIndex;
+                       if (o.selectOnClick) {
+                               methods._draw.call(this);
+                       }
+                       return o.onPageClick(pageIndex + 1, event);
+               },
+
+
+               _ellipseClick: function($panel) {
+                       var self = this,
+                               o = this.data('pagination'),
+                               $ellip = $panel.find('.ellipse');
+                       $ellip.addClass('clickable').parent().removeClass('disabled');
+                       $ellip.click(function(event) {
+                               if (!o.disable) {
+                                       var $this = $(this),
+                                               val = (parseInt($this.parent().prev().text(), 10) || 0) + 1;
+                                       $this
+                                               .html('<input type="number" min="1" max="' + o.pages + '" step="1" value="' + val + '">')
+                                               .find('input')
+                                               .focus()
+                                               .click(function(event) {
+                                                       // prevent input number arrows from bubbling a click event on $ellip
+                                                       event.stopPropagation();
+                                               })
+                                               .keyup(function(event) {
+                                                       var val = $(this).val();
+                                                       if (event.which === 13 && val !== '') {
+                                                               // enter to accept
+                                                               if ((val>0)&&(val<=o.pages))
+                                                               methods._selectPage.call(self, val - 1);
+                                                       } else if (event.which === 27) {
+                                                               // escape to cancel
+                                                               $ellip.empty().html(o.ellipseText);
+                                                       }
+                                               })
+                                               .bind('blur', function(event) {
+                                                       var val = $(this).val();
+                                                       if (val !== '') {
+                                                               methods._selectPage.call(self, val - 1);
+                                                       }
+                                                       $ellip.empty().html(o.ellipseText);
+                                                       return false;
+                                               });
+                               }
+                               return false;
+                       });
+               }
+
+       };
+
+       $.fn.pagination = function(method) {
+
+               // Method calling logic
+               if (methods[method] && method.charAt(0) != '_') {
+                       return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+               } else if (typeof method === 'object' || !method) {
+                       return methods.init.apply(this, arguments);
+               } else {
+                       $.error('Method ' +  method + ' does not exist on jQuery.pagination');
+               }
+
+       };
+
+})(jQuery);
index bfd561a21eb27bd572b7e09069021287b4f500a0..f4305336fb73995f89dc98adff258d73ef2684ff 100644 (file)
@@ -12,7 +12,7 @@ var loadMountList = function( dom ) {
             for( var key in myData )
             {
                 list.append( "<tr><td><a href=\"#\" onclick=\"loadMount(" + 
-                                        myData[key].id + ", '" + myData[key].instance + "')\">" +
+                                        myData[key].id + ", 0, '" + myData[key].instance + "')\">" +
                                         myData[key].instance + "</a></td></tr>");
             }
             dom.empty();
diff --git a/restconf/sal-rest-docgen/src/main/resources/explorer/lib/odl/page.js b/restconf/sal-rest-docgen/src/main/resources/explorer/lib/odl/page.js
new file mode 100644 (file)
index 0000000..5dff488
--- /dev/null
@@ -0,0 +1,20 @@
+//constructs a pagination
+var loadPagination= function(url, mountIndex, mountPath, dom_id) {
+    $.ajax( {
+        url: url + mountIndex + "?totalPages",
+        datatype: 'jsonp',
+        success: function( strData ){
+            var totalPages = strData;
+            $(function() {
+                $('#light-pagination').pagination({
+                    pages: totalPages,
+                    cssStyle: 'light-theme',
+                    onPageClick: function(pageNumber, event) {
+                        loadSwagger(url + mountIndex + "?pageNum=" + pageNumber,
+                            dom_id, mountIndex, mountPath);
+                    }
+                });
+            });
+        }
+    } );
+}
\ No newline at end of file
index 0b302547c319f93d0ac0dc622900471fb9181f92..af8670c63654d4ebd4a80c5a7a8a84eb00f3a23b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.sal.rest.doc.impl;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -121,6 +122,7 @@ public class DocGenTestHelper {
         final UriInfo info = mock(UriInfo.class);
 
         when(info.getRequestUriBuilder()).thenReturn(mockBuilder);
+        when(mockBuilder.replaceQuery(any())).thenReturn(mockBuilder);
         when(info.getBaseUri()).thenReturn(uri);
         return info;
     }