001/* 002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 */ 017 018package org.nuxeo.connect.client.we; 019 020import java.util.ArrayList; 021import java.util.List; 022 023import javax.ws.rs.GET; 024import javax.ws.rs.Path; 025import javax.ws.rs.PathParam; 026import javax.ws.rs.Produces; 027import javax.ws.rs.QueryParam; 028 029import org.apache.commons.lang.StringUtils; 030 031import org.nuxeo.connect.client.status.ConnectStatusHolder; 032import org.nuxeo.connect.client.ui.SharedPackageListingsSettings; 033import org.nuxeo.connect.client.vindoz.InstallAfterRestart; 034import org.nuxeo.connect.connector.http.ConnectUrlConfig; 035import org.nuxeo.connect.data.DownloadablePackage; 036import org.nuxeo.connect.data.DownloadingPackage; 037import org.nuxeo.connect.data.SubscriptionStatusType; 038import org.nuxeo.connect.packages.PackageManager; 039import org.nuxeo.connect.packages.dependencies.TargetPlatformFilterHelper; 040import org.nuxeo.connect.update.Package; 041import org.nuxeo.connect.update.PackageState; 042import org.nuxeo.connect.update.PackageType; 043import org.nuxeo.connect.update.PackageVisibility; 044import org.nuxeo.ecm.admin.runtime.PlatformVersionHelper; 045import org.nuxeo.ecm.webengine.model.WebObject; 046import org.nuxeo.ecm.webengine.model.impl.DefaultObject; 047import org.nuxeo.runtime.api.Framework; 048 049/** 050 * Provides REST binding for {@link Package} listings. 051 * 052 * @author <a href="mailto:td@nuxeo.com">Thierry Delprat</a> 053 */ 054@WebObject(type = "packageListingProvider") 055public class PackageListingProvider extends DefaultObject { 056 057 /** 058 * @deprecated since 5.6 059 */ 060 @Deprecated 061 public String getConnectBaseUrl() { 062 return ConnectUrlConfig.getBaseUrl(); 063 } 064 065 /** 066 * @deprecated Since 5.6. Use {@link #getTargetPlatform(Boolean)} in original request to get only the wanted 067 * packages instead of later filtering the whole list. 068 */ 069 @Deprecated 070 protected List<DownloadablePackage> filterOnPlatform(List<DownloadablePackage> pkgs, Boolean filterOnPlatform) { 071 if (filterOnPlatform != Boolean.TRUE) { 072 return pkgs; 073 } 074 String targetPF = PlatformVersionHelper.getPlatformFilter(); 075 if (targetPF == null) { 076 return pkgs; 077 } else { 078 List<DownloadablePackage> filteredPackages = new ArrayList<>(); 079 for (DownloadablePackage pkg : pkgs) { 080 if (TargetPlatformFilterHelper.isCompatibleWithTargetPlatform(pkg, 081 PlatformVersionHelper.getPlatformFilter())) { 082 filteredPackages.add(pkg); 083 } 084 } 085 return filteredPackages; 086 } 087 } 088 089 @GET 090 @Produces("text/html") 091 @Path(value = "list") 092 public Object doList(@QueryParam("type") String pkgType, @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 093 PackageManager pm = Framework.getLocalService(PackageManager.class); 094 String targetPlatform = getTargetPlatform(filterOnPlatform); 095 List<DownloadablePackage> pkgs; 096 if (StringUtils.isBlank(pkgType)) { 097 pkgs = pm.listPackages(targetPlatform); 098 } else { 099 pkgs = pm.listPackages(PackageType.getByValue(pkgType), targetPlatform); 100 } 101 return getView("simpleListing").arg("pkgs", pm.sort(pkgs)).arg("showCommunityInfo", true).arg("source", "list").arg( 102 "filterOnPlatform", filterOnPlatform); 103 } 104 105 @GET 106 @Produces("text/html") 107 @Path(value = "updates") 108 public Object getUpdates(@QueryParam("type") String pkgType, 109 @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 110 PackageManager pm = Framework.getLocalService(PackageManager.class); 111 if (pkgType == null) { 112 pkgType = SharedPackageListingsSettings.instance().get("updates").getPackageTypeFilter(); 113 } 114 if (filterOnPlatform == null) { 115 filterOnPlatform = SharedPackageListingsSettings.instance().get("updates").getPlatformFilter(); 116 } 117 String targetPlatform = getTargetPlatform(filterOnPlatform); 118 List<DownloadablePackage> pkgs; 119 if (StringUtils.isBlank(pkgType)) { 120 pkgs = pm.listUpdatePackages(null, targetPlatform); 121 } else { 122 pkgs = pm.listUpdatePackages(PackageType.getByValue(pkgType), targetPlatform); 123 } 124 return getView("simpleListing").arg("pkgs", pm.sort(pkgs)).arg("showCommunityInfo", true).arg("source", 125 "updates").arg("filterOnPlatform", filterOnPlatform); 126 } 127 128 @GET 129 @Produces("text/html") 130 @Path(value = "private") 131 public Object getPrivate(@QueryParam("type") String pkgType, 132 @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 133 PackageManager pm = Framework.getLocalService(PackageManager.class); 134 if (pkgType == null) { 135 pkgType = SharedPackageListingsSettings.instance().get("private").getPackageTypeFilter(); 136 } 137 if (filterOnPlatform == null) { 138 filterOnPlatform = SharedPackageListingsSettings.instance().get("private").getPlatformFilter(); 139 } 140 String targetPlatform = getTargetPlatform(filterOnPlatform); 141 List<DownloadablePackage> pkgs; 142 if (StringUtils.isBlank(pkgType)) { 143 pkgs = pm.listPrivatePackages(targetPlatform); 144 } else { 145 pkgs = pm.listPrivatePackages(PackageType.getByValue(pkgType), targetPlatform); 146 } 147 return getView("simpleListing").arg("pkgs", pm.sort(pkgs)).arg("showCommunityInfo", true).arg("source", 148 "private").arg("filterOnPlatform", filterOnPlatform); 149 } 150 151 @GET 152 @Produces("text/html") 153 @Path(value = "local") 154 public Object getLocal(@QueryParam("type") String pkgType) { 155 PackageManager pm = Framework.getLocalService(PackageManager.class); 156 if (pkgType == null) { 157 pkgType = SharedPackageListingsSettings.instance().get("local").getPackageTypeFilter(); 158 } 159 List<DownloadablePackage> pkgs; 160 if (StringUtils.isBlank(pkgType)) { 161 pkgs = pm.listLocalPackages(); 162 } else { 163 pkgs = pm.listLocalPackages(PackageType.getByValue(pkgType)); 164 } 165 return getView("simpleListing").arg("pkgs", pm.sort(pkgs)).arg("showCommunityInfo", false).arg("source", 166 "local"); 167 } 168 169 @GET 170 @Produces("text/html") 171 @Path(value = "remote") 172 public Object getRemote(@QueryParam("type") String pkgType, @QueryParam("onlyRemote") Boolean onlyRemote, 173 @QueryParam("searchString") String searchString, @QueryParam("filterOnPlatform") Boolean filterOnPlatform) { 174 PackageManager pm = Framework.getLocalService(PackageManager.class); 175 if (pkgType == null) { 176 pkgType = SharedPackageListingsSettings.instance().get("remote").getPackageTypeFilter(); 177 } 178 if (filterOnPlatform == null) { 179 filterOnPlatform = SharedPackageListingsSettings.instance().get("remote").getPlatformFilter(); 180 } 181 if (onlyRemote == null) { 182 onlyRemote = SharedPackageListingsSettings.instance().get("remote").isOnlyRemote(); 183 } 184 List<DownloadablePackage> pkgs; 185 String targetPlatform = getTargetPlatform(filterOnPlatform); 186 if (!StringUtils.isEmpty(searchString)) { // SEARCH IS NOT IMPLEMENTED 187 pkgs = pm.searchPackages(searchString); 188 } else if (onlyRemote) { 189 if (StringUtils.isBlank(pkgType)) { 190 pkgs = pm.listOnlyRemotePackages(targetPlatform); 191 } else { 192 pkgs = pm.listOnlyRemotePackages(PackageType.getByValue(pkgType), targetPlatform); 193 } 194 } else { 195 if (StringUtils.isBlank(pkgType)) { 196 pkgs = pm.listRemoteOrLocalPackages(targetPlatform); 197 } else { 198 pkgs = pm.listRemoteOrLocalPackages(PackageType.getByValue(pkgType), targetPlatform); 199 } 200 } 201 return getView("simpleListing").arg("pkgs", pm.sort(pkgs)).arg("showCommunityInfo", false).arg("source", 202 "remote").arg("filterOnPlatform", filterOnPlatform.toString()).arg("type", pkgType.toString()).arg( 203 "onlyRemote", onlyRemote.toString()); 204 } 205 206 /** 207 * @param filterOnPlatform 208 * @return target platform if {@code filterOnPlatform==true} else null 209 * @since 5.6 210 */ 211 private String getTargetPlatform(Boolean filterOnPlatform) { 212 if (filterOnPlatform != Boolean.TRUE) { 213 return null; 214 } 215 return PlatformVersionHelper.getPlatformFilter(); 216 } 217 218 @GET 219 @Produces("text/html") 220 @Path(value = "studio") 221 public Object getStudio() { 222 PackageManager pm = Framework.getLocalService(PackageManager.class); 223 List<DownloadablePackage> pkgs = pm.listAllStudioRemoteOrLocalPackages(); 224 List<DownloadablePackage> pkgsWithoutSnapshot = StudioSnapshotHelper.removeSnapshot(pkgs); 225 return getView("simpleListing").arg("pkgs", pm.sort(pkgsWithoutSnapshot)).arg("showCommunityInfo", false).arg( 226 "source", "studio"); 227 } 228 229 public String getStateLabel(Package pkg) { 230 PackageState state = pkg.getPackageState(); 231 switch (state) { 232 case REMOTE: 233 case DOWNLOADED: 234 case INSTALLED: 235 return state.getLabel(); 236 case DOWNLOADING: 237 DownloadingPackage dpkg = (DownloadingPackage) pkg; 238 return state.getLabel() + " (" + dpkg.getDownloadProgress() + "%)"; 239 case INSTALLING: 240 return "installation in progress"; 241 case STARTED: 242 return "running"; 243 case UNKNOWN: 244 default: 245 return "!?!"; 246 } 247 } 248 249 public boolean canInstall(Package pkg) { 250 return PackageState.DOWNLOADED == pkg.getPackageState() 251 && !InstallAfterRestart.isMarkedForInstallAfterRestart(pkg.getId()); 252 } 253 254 public boolean needsRestart(Package pkg) { 255 return InstallAfterRestart.isMarkedForInstallAfterRestart(pkg.getId()) 256 || PackageState.INSTALLED == pkg.getPackageState() 257 || InstallAfterRestart.isMarkedForUninstallAfterRestart(pkg.getName()); 258 } 259 260 public boolean canUnInstall(Package pkg) { 261 return pkg.getPackageState().isInstalled() 262 && !InstallAfterRestart.isMarkedForUninstallAfterRestart(pkg.getName()); 263 } 264 265 /** 266 * @since 5.8 267 */ 268 public boolean canUpgrade(Package pkg) { 269 return pkg.getPackageState().isInstalled() && pkg.getVersion().isSnapshot() 270 && !InstallAfterRestart.isMarkedForInstallAfterRestart(pkg.getName()); 271 } 272 273 public boolean canRemove(Package pkg) { 274 return pkg.isLocal(); 275 } 276 277 /** 278 * @since 5.6 279 */ 280 public boolean canCancel(Package pkg) { 281 return PackageState.DOWNLOADING == pkg.getPackageState(); 282 } 283 284 public boolean canDownload(Package pkg) { 285 return pkg.getPackageState() == PackageState.REMOTE 286 && (pkg.getType() == PackageType.STUDIO || pkg.getVisibility() == PackageVisibility.PUBLIC // 287 || (ConnectStatusHolder.instance().isRegistred() // 288 && ConnectStatusHolder.instance().getStatus().status() == SubscriptionStatusType.OK)); 289 } 290 291 @GET 292 @Produces("text/html") 293 @Path(value = "details/{pkgId}") 294 public Object getDetails(@PathParam("pkgId") String pkgId) { 295 PackageManager pm = Framework.getLocalService(PackageManager.class); 296 DownloadablePackage pkg = pm.getPackage(pkgId); 297 if (pkg != null) { 298 return getView("pkgDetails").arg("pkg", pkg); 299 } else { 300 return getView("pkgNotFound").arg("pkgId", pkgId); 301 } 302 } 303 304 /** 305 * @since 5.6 306 * @return true if registration is required for download 307 */ 308 public boolean registrationRequired(Package pkg) { 309 return pkg.getPackageState() == PackageState.REMOTE && pkg.getType() != PackageType.STUDIO 310 && pkg.getVisibility() != PackageVisibility.PUBLIC && (!ConnectStatusHolder.instance().isRegistred() // 311 || ConnectStatusHolder.instance().getStatus().status() != SubscriptionStatusType.OK); 312 } 313 314}