ONOS-6980 Adding support for download of application bits.

Change-Id: I742950690b50038cac0bb2ad2da4eaac5781da85
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationResource.java b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationResource.java
index d245eff..16f288a 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationResource.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationResource.java
@@ -58,6 +58,26 @@
         return Response.ok().build();
     }
 
+    /**
+     * Get application OAR/JAR file.
+     * Returns the OAR/JAR file used to install the specified application.
+     *
+     * @param name application name
+     * @return 200 OK; 404; 401
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    @Path("{name}/download")
+    public Response download(@PathParam("name") String name) {
+        ApplicationAdminService service = get(ApplicationAdminService.class);
+        ApplicationId appId = service.getId(name);
+        InputStream bits = service.getApplicationArchive(appId);
+        String fileName = appId.name() + ".oar";
+        return Response.ok(bits)
+                .header("Content-Disposition", "attachment; filename=\"" + fileName + "\"")
+                .build();
+    }
+
     @Path("{name}/icon")
     @GET
     @Produces("image/png")
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/App.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/App.properties
index 5ce011a..b362edd 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/App.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/App.properties
@@ -26,6 +26,7 @@
 tt_ctl_activate=Activate selected application
 tt_ctl_deactivate=Deactivate selected application
 tt_ctl_uninstall=Uninstall selected application
+tt_ctl_download=Download selected application (.oar file)
 
 # Quick-Help panel
 qh_hint_esc=Deselect application
diff --git a/web/gui/src/main/webapp/app/view/app/app.css b/web/gui/src/main/webapp/app/view/app/app.css
index 9eb8ba8..4d61f81 100644
--- a/web/gui/src/main/webapp/app/view/app/app.css
+++ b/web/gui/src/main/webapp/app/view/app/app.css
@@ -23,7 +23,7 @@
 }
 
 #ov-app div.ctrl-btns {
-    width: 250px;
+    width: 290px;
 }
 
 /* -- Drag-n-Drop oar file upload -- */
diff --git a/web/gui/src/main/webapp/app/view/app/app.html b/web/gui/src/main/webapp/app/view/app/app.html
index 6eaa126..e371248 100644
--- a/web/gui/src/main/webapp/app/view/app/app.html
+++ b/web/gui/src/main/webapp/app/view/app/app.html
@@ -38,6 +38,12 @@
                  tooltip tt-msg="uninstallTip"
                  ng-class="{active: ctrlBtnState.selection}">
             </div>
+            <!-- FIXME: create proper download icon -->
+            <div icon icon-size="42" icon-id="downArrow"
+                 ng-click="downloadApp()"
+                 tooltip tt-msg="downloadTip"
+                 ng-class="{active: ctrlBtnState.selection}">
+            </div>
         </div>
     </div>
 
diff --git a/web/gui/src/main/webapp/app/view/app/app.js b/web/gui/src/main/webapp/app/view/app/app.js
index a01dd2e..5a2272e 100644
--- a/web/gui/src/main/webapp/app/view/app/app.js
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -45,8 +45,9 @@
         detailsResp = 'appDetailsResponse',
         fileUploadUrl = 'applications/upload',
         activateOption = '?activate=true',
-        iconUrlPrefix = 'rs/applications/',
+        appUrlPrefix = 'rs/applications/',
         iconUrlSuffix = '/icon',
+        downloadSuffix = '/download',
         dialogId = 'app-dialog',
         dialogOpts = {
             edge: 'right',
@@ -167,7 +168,7 @@
     }
 
     function addIcon(elem, value) {
-        elem.append('img').attr('src', iconUrlPrefix + value + iconUrlSuffix);
+        elem.append('img').attr('src', appUrlPrefix + value + iconUrlSuffix);
     }
 
     function populateTop(details) {
@@ -250,6 +251,7 @@
         $scope.activateTip = lion('tt_ctl_activate');
         $scope.deactivateTip = lion('tt_ctl_deactivate');
         $scope.uninstallTip = lion('tt_ctl_uninstall');
+        $scope.downloadTip = lion('tt_ctl_download');
 
 
         var handlers = {};
@@ -359,6 +361,12 @@
             }
         };
 
+        $scope.downloadApp = function () {
+            if ($scope.ctrlBtnState.selection) {
+                window.location = appUrlPrefix + $scope.selId + downloadSuffix;
+            }
+        };
+
         $scope.$on('FileChanged', function () {
             var formData = new FormData(),
                 url;