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