001/*
002 * (C) Copyright 2011 Nuxeo SAS (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.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 *     tdelprat
016 *
017 */
018package org.nuxeo.wizard.download;
019
020import java.io.InputStream;
021import java.util.ArrayList;
022import java.util.List;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.dom4j.Document;
027import org.dom4j.DocumentException;
028import org.dom4j.Element;
029import org.dom4j.io.SAXReader;
030
031/**
032 * Simple DOM4J parser to read the {@link DownloadPackage} list from an XML stream
033 *
034 * @author Tiry (tdelprat@nuxeo.com)
035 */
036public class DownloadDescriptorParser {
037
038    protected static final Log log = LogFactory.getLog(DownloadDescriptorParser.class);
039
040    public static Document parse(InputStream in) {
041        Document document = null;
042        SAXReader reader = new SAXReader();
043        try {
044            document = reader.read(in);
045        } catch (DocumentException e) {
046            e.printStackTrace();
047        }
048        return document;
049    }
050
051    public static DownloadablePackageOptions parsePackages(InputStream in) {
052
053        DownloadablePackageOptions options = new DownloadablePackageOptions();
054
055        List<DownloadPackage> pkgs = new ArrayList<>();
056        Document document = parse(in);
057        if (document != null) {
058
059            String baseUrl = document.getRootElement().element("packageDefinitions").attributeValue("baseUrl");
060
061            // parse package definition
062            for (Object el : document.getRootElement().element("packageDefinitions").elements("package")) {
063                DownloadPackage pkg = readPackageDefinition((Element) el, baseUrl);
064                if (pkg != null) {
065                    pkgs.add(pkg);
066                }
067            }
068
069            options.setAllPackages(pkgs);
070
071            Element install = document.getRootElement().element("install");
072
073            // get common packages
074            if (install.element("common") != null) {
075                for (Object el : install.element("common").elements("package")) {
076                    DownloadPackage pkg = readCommonPackage((Element) el, pkgs);
077                    if (pkg != null) {
078                        options.addCommonPackage(pkg);
079                    }
080                }
081            }
082
083            nodeCounter = 0;
084            // get package Options
085            for (Object el : install.element("packageOptions").elements("package")) {
086                DownloadablePackageOption pkg = readPackageOptions((Element) el, pkgs);
087                if (pkg != null) {
088                    options.addOptions(pkg);
089                }
090            }
091
092            // get presets
093            if (document.getRootElement().element("presets") != null) {
094                for (Object el : document.getRootElement().element("presets").elements("preset")) {
095                    Element preset = (Element) el;
096                    String presetId = preset.attribute("id").getValue();
097                    String presetLabel = preset.attribute("label").getValue();
098                    String pkgList = preset.getText();
099                    String[] presetPackages = pkgList.split(",");
100                    options.addPreset(presetId, presetLabel, presetPackages);
101                }
102            }
103        }
104        return options;
105    }
106
107    protected static int nodeCounter = 0;
108
109    protected static DownloadPackage readPackageDefinition(Element el, String baseUrl) {
110        String id = el.attribute("id").getValue();
111        if (id != null) {
112            DownloadPackage pkg = new DownloadPackage(id);
113            String bUrl = el.attributeValue("baseUrl");
114            if (bUrl == null) {
115                bUrl = baseUrl;
116            }
117            pkg.setLabel(el.attributeValue("label"));
118            pkg.setFilename(el.attributeValue("filename"));
119            pkg.setMd5(el.attributeValue("md5"));
120            pkg.setVirtual(Boolean.parseBoolean(el.attributeValue("virtual")));
121            pkg.setBaseUrl(bUrl);
122            pkg.setColor(el.attributeValue("color"));
123            pkg.setTextColor(el.attributeValue("textcolor"));
124            pkg.setShortLabel(el.attributeValue("shortlabel"));
125            String url = el.attributeValue("url");
126            if (url != null) {
127                pkg.setDownloadUrl(url);
128            }
129
130            String implies = el.attributeValue("implies");
131            if (implies != null && !implies.trim().equals("")) {
132                String[] deps = implies.split(",");
133                pkg.addDeps(deps);
134            }
135            return pkg;
136        }
137        return null;
138    }
139
140    protected static DownloadPackage readCommonPackage(Element el, List<DownloadPackage> pkgs) {
141        String ref = el.attributeValue("ref");
142        for (DownloadPackage pkg : pkgs) {
143            if (pkg.getId().equals(ref)) {
144                return pkg;
145            }
146        }
147        log.error("Unable to find common package for ref " + ref);
148        return null;
149    }
150
151    protected static DownloadablePackageOption readPackageOptions(Element el, List<DownloadPackage> pkgs) {
152
153        String ref = el.attributeValue("ref");
154        DownloadPackage targetPkg = null;
155
156        if (ref != null) {
157            for (DownloadPackage pkg : pkgs) {
158                if (pkg.getId().equals(ref)) {
159                    targetPkg = pkg;
160                    break;
161                }
162            }
163            if (targetPkg == null) {
164                log.error("Unable to find package for ref " + ref);
165                return null;
166            }
167        }
168
169        String id = el.attributeValue("ref");
170        if (id == null) {
171            id = ref;
172        }
173        DownloadablePackageOption pkgOption;
174        nodeCounter++;
175
176        if (id != null) {
177            pkgOption = new DownloadablePackageOption(targetPkg, id);
178        } else {
179            pkgOption = new DownloadablePackageOption(targetPkg, nodeCounter);
180        }
181
182        String label = el.attributeValue("label");
183        if (label != null) {
184            pkgOption.setLabel(label);
185        }
186        pkgOption.setExclusive(el.attributeValue("exclusive"));
187
188        for (Object child : el.elements()) {
189            DownloadablePackageOption childPkg = readPackageOptions((Element) child, pkgs);
190            if (childPkg != null) {
191                pkgOption.addChildPackage(childPkg);
192            }
193        }
194        return pkgOption;
195    }
196}