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