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