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