001/* 002 * (C) Copyright 2006-2016 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 * bstefanescu 018 * jcarsique 019 * Yannis JULIENNE 020 */ 021package org.nuxeo.connect.update.standalone; 022 023import static java.nio.charset.StandardCharsets.UTF_8; 024 025import java.io.File; 026import java.io.FileInputStream; 027import java.io.FileNotFoundException; 028import java.io.IOException; 029import java.io.InputStream; 030 031import org.apache.commons.io.FileUtils; 032import org.nuxeo.common.xmap.XMap; 033import org.nuxeo.connect.update.LocalPackage; 034import org.nuxeo.connect.update.PackageDependency; 035import org.nuxeo.connect.update.PackageException; 036import org.nuxeo.connect.update.PackageState; 037import org.nuxeo.connect.update.PackageType; 038import org.nuxeo.connect.update.PackageUpdateService; 039import org.nuxeo.connect.update.Validator; 040import org.nuxeo.connect.update.Version; 041import org.nuxeo.connect.update.model.Form; 042import org.nuxeo.connect.update.model.TaskDefinition; 043import org.nuxeo.connect.update.task.Task; 044import org.nuxeo.connect.update.xml.FormsDefinition; 045import org.nuxeo.connect.update.xml.PackageDefinitionImpl; 046import org.nuxeo.connect.update.xml.TaskDefinitionImpl; 047 048/** 049 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 050 */ 051public class LocalPackageImpl implements LocalPackage { 052 053 protected String id; 054 055 protected PackageState state = PackageState.UNKNOWN; 056 057 protected LocalPackageData data; 058 059 protected PackageDefinitionImpl def; 060 061 private PackageUpdateService service; 062 063 /** 064 * @deprecated Since 5.8. Use {@link #LocalPackageImpl(File, PackageState, PackageUpdateService)} instead. 065 */ 066 @Deprecated 067 public LocalPackageImpl(File file, int state, PackageUpdateService pus) throws PackageException { 068 this(null, file, state, pus); 069 } 070 071 /** 072 * @deprecated Since 5.8. Use {@link #LocalPackageImpl(ClassLoader, File, PackageState, PackageUpdateService)} 073 * instead. 074 */ 075 @Deprecated 076 public LocalPackageImpl(ClassLoader parent, File file, int state, PackageUpdateService pus) 077 throws PackageException { 078 this(parent, file, PackageState.getByValue(state), pus); 079 } 080 081 /** 082 * @since 5.7 083 */ 084 public LocalPackageImpl(File file, PackageState state, PackageUpdateService pus) throws PackageException { 085 this(null, file, state, pus); 086 } 087 088 /** 089 * @since 5.8 090 */ 091 public LocalPackageImpl(ClassLoader parent, File file, PackageState state, PackageUpdateService pus) 092 throws PackageException { 093 this.state = state; 094 service = pus; 095 XMap xmap = StandaloneUpdateService.getXmap(); 096 if (xmap == null) { // for tests 097 xmap = StandaloneUpdateService.createXmap(); 098 } 099 try { 100 data = new LocalPackageData(parent, file); 101 try (InputStream in = new FileInputStream(data.getManifest())) { 102 def = (PackageDefinitionImpl) xmap.load(in); 103 } 104 } catch (FileNotFoundException e) { 105 throw new PackageException("Invalid package - no package.xml file found in package " + file.getName()); 106 } catch (IOException e) { 107 throw new PackageException("Failed to load package.xml descriptor for package " + file.getName(), e); 108 } 109 id = def.getId(); 110 } 111 112 @Deprecated 113 @Override 114 public void setState(int state) { 115 this.state = PackageState.getByValue(state); 116 } 117 118 @Override 119 public void setState(PackageState state) { 120 this.state = state; 121 } 122 123 @Override 124 public LocalPackageData getData() { 125 return data; 126 } 127 128 @Override 129 public File getInstallFile() { 130 return data.getEntry(LocalPackage.INSTALL); 131 } 132 133 @Override 134 public File getUninstallFile() { 135 return data.getEntry(LocalPackage.UNINSTALL); 136 } 137 138 @Override 139 public String getLicenseType() { 140 return def.getLicenseType(); 141 } 142 143 @Override 144 public String getLicenseUrl() { 145 return def.getLicenseUrl(); 146 } 147 148 @Override 149 public String getLicenseContent() throws PackageException { 150 File file = data.getEntry(LocalPackage.LICENSE); 151 if (file.isFile()) { 152 try { 153 return FileUtils.readFileToString(file, UTF_8); 154 } catch (IOException e) { 155 throw new PackageException("Failed to read license.txt file for package: " + getId()); 156 } 157 } 158 return null; 159 } 160 161 @Override 162 public String getClassifier() { 163 return def.getClassifier(); 164 } 165 166 @Override 167 public String getDescription() { 168 return def.getDescription(); 169 } 170 171 @Override 172 public String getId() { 173 return id; 174 } 175 176 @Override 177 public String getName() { 178 return def.getName(); 179 } 180 181 @Override 182 public String getTitle() { 183 return def.getTitle(); 184 } 185 186 @Deprecated 187 @Override 188 public int getState() { 189 return state.getValue(); 190 } 191 192 @Override 193 public PackageState getPackageState() { 194 return state; 195 } 196 197 @Override 198 public String[] getTargetPlatforms() { 199 return def.getTargetPlatforms(); 200 } 201 202 @Override 203 public String getTargetPlatformRange() { 204 return def.getTargetPlatformRange(); 205 } 206 207 @Override 208 public String getTargetPlatformName() { 209 return def.getTargetPlatformName(); 210 } 211 212 @Override 213 public PackageDependency[] getDependencies() { 214 return def.getDependencies(); 215 } 216 217 @Override 218 public PackageDependency[] getOptionalDependencies() { 219 return def.getOptionalDependencies(); 220 } 221 222 @Override 223 public PackageDependency[] getConflicts() { 224 return def.getConflicts(); 225 } 226 227 @Override 228 public PackageDependency[] getProvides() { 229 return def.getProvides(); 230 } 231 232 @Override 233 public PackageType getType() { 234 return def.getType(); 235 } 236 237 @Override 238 public Version getVersion() { 239 return def.getVersion(); 240 } 241 242 @Override 243 public String getVendor() { 244 return def.getVendor(); 245 } 246 247 @Override 248 public boolean isLocal() { 249 return true; 250 } 251 252 @Override 253 public Task getInstallTask() throws PackageException { 254 if (def.getInstaller() == null) { 255 def.setInstaller(new TaskDefinitionImpl(service.getDefaultInstallTaskType(), false)); 256 } else if (def.getInstaller().getType() == null) { 257 def.getInstaller().setType(service.getDefaultInstallTaskType()); 258 } 259 return getTask(def.getInstaller()); 260 } 261 262 @Override 263 public Task getUninstallTask() throws PackageException { 264 if (def.getUninstaller() == null) { 265 def.setUninstaller(new TaskDefinitionImpl(service.getDefaultUninstallTaskType(), false)); 266 } else if (def.getUninstaller().getType() == null) { 267 def.getUninstaller().setType(service.getDefaultUninstallTaskType()); 268 } 269 return getTask(def.getUninstaller()); 270 } 271 272 protected Task getTask(TaskDefinition tdef) throws PackageException { 273 Task task; 274 try { 275 task = (Task) data.loadClass(tdef.getType()) 276 .getConstructor(PackageUpdateService.class) 277 .newInstance(service); 278 } catch (ReflectiveOperationException e) { 279 throw new PackageException( 280 "Could not instantiate custom task " + tdef.getType() + " for package " + getId(), e); 281 } 282 task.initialize(this, tdef.getRequireRestart()); 283 return task; 284 } 285 286 @Override 287 public Validator getValidator() throws PackageException { 288 if (def.getValidator() != null) { 289 try { 290 return (Validator) data.loadClass(def.getValidator()).getConstructor().newInstance(); 291 } catch (ReflectiveOperationException e) { 292 throw new PackageException( 293 "Could not instantiate custom validator " + def.getValidator() + " for package " + getId(), e); 294 } 295 } 296 return null; 297 } 298 299 public Form[] getForms(String path) throws PackageException { 300 File file = data.getEntry(path); 301 if (file.isFile()) { 302 try (FileInputStream in = new FileInputStream(file)) { 303 FormsDefinition forms = (FormsDefinition) StandaloneUpdateService.getXmap().load(in); 304 return forms.getForms(); 305 } catch (IOException e) { 306 throw new PackageException("Failed to load forms file: " + file); 307 } 308 } 309 return null; 310 } 311 312 @Override 313 public Form[] getValidationForms() throws PackageException { 314 return getForms(LocalPackage.VALIDATION_FORMS); 315 } 316 317 @Override 318 public Form[] getInstallForms() throws PackageException { 319 return getForms(LocalPackage.INSTALL_FORMS); 320 } 321 322 @Override 323 public Form[] getUninstallForms() throws PackageException { 324 return getForms(LocalPackage.UNINSTALL_FORMS); 325 } 326 327 @Override 328 public String getTermsAndConditionsContent() throws PackageException { 329 File file = data.getEntry(LocalPackage.TERMSANDCONDITIONS); 330 if (file.isFile()) { 331 try { 332 return FileUtils.readFileToString(file, UTF_8); 333 } catch (IOException e) { 334 throw new PackageException("Failed to read license.txt file for package: " + getId()); 335 } 336 } 337 return null; 338 } 339 340 @Override 341 public boolean requireTermsAndConditionsAcceptance() { 342 return def.requireTermsAndConditionsAcceptance(); 343 } 344 345 @Override 346 public boolean supportsHotReload() { 347 return def.supportsHotReload(); 348 } 349 350 @Override 351 public String toString() { 352 return getId(); 353 } 354 355}