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