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; 030 031import org.apache.commons.logging.Log; 032import org.apache.commons.logging.LogFactory; 033import org.nuxeo.connect.connector.ConnectServerError; 034import org.nuxeo.connect.data.DownloadablePackage; 035import org.nuxeo.connect.data.DownloadingPackage; 036import org.nuxeo.connect.downloads.ConnectDownloadManager; 037import org.nuxeo.connect.packages.PackageManager; 038import org.nuxeo.connect.update.PackageState; 039import org.nuxeo.ecm.webengine.model.WebObject; 040import org.nuxeo.ecm.webengine.model.impl.DefaultObject; 041import org.nuxeo.runtime.api.Framework; 042 043/** 044 * Provides REST binding for {@link org.nuxeo.connect.update.Package} download management. 045 * 046 * @author <a href="mailto:td@nuxeo.com">Thierry Delprat</a> 047 */ 048@WebObject(type = "downloadHandler") 049public class DownloadHandler extends DefaultObject { 050 051 protected static final Log log = LogFactory.getLog(DownloadHandler.class); 052 053 @GET 054 @Produces("text/plain") 055 @Path(value = "progress/{pkgId}") 056 public String getDownloadProgress(@PathParam("pkgId") String pkgId) { 057 DownloadingPackage pkg = getDownloadingPackage(pkgId); 058 if (pkg == null) { 059 return null; 060 } 061 return pkg.getDownloadProgress() + ""; 062 } 063 064 @GET 065 @Produces("application/json") 066 @Path(value = "progressAsJSON") 067 public String getDownloadsProgress() { 068 ConnectDownloadManager cdm = Framework.getLocalService(ConnectDownloadManager.class); 069 List<DownloadingPackage> pkgs = cdm.listDownloadingPackages(); 070 StringBuffer sb = new StringBuffer(); 071 sb.append("["); 072 for (int i = 0; i < pkgs.size(); i++) { 073 if (i > 0) { 074 sb.append(","); 075 } 076 sb.append("{ \"pkgid\" : "); 077 sb.append("\"" + pkgs.get(i).getId() + "\","); 078 sb.append(" \"progress\" : "); 079 sb.append(pkgs.get(i).getDownloadProgress() + "}"); 080 } 081 sb.append("]"); 082 return sb.toString(); 083 } 084 085 @GET 086 @Produces("text/html") 087 @Path(value = "progressPage/{pkgId}") 088 public Object getDownloadProgressPage(@PathParam("pkgId") String pkgId, @QueryParam("source") String source, 089 @QueryParam("install") Boolean install, @QueryParam("depCheck") Boolean depCheck, 090 @QueryParam("type") String pkgType, @QueryParam("onlyRemote") Boolean onlyRemote, 091 @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 092 DownloadablePackage pkg = getDownloadingPackage(pkgId); 093 boolean downloadOver = false; 094 // flag to start install after download 095 if (install == null) { 096 install = false; 097 } 098 if (depCheck == null) { 099 depCheck = true; 100 } 101 if (pkg == null) { 102 PackageManager pm = Framework.getLocalService(PackageManager.class); 103 pkg = pm.getPackage(pkgId); 104 if (pkg.getPackageState() != PackageState.DOWNLOADING) { 105 downloadOver = true; 106 } 107 } 108 return getView("downloadStarted").arg("pkg", pkg).arg("source", source).arg("over", downloadOver).arg( 109 "install", install).arg("depCheck", depCheck).arg("filterOnPlatform", filterOnPlatform.toString()).arg( 110 "type", pkgType.toString()).arg("onlyRemote", onlyRemote.toString()); 111 } 112 113 protected DownloadingPackage getDownloadingPackage(String pkgId) { 114 ConnectDownloadManager cdm = Framework.getLocalService(ConnectDownloadManager.class); 115 List<DownloadingPackage> pkgs = cdm.listDownloadingPackages(); 116 for (DownloadingPackage pkg : pkgs) { 117 if (pkg.getId().equals(pkgId)) { 118 return pkg; 119 } 120 } 121 return null; 122 } 123 124 @GET 125 @Produces("text/html") 126 @Path(value = "start/{pkgId}") 127 public Object startDownload(@PathParam("pkgId") String pkgId, @QueryParam("source") String source, 128 @QueryParam("install") Boolean install, @QueryParam("depCheck") Boolean depCheck, 129 @QueryParam("type") String pkgType, @QueryParam("onlyRemote") Boolean onlyRemote, 130 @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 131 PackageManager pm = Framework.getLocalService(PackageManager.class); 132 // flag to start install after download 133 if (install == null) { 134 install = false; 135 } 136 if (depCheck == null) { 137 depCheck = true; 138 } 139 if (!RequestHelper.isInternalLink(getContext())) { 140 DownloadablePackage pkg = pm.getPackage(pkgId); 141 return getView("confirmDownload").arg("pkg", pkg).arg("source", source); 142 } 143 try { 144 pm.download(pkgId); 145 } catch (ConnectServerError e) { 146 return getView("downloadError").arg("e", e); 147 } 148 return getView("downloadStarted").arg("pkg", getDownloadingPackage(pkgId)).arg("source", source).arg("over", 149 false).arg("install", install).arg("depCheck", depCheck).arg("filterOnPlatform", 150 filterOnPlatform.toString()).arg("type", pkgType.toString()).arg("onlyRemote", onlyRemote.toString()); 151 } 152 153 @GET 154 @Produces("application/json") 155 @Path(value = "startDownloads") 156 public String startDownloads(@QueryParam("pkgList") String pkgList) { 157 if (RequestHelper.isInternalLink(getContext())) { 158 if (pkgList != null) { 159 String[] pkgs = pkgList.split("/"); 160 PackageManager pm = Framework.getLocalService(PackageManager.class); 161 try { 162 log.info("Starting download for packages " + Arrays.toString(pkgs)); 163 pm.download(Arrays.asList(pkgs)); 164 } catch (ConnectServerError e) { 165 log.error(e, e); 166 } 167 // here we generate a fake progress report so that if some 168 // download are very fast, they will still be visible on the 169 // client side 170 StringBuffer sb = new StringBuffer(); 171 sb.append("["); 172 for (int i = 0; i < pkgs.length; i++) { 173 if (i > 0) { 174 sb.append(","); 175 } 176 sb.append("{ \"pkgid\" : "); 177 sb.append("\"" + pkgs[i] + "\","); 178 sb.append(" \"progress\" : 0}"); 179 } 180 sb.append("]"); 181 return sb.toString(); 182 } 183 } 184 return "[]"; 185 } 186 187 /** 188 * @since 5.6 189 */ 190 @GET 191 @Path(value = "cancel/{pkgId}") 192 public Object cancelDownload(@PathParam("pkgId") String pkgId, @QueryParam("source") String source) { 193 PackageManager pm = Framework.getLocalService(PackageManager.class); 194 pm.cancelDownload(pkgId); 195 return redirect(getPrevious().getPath() + "/packages/" + source); 196 } 197 198}