<commit_before>/**
 *  Copyright (C) 2007 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.xforms.processor;

import org.orbeon.oxf.common.Version;
import org.orbeon.oxf.xforms.XFormsContainingDocument;
import org.orbeon.oxf.xforms.XFormsProperties;
import org.orbeon.oxf.xforms.control.controls.XFormsSelect1Control;
import org.orbeon.saxon.om.FastStringBuffer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XFormsFeatures {

    private static final FeatureConfig[] features = {
            new FeatureConfig("range", "range"),
            new FeatureConfig("tree", new String[] { "select", "select1" }, XFormsSelect1Control.TREE_APPEARANCE),
            new FeatureConfig("menu", "select1", XFormsSelect1Control.MENU_APPEARANCE),
            new FeatureConfig("autocomplete", "select1", XFormsSelect1Control.AUTOCOMPLETE_APPEARANCE),
            new FeatureConfig("htmlarea", "textarea", "text/html"),
            new FeatureConfig("dialog", "dialog"),
            new FeatureConfig("offline") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return XFormsProperties.isOfflineMode(containingDocument);
                }
            },
            new FeatureConfig("jscalendar") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
            },
            new FeatureConfig("yuicalendar") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return !"jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
            }
    };
    
    public static class FeatureConfig {
        private String name;
//        private String id;
        private String[] controlNames;
        private String[] controlAppearanceOrMediatypes;

        public FeatureConfig(String name) {
            this(name, (String[]) null, (String[]) null);
        }

        public FeatureConfig(String name, String controlName) {
            this(name, new String[] { controlName }, (String[]) null);
        }

        public FeatureConfig(String name, String controlName, String controlAppearanceOrMediatype) {
            this(name, new String[] { controlName }, new String[] { controlAppearanceOrMediatype });
        }

        public FeatureConfig(String name, String[] controlNames, String controlAppearanceOrMediatype) {
            this(name, controlNames, new String[] { controlAppearanceOrMediatype });
        }

        public FeatureConfig(String name, String[] controlNames, String[] controlAppearanceOrMediatypes) {
            this.name = name;
//            this.id = SecureUtils.digestString(name, "md5", "base64");
            this.controlNames = controlNames;
            this.controlAppearanceOrMediatypes = controlAppearanceOrMediatypes;
        }

        public String getName() {
            return name;
        }

        public String getId() {
//            return id;
            return name;
        }

        public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
            if (controlAppearanceOrMediatypes != null && controlAppearanceOrMediatypes.length > 0) {
                // Test by control name and appearance/mediatype
                for (int i = 0; i < controlNames.length; i++) {
                    for (int j = 0; j < controlAppearanceOrMediatypes.length; j++) {
                        if (ResourceConfig.isInUse(appearancesMap, controlNames[i], controlAppearanceOrMediatypes[j])) {
                            return true;
                        }
                    }
                }
            } else {
                // Test by control name only
                for (int i = 0; i < controlNames.length; i++) {
                    if (ResourceConfig.isInUse(appearancesMap, controlNames[i]))
                        return true;
                }
            }
            return false;
        }
    }

    private static Map featuresByIdMap = new HashMap();
    static {
        for (int i = 0; i < features.length; i++) {
            final FeatureConfig currentFeatureConfig = features[i];
            featuresByIdMap.put(currentFeatureConfig.getId(), currentFeatureConfig);
        }
    }

    private static final ResourceConfig[] stylesheets = {
            // Standard CSS
            new ResourceConfig("/ops/yui/container/assets/skins/sam/container.css", null),
            // Calendar CSS
            new ResourceConfig("/ops/javascript/jscalendar/calendar-blue.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }

                protected String getFeatureName() { return "jscalendar"; }
            },
            new ResourceConfig("/ops/yui/calendar/assets/skins/sam/calendar.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return !"jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }

                protected String getFeatureName() { return "yuicalendar"; }
            },
            // Yahoo! UI Library
            new ResourceConfig("/ops/yui/treeview/assets/skins/sam/treeview.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/examples/treeview/assets/css/check/tree.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/menu/assets/skins/sam/menu.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isMenuInUse(appearancesMap);
                }
                public String getFeatureName() { return "menu"; }
            },
            // NOTE: This doesn't work, probably because FCK editor files must be loaded in an iframe
//            new ResourceConfig("/ops/fckeditor/editor/skins/default/fck_editor.css", null) {
//                public boolean isInUse(Map appearancesMap) {
//                    return isHtmlAreaInUse(appearancesMap);
//                }
//                public String getFeatureName() { return "htmlarea"; }
//            },
            // Other standard stylesheets
            new ResourceConfig("/config/theme/xforms.css", null),
            new ResourceConfig("/config/theme/error.css", null)
    };

    private static final ResourceConfig[] scripts = {
            // Calendar scripts
            new ResourceConfig("/ops/javascript/jscalendar/calendar.js", "/ops/javascript/jscalendar/calendar-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "jscalendar"; }
            },
            new ResourceConfig("/ops/javascript/jscalendar/lang/calendar-en.js", "/ops/javascript/jscalendar/lang/calendar-en-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "jscalendar"; }
            },
            new ResourceConfig("/ops/javascript/jscalendar/calendar-setup.js", "/ops/javascript/jscalendar/calendar-setup-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "jscalendar"; }
            },
            // Yahoo UI Library
            new ResourceConfig("/ops/yui/yahoo/yahoo.js", "/ops/yui/yahoo/yahoo-min.js"),
            new ResourceConfig("/ops/yui/selector/selector-beta.js", "/ops/yui/selector/selector-beta-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return XFormsProperties.isOfflineMode(containingDocument);
                }
                public String getFeatureName() { return "offline"; }
            },
            new ResourceConfig("/ops/yui/event/event.js", "/ops/yui/event/event-min.js"),
            new ResourceConfig("/ops/yui/dom/dom.js", "/ops/yui/dom/dom-min.js"),
            new ResourceConfig("/ops/yui/connection/connection.js", "/ops/yui/connection/connection-min.js"),
            new ResourceConfig("/ops/yui/animation/animation.js", "/ops/yui/animation/animation-min.js"),
            new ResourceConfig("/ops/yui/dragdrop/dragdrop.js", "/ops/yui/dragdrop/dragdrop-min.js"),
            new ResourceConfig("/ops/yui/container/container.js", "/ops/yui/container/container-min.js"),

            new ResourceConfig("/ops/yui/calendar/calendar.js", "/ops/yui/calendar/calendar-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return !"jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "yuicalendar"; }
            },
            new ResourceConfig("/ops/yui/slider/slider.js", "/ops/yui/slider/slider-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isRangeInUse(appearancesMap);
                }
                public String getFeatureName() { return "range"; }
            },
            new ResourceConfig("/ops/yui/treeview/treeview.js", "/ops/yui/treeview/treeview-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/examples/treeview/assets/js/TaskNode.js", "/ops/yui/examples/treeview/assets/js/TaskNode-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/examples/treeview/assets/js/CheckOnClickNode.js", "/ops/yui/examples/treeview/assets/js/CheckOnClickNode-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/menu/menu.js", "/ops/yui/menu/menu-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isMenuInUse(appearancesMap);
                }
                public String getFeatureName() { return "menu"; }
            },
            // HTML area
            new ResourceConfig("/ops/fckeditor/fckeditor.js", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isHtmlAreaInUse(appearancesMap);
                }
                public String getFeatureName() { return "htmlarea"; }
            },
            // Autocomplete
            new ResourceConfig("/ops/javascript/suggest-common.js", "/ops/javascript/suggest-common-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isAutocompleteInUse(appearancesMap);
                }
                public String getFeatureName() { return "autocomplete"; }
            },<commit_msg>We don't need CheckOnClickNode.js in YUI 2.6.0<commit_after>/**
 *  Copyright (C) 2007 Orbeon, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the
 *  GNU Lesser General Public License as published by the Free Software Foundation; either version
 *  2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU Lesser General Public License for more details.
 *
 *  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.xforms.processor;

import org.orbeon.oxf.common.Version;
import org.orbeon.oxf.xforms.XFormsContainingDocument;
import org.orbeon.oxf.xforms.XFormsProperties;
import org.orbeon.oxf.xforms.control.controls.XFormsSelect1Control;
import org.orbeon.saxon.om.FastStringBuffer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XFormsFeatures {

    private static final FeatureConfig[] features = {
            new FeatureConfig("range", "range"),
            new FeatureConfig("tree", new String[] { "select", "select1" }, XFormsSelect1Control.TREE_APPEARANCE),
            new FeatureConfig("menu", "select1", XFormsSelect1Control.MENU_APPEARANCE),
            new FeatureConfig("autocomplete", "select1", XFormsSelect1Control.AUTOCOMPLETE_APPEARANCE),
            new FeatureConfig("htmlarea", "textarea", "text/html"),
            new FeatureConfig("dialog", "dialog"),
            new FeatureConfig("offline") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return XFormsProperties.isOfflineMode(containingDocument);
                }
            },
            new FeatureConfig("jscalendar") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
            },
            new FeatureConfig("yuicalendar") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return !"jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
            }
    };
    
    public static class FeatureConfig {
        private String name;
//        private String id;
        private String[] controlNames;
        private String[] controlAppearanceOrMediatypes;

        public FeatureConfig(String name) {
            this(name, (String[]) null, (String[]) null);
        }

        public FeatureConfig(String name, String controlName) {
            this(name, new String[] { controlName }, (String[]) null);
        }

        public FeatureConfig(String name, String controlName, String controlAppearanceOrMediatype) {
            this(name, new String[] { controlName }, new String[] { controlAppearanceOrMediatype });
        }

        public FeatureConfig(String name, String[] controlNames, String controlAppearanceOrMediatype) {
            this(name, controlNames, new String[] { controlAppearanceOrMediatype });
        }

        public FeatureConfig(String name, String[] controlNames, String[] controlAppearanceOrMediatypes) {
            this.name = name;
//            this.id = SecureUtils.digestString(name, "md5", "base64");
            this.controlNames = controlNames;
            this.controlAppearanceOrMediatypes = controlAppearanceOrMediatypes;
        }

        public String getName() {
            return name;
        }

        public String getId() {
//            return id;
            return name;
        }

        public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
            if (controlAppearanceOrMediatypes != null && controlAppearanceOrMediatypes.length > 0) {
                // Test by control name and appearance/mediatype
                for (int i = 0; i < controlNames.length; i++) {
                    for (int j = 0; j < controlAppearanceOrMediatypes.length; j++) {
                        if (ResourceConfig.isInUse(appearancesMap, controlNames[i], controlAppearanceOrMediatypes[j])) {
                            return true;
                        }
                    }
                }
            } else {
                // Test by control name only
                for (int i = 0; i < controlNames.length; i++) {
                    if (ResourceConfig.isInUse(appearancesMap, controlNames[i]))
                        return true;
                }
            }
            return false;
        }
    }

    private static Map featuresByIdMap = new HashMap();
    static {
        for (int i = 0; i < features.length; i++) {
            final FeatureConfig currentFeatureConfig = features[i];
            featuresByIdMap.put(currentFeatureConfig.getId(), currentFeatureConfig);
        }
    }

    private static final ResourceConfig[] stylesheets = {
            // Standard CSS
            new ResourceConfig("/ops/yui/container/assets/skins/sam/container.css", null),
            // Calendar CSS
            new ResourceConfig("/ops/javascript/jscalendar/calendar-blue.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }

                protected String getFeatureName() { return "jscalendar"; }
            },
            new ResourceConfig("/ops/yui/calendar/assets/skins/sam/calendar.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return !"jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }

                protected String getFeatureName() { return "yuicalendar"; }
            },
            // Yahoo! UI Library
            new ResourceConfig("/ops/yui/treeview/assets/skins/sam/treeview.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/examples/treeview/assets/css/check/tree.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/menu/assets/skins/sam/menu.css", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isMenuInUse(appearancesMap);
                }
                public String getFeatureName() { return "menu"; }
            },
            // NOTE: This doesn't work, probably because FCK editor files must be loaded in an iframe
//            new ResourceConfig("/ops/fckeditor/editor/skins/default/fck_editor.css", null) {
//                public boolean isInUse(Map appearancesMap) {
//                    return isHtmlAreaInUse(appearancesMap);
//                }
//                public String getFeatureName() { return "htmlarea"; }
//            },
            // Other standard stylesheets
            new ResourceConfig("/config/theme/xforms.css", null),
            new ResourceConfig("/config/theme/error.css", null)
    };

    private static final ResourceConfig[] scripts = {
            // Calendar scripts
            new ResourceConfig("/ops/javascript/jscalendar/calendar.js", "/ops/javascript/jscalendar/calendar-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "jscalendar"; }
            },
            new ResourceConfig("/ops/javascript/jscalendar/lang/calendar-en.js", "/ops/javascript/jscalendar/lang/calendar-en-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "jscalendar"; }
            },
            new ResourceConfig("/ops/javascript/jscalendar/calendar-setup.js", "/ops/javascript/jscalendar/calendar-setup-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return "jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "jscalendar"; }
            },
            // Yahoo UI Library
            new ResourceConfig("/ops/yui/yahoo/yahoo.js", "/ops/yui/yahoo/yahoo-min.js"),
            new ResourceConfig("/ops/yui/selector/selector-beta.js", "/ops/yui/selector/selector-beta-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return XFormsProperties.isOfflineMode(containingDocument);
                }
                public String getFeatureName() { return "offline"; }
            },
            new ResourceConfig("/ops/yui/event/event.js", "/ops/yui/event/event-min.js"),
            new ResourceConfig("/ops/yui/dom/dom.js", "/ops/yui/dom/dom-min.js"),
            new ResourceConfig("/ops/yui/connection/connection.js", "/ops/yui/connection/connection-min.js"),
            new ResourceConfig("/ops/yui/animation/animation.js", "/ops/yui/animation/animation-min.js"),
            new ResourceConfig("/ops/yui/dragdrop/dragdrop.js", "/ops/yui/dragdrop/dragdrop-min.js"),
            new ResourceConfig("/ops/yui/container/container.js", "/ops/yui/container/container-min.js"),

            new ResourceConfig("/ops/yui/calendar/calendar.js", "/ops/yui/calendar/calendar-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return !"jscalendar".equals(XFormsProperties.getDatePicker(containingDocument));
                }
                protected String getFeatureName() { return "yuicalendar"; }
            },
            new ResourceConfig("/ops/yui/slider/slider.js", "/ops/yui/slider/slider-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isRangeInUse(appearancesMap);
                }
                public String getFeatureName() { return "range"; }
            },
            new ResourceConfig("/ops/yui/treeview/treeview.js", "/ops/yui/treeview/treeview-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/examples/treeview/assets/js/TaskNode.js", "/ops/yui/examples/treeview/assets/js/TaskNode-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isTreeInUse(appearancesMap);
                }
                public String getFeatureName() { return "tree"; }
            },
            new ResourceConfig("/ops/yui/menu/menu.js", "/ops/yui/menu/menu-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isMenuInUse(appearancesMap);
                }
                public String getFeatureName() { return "menu"; }
            },
            // HTML area
            new ResourceConfig("/ops/fckeditor/fckeditor.js", null) {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isHtmlAreaInUse(appearancesMap);
                }
                public String getFeatureName() { return "htmlarea"; }
            },
            // Autocomplete
            new ResourceConfig("/ops/javascript/suggest-common.js", "/ops/javascript/suggest-common-min.js") {
                public boolean isInUse(XFormsContainingDocument containingDocument, Map appearancesMap) {
                    return isAutocompleteInUse(appearancesMap);
                }
                public String getFeatureName() { return "autocomplete"; }
            },
{'fraction_non_alphanumeric': 0.09883435814251763, 'fraction_numerical': 0.001697536685653929, 'mean_word_length': 2.1782759860927947, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2559019', 'n_tokens_mistral': 6756, 'n_tokens_neox': 6473, 'n_words': 1402}