1 /* ResourceUrlCreator.java 2 Copyright (C) 2011 Red Hat, Inc 3 4 This file is part of IcedTea. 5 6 IcedTea is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 IcedTea is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with IcedTea; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package net.sourceforge.jnlp.cache; 39 40 import java.net.MalformedURLException; 41 import java.net.URL; 42 import java.util.LinkedList; 43 import java.util.List; 44 45 import net.sourceforge.jnlp.DownloadOptions; 46 47 public class ResourceUrlCreator { 48 49 protected final Resource resource; 50 protected final DownloadOptions downloadOptions; 51 ResourceUrlCreator(Resource resource, DownloadOptions downloadOptions)52 public ResourceUrlCreator(Resource resource, DownloadOptions downloadOptions) { 53 this.resource = resource; 54 this.downloadOptions = downloadOptions; 55 } 56 57 /** 58 * Returns a list of URLs that the resources might be downloadable from. 59 * The Resources may not be downloadable from any of them. The returned order is the order 60 * the urls should be attempted in. 61 * @return a list of URLs that the resources might be downloadable from 62 */ getUrls()63 public List<URL> getUrls() { 64 List<URL> urls = new LinkedList<>(); 65 URL url; 66 67 if (downloadOptions.useExplicitPack() && downloadOptions.useExplicitVersion()) { 68 url = getUrl(resource, true, true); 69 if (url != null) { 70 urls.add(url); 71 } 72 url = getUrl(resource, false, true); 73 if (url != null) { 74 urls.add(url); 75 } 76 url = getUrl(resource, true, false); 77 if (url != null) { 78 urls.add(url); 79 } 80 } else if (downloadOptions.useExplicitPack()) { 81 url = getUrl(resource, true, false); 82 if (url != null) { 83 urls.add(url); 84 } 85 } else if (downloadOptions.useExplicitVersion()) { 86 url = getUrl(resource, false, true); 87 if (url != null) { 88 urls.add(url); 89 } 90 } 91 92 url = getVersionedUrl(); 93 urls.add(url); 94 95 urls.add(resource.getLocation()); 96 97 return urls; 98 } 99 100 /** 101 * Returns a url for the resource. 102 * @param resource the resource 103 * @param usePack whether the URL should point to the pack200 file 104 * @param useVersion whether the URL should be modified to include the version 105 * @return a URL for the resource or null if an appropriate URL can not be found 106 */ getUrl(Resource resource, boolean usePack, boolean useVersion)107 static URL getUrl(Resource resource, boolean usePack, boolean useVersion) { 108 if (!(usePack || useVersion)) { 109 throw new IllegalArgumentException("either pack200 or version required"); 110 } 111 112 String location = resource.getLocation().toString(); 113 int lastSlash = resource.getLocation().toString().lastIndexOf('/'); 114 if (lastSlash == -1) { 115 return resource.getLocation(); 116 } 117 String filename = location.substring(lastSlash + 1); 118 if (useVersion && resource.getRequestVersion() != null) { 119 // With 'useVersion', j2-commons-cli.jar becomes, for example, j2-commons-cli__V1.0.jar 120 String parts[] = filename.split("\\.", -1 /* Keep blank strings*/); 121 122 StringBuilder sb = new StringBuilder(); 123 for (int i = 0; i < parts.length; i++) { 124 sb.append(parts[i]); 125 // Append __V<number> before last '.' 126 if (i == parts.length -2) { 127 sb.append("__V").append(resource.getRequestVersion()); 128 } 129 sb.append('.'); 130 } 131 sb.setLength(sb.length() - 1); // remove last '.' 132 133 filename = sb.toString(); 134 } 135 if (usePack) { 136 filename = filename + ".pack.gz"; 137 } 138 139 location = location.substring(0, lastSlash + 1) + filename; 140 try { 141 URL newUrl = new URL(location); 142 return newUrl; 143 } catch (MalformedURLException e) { 144 return null; 145 } 146 } 147 148 /** 149 * Returns the URL for this resource, including the resource's version number in the query string 150 * @return url with version cared about 151 */ getVersionedUrl()152 protected URL getVersionedUrl() { 153 URL resourceUrl = resource.getLocation(); 154 String protocol = uriPartToString(resourceUrl.getProtocol()) + "://"; 155 String userInfo = uriPartToString(resourceUrl.getUserInfo()); 156 if (!userInfo.isEmpty()) { 157 userInfo += "@"; 158 } 159 String host = uriPartToString(resourceUrl.getHost()); 160 String port; 161 if (resourceUrl.getPort() == -1) { 162 port = ""; 163 } else { 164 port = ":" + String.valueOf(resourceUrl.getPort()); 165 } 166 String path = uriPartToString(resourceUrl.getPath()); 167 String query = uriPartToString(resourceUrl.getQuery()); 168 if (!query.isEmpty()) { 169 query = "?" + query; 170 } 171 if (resource.getRequestVersion() != null && resource.getRequestVersion().isVersionId()) { 172 if (!query.isEmpty()) { 173 query += "&"; 174 } else { 175 query = "?" + query; 176 } 177 query += "version-id=" + resource.getRequestVersion(); 178 } 179 try { 180 URL url = new URL(protocol + userInfo + host + port + path + query); 181 return url; 182 } catch (MalformedURLException e) { 183 return resourceUrl; 184 } 185 } 186 uriPartToString(String part)187 private static String uriPartToString(String part) { 188 if (part == null) 189 return ""; 190 return part; 191 } 192 193 } 194