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 */
018
019package org.nuxeo.wizard.download;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026
027/**
028 * @author Tiry (tdelprat@nuxeo.com)
029 * @since 5.5
030 */
031public class DownloadablePackageOptions {
032
033    protected List<DownloadablePackageOption> pkgOptions = new ArrayList<>();
034
035    protected List<DownloadPackage> pkg4Install = new ArrayList<>();
036
037    protected List<DownloadPackage> commonPackages = new ArrayList<>();
038
039    protected List<DownloadPackage> allPackages = new ArrayList<>();
040
041    protected List<Preset> presets = new ArrayList<>();
042
043    protected static final Log log = LogFactory.getLog(DownloadablePackageOptions.class);
044
045    public List<DownloadablePackageOption> getOptions() {
046        return pkgOptions;
047    }
048
049    public void addOptions(DownloadablePackageOption pkgOption) {
050        pkgOptions.add(pkgOption);
051    }
052
053    public void addCommonPackage(DownloadPackage pkg) {
054        commonPackages.add(pkg);
055    }
056
057    public int size() {
058        return getOptions().size();
059    }
060
061    public DownloadablePackageOption get(int idx) {
062        return getOptions().get(idx);
063    }
064
065    public void resetSelection() {
066        pkg4Install = new ArrayList<>();
067        for (DownloadablePackageOption option : pkgOptions) {
068            resetSelection(option);
069        }
070    }
071
072    protected void resetSelection(DownloadablePackageOption option) {
073        option.setSelected(false);
074        for (DownloadablePackageOption child : option.getChildrenPackages()) {
075            resetSelection(child);
076        }
077    }
078
079    public List<String> checkSelectionValid(List<String> ids) {
080        for (String id : ids) {
081            DownloadablePackageOption option = findById(id, pkgOptions);
082            if (option == null) {
083                List<String> newIds = new ArrayList<>();
084                newIds.addAll(ids);
085                newIds.remove(id);
086                return checkSelectionValid(newIds);
087            }
088            // force selection of parents
089            if (option.getParent() != null && !ids.contains(option.getParent().getId())) {
090                List<String> newIds = new ArrayList<>();
091                newIds.addAll(ids);
092                newIds.add(0, option.getParent().getId());
093                return checkSelectionValid(newIds);
094            }
095            // check constraints
096            if (option.isExclusive()) {
097                for (DownloadablePackageOption sib : option.getSiblingPackages()) {
098                    if (ids.contains(sib.getId())) {
099                        ids.remove(option.getId());
100                        log.warn("Unsatisfied constraints in selection ... fixing");
101                        return checkSelectionValid(ids);
102                    }
103                }
104            } else {
105                for (DownloadablePackageOption sib : option.getSiblingPackages()) {
106                    if (ids.contains(sib.getId()) && sib.isExclusive()) {
107                        ids.remove(sib.getId());
108                        log.warn("Unsatisfied constraints in selection ... fixing");
109                        return checkSelectionValid(ids);
110                    }
111                }
112            }
113        }
114        return ids;
115    }
116
117    protected void markForDownload(String pkgId) {
118        for (DownloadPackage pkg : allPackages) {
119            if (pkg.getId().equals(pkgId)) {
120                markForDownload(pkg);
121                break;
122            }
123        }
124    }
125
126    protected void markForDownload(DownloadPackage pkg) {
127        if (!pkg4Install.contains(pkg)) {
128            if (pkg.getFilename() != null && !"".equals(pkg.getFilename())) {
129                for (String dep : pkg.getImpliedDeps()) {
130                    markForDownload(dep);
131                }
132            }
133            pkg4Install.add(pkg);
134        }
135    }
136
137    public void select(List<String> ids) {
138        resetSelection();
139        ids = checkSelectionValid(ids);
140        for (String id : ids) {
141            DownloadablePackageOption option = findById(id, pkgOptions);
142            option.setSelected(true);
143            DownloadPackage pkg = option.getPackage();
144            if (pkg != null) {
145                markForDownload(pkg);
146            }
147        }
148    }
149
150    protected DownloadablePackageOption findById(String id, List<DownloadablePackageOption> options) {
151        for (DownloadablePackageOption option : options) {
152            if (option.getId().equals(id)) {
153                return option;
154            }
155            DownloadablePackageOption childOption = findById(id, option.getChildrenPackages());
156            if (childOption != null) {
157                return childOption;
158            }
159        }
160        return null;
161    }
162
163    public List<DownloadPackage> getPkg4Install() {
164        List<DownloadPackage> pkgs = new ArrayList<>(commonPackages);
165        pkgs.addAll(pkg4Install);
166        return pkgs;
167    }
168
169    protected void asJson(DownloadablePackageOption option, StringBuffer sb) {
170        sb.append("{");
171        sb.append("\"id\":\"" + option.id + "\",");
172        sb.append("\"package\":\"" + option.getPackage().getId() + "\",");
173        sb.append("\"color\":\"" + option.getColor() + "\",");
174        sb.append("\"textcolor\":\"" + option.getTextColor() + "\",");
175        sb.append("\"label\":\"" + option.getLabel() + "\",");
176        sb.append("\"shortlabel\":\"" + option.getShortLabel() + "\",");
177        sb.append("\"selected\":\"" + option.selected + "\",");
178        sb.append("\"exclusive\":\"" + option.exclusive + "\",");
179        sb.append("\"children\": [");
180        List<DownloadablePackageOption> children = option.getChildrenPackages();
181        for (int i = 0; i < children.size(); i++) {
182            if (i > 0) {
183                sb.append(",");
184            }
185            asJson(children.get(i), sb);
186        }
187        sb.append("] }");
188    }
189
190    protected DownloadablePackageOption getSelectedRoot() {
191        for (DownloadablePackageOption option : pkgOptions) {
192            if (option.isSelected()) {
193                return option;
194            }
195        }
196        return pkgOptions.get(0);
197    }
198
199    public String asJson() {
200        StringBuffer sb = new StringBuffer();
201        asJson(getSelectedRoot(), sb);
202        return sb.toString();
203    }
204
205    void addPreset(String id, String label, String[] pkgIds) {
206        presets.add(new Preset(id, label, pkgIds));
207    }
208
209    public List<Preset> getPresets() {
210        return presets;
211    }
212
213    public List<DownloadPackage> getAllPackages() {
214        return allPackages;
215    }
216
217    public void setAllPackages(List<DownloadPackage> allPackages) {
218        this.allPackages = allPackages;
219    }
220
221}