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