001/* 002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 */ 020package org.nuxeo.connect.client.we; 021 022import java.util.Arrays; 023import java.util.List; 024 025import javax.ws.rs.GET; 026import javax.ws.rs.Path; 027import javax.ws.rs.PathParam; 028import javax.ws.rs.Produces; 029import javax.ws.rs.QueryParam; 030import javax.ws.rs.core.MediaType; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.nuxeo.connect.connector.ConnectServerError; 035import org.nuxeo.connect.data.DownloadablePackage; 036import org.nuxeo.connect.data.DownloadingPackage; 037import org.nuxeo.connect.downloads.ConnectDownloadManager; 038import org.nuxeo.connect.packages.PackageManager; 039import org.nuxeo.connect.update.PackageState; 040import org.nuxeo.ecm.webengine.model.WebObject; 041import org.nuxeo.ecm.webengine.model.impl.DefaultObject; 042import org.nuxeo.runtime.api.Framework; 043 044/** 045 * Provides REST binding for {@link org.nuxeo.connect.update.Package} download management. 046 * 047 * @author <a href="mailto:td@nuxeo.com">Thierry Delprat</a> 048 */ 049@WebObject(type = "downloadHandler") 050public class DownloadHandler extends DefaultObject { 051 052 protected static final Log log = LogFactory.getLog(DownloadHandler.class); 053 054 @GET 055 @Produces("text/plain") 056 @Path(value = "progress/{pkgId}") 057 public String getDownloadProgress(@PathParam("pkgId") String pkgId) { 058 DownloadingPackage pkg = getDownloadingPackage(pkgId); 059 if (pkg == null) { 060 return null; 061 } 062 return pkg.getDownloadProgress() + ""; 063 } 064 065 @GET 066 @Produces(MediaType.APPLICATION_JSON) 067 @Path(value = "progressAsJSON") 068 public String getDownloadsProgress() { 069 ConnectDownloadManager cdm = Framework.getService(ConnectDownloadManager.class); 070 List<DownloadingPackage> pkgs = cdm.listDownloadingPackages(); 071 StringBuilder sb = new StringBuilder(); 072 sb.append("["); 073 for (int i = 0; i < pkgs.size(); i++) { 074 if (i > 0) { 075 sb.append(","); 076 } 077 sb.append("{ \"pkgid\" : ") 078 .append("\"") 079 .append(pkgs.get(i).getId()) 080 .append("\",") 081 .append(" \"progress\" : ") 082 .append(pkgs.get(i).getDownloadProgress()) 083 .append("}"); 084 } 085 sb.append("]"); 086 return sb.toString(); 087 } 088 089 @GET 090 @Produces("text/html") 091 @Path(value = "progressPage/{pkgId}") 092 public Object getDownloadProgressPage(@PathParam("pkgId") String pkgId, @QueryParam("source") String source, 093 @QueryParam("install") Boolean install, @QueryParam("depCheck") Boolean depCheck, 094 @QueryParam("type") String pkgType, @QueryParam("onlyRemote") Boolean onlyRemote, 095 @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 096 DownloadablePackage pkg = getDownloadingPackage(pkgId); 097 boolean downloadOver = false; 098 // flag to start install after download 099 if (install == null) { 100 install = false; 101 } 102 if (depCheck == null) { 103 depCheck = true; 104 } 105 if (pkg == null) { 106 PackageManager pm = Framework.getService(PackageManager.class); 107 pkg = pm.getPackage(pkgId); 108 if (pkg.getPackageState() != PackageState.DOWNLOADING) { 109 downloadOver = true; 110 } 111 } 112 return getView("downloadStarted").arg("pkg", pkg) 113 .arg("source", source) 114 .arg("over", downloadOver) 115 .arg("install", install) 116 .arg("depCheck", depCheck) 117 .arg("filterOnPlatform", filterOnPlatform.toString()) 118 .arg("type", pkgType.toString()) 119 .arg("onlyRemote", onlyRemote.toString()); 120 } 121 122 protected DownloadingPackage getDownloadingPackage(String pkgId) { 123 ConnectDownloadManager cdm = Framework.getService(ConnectDownloadManager.class); 124 List<DownloadingPackage> pkgs = cdm.listDownloadingPackages(); 125 for (DownloadingPackage pkg : pkgs) { 126 if (pkg.getId().equals(pkgId)) { 127 return pkg; 128 } 129 } 130 return null; 131 } 132 133 @GET 134 @Produces("text/html") 135 @Path(value = "start/{pkgId}") 136 public Object startDownload(@PathParam("pkgId") String pkgId, @QueryParam("source") String source, 137 @QueryParam("install") Boolean install, @QueryParam("depCheck") Boolean depCheck, 138 @QueryParam("type") String pkgType, @QueryParam("onlyRemote") Boolean onlyRemote, 139 @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 140 PackageManager pm = Framework.getService(PackageManager.class); 141 // flag to start install after download 142 if (install == null) { 143 install = false; 144 } 145 if (depCheck == null) { 146 depCheck = true; 147 } 148 if (!RequestHelper.isInternalLink(getContext())) { 149 DownloadablePackage pkg = pm.getPackage(pkgId); 150 return getView("confirmDownload").arg("pkg", pkg).arg("source", source); 151 } 152 try { 153 pm.download(pkgId); 154 } catch (ConnectServerError e) { 155 return getView("downloadError").arg("e", e); 156 } 157 return getView("downloadStarted").arg("pkg", getDownloadingPackage(pkgId)) 158 .arg("source", source) 159 .arg("over", false) 160 .arg("install", install) 161 .arg("depCheck", depCheck) 162 .arg("filterOnPlatform", filterOnPlatform.toString()) 163 .arg("type", pkgType.toString()) 164 .arg("onlyRemote", onlyRemote.toString()); 165 } 166 167 @GET 168 @Produces(MediaType.APPLICATION_JSON) 169 @Path(value = "startDownloads") 170 public String startDownloads(@QueryParam("pkgList") String pkgList) { 171 if (RequestHelper.isInternalLink(getContext())) { 172 if (pkgList != null) { 173 String[] pkgs = pkgList.split("/"); 174 PackageManager pm = Framework.getService(PackageManager.class); 175 try { 176 log.info("Starting download for packages " + Arrays.toString(pkgs)); 177 pm.download(Arrays.asList(pkgs)); 178 } catch (ConnectServerError e) { 179 log.error(e, e); 180 } 181 // here we generate a fake progress report so that if some 182 // download are very fast, they will still be visible on the 183 // client side 184 StringBuilder sb = new StringBuilder(); 185 sb.append("["); 186 for (int i = 0; i < pkgs.length; i++) { 187 if (i > 0) { 188 sb.append(","); 189 } 190 sb.append("{ \"pkgid\" : ") 191 .append("\"") 192 .append(pkgs[i]) 193 .append("\",") 194 .append(" \"progress\" : 0}"); 195 } 196 sb.append("]"); 197 return sb.toString(); 198 } 199 } 200 return "[]"; 201 } 202 203 /** 204 * @since 5.6 205 */ 206 @GET 207 @Path(value = "cancel/{pkgId}") 208 public Object cancelDownload(@PathParam("pkgId") String pkgId, @QueryParam("source") String source) { 209 PackageManager pm = Framework.getService(PackageManager.class); 210 pm.cancelDownload(pkgId); 211 return redirect(getPrevious().getPath() + "/packages/" + source); 212 } 213 214}