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