<commit_before>/*
 * #%L
 * fujion
 * %%
 * Copyright (C) 2018 Fujion Framework
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * #L%
 */
package org.fujion.sandbox;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.fujion.ancillary.ComponentRegistry;
import org.fujion.ancillary.IAutoWired;
import org.fujion.annotation.ComponentDefinition;
import org.fujion.annotation.EventHandler;
import org.fujion.annotation.WiredComponent;
import org.fujion.codemirror.CodeMirrorXML;
import org.fujion.codemirror.CodeMirrorXML.SchemaInfo;
import org.fujion.codemirror.CodeMirrorXML.Tag;
import org.fujion.common.MiscUtil;
import org.fujion.component.BaseComponent;
import org.fujion.component.Combobox;
import org.fujion.component.Comboitem;
import org.fujion.component.Label;
import org.fujion.component.Namespace;
import org.fujion.component.Window;
import org.fujion.component.Window.Mode;
import org.fujion.event.EventUtil;
import org.fujion.model.IComponentRenderer;
import org.fujion.model.ListModel;
import org.fujion.page.PageUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;

/**
 * Plugin to facilitate testing of Fujion layouts.
 */
public class MainController implements IAutoWired, ApplicationContextAware {
    
    private static final Mode[] REPLACE_MODES = { Mode.MODAL, Mode.POPUP };
    
    private static final Comparator<Resource> resourceComparator = (r1, r2) -> {
        return r1.getFilename().compareToIgnoreCase(r2.getFilename());
    };
    
    private static final IComponentRenderer<Comboitem, Resource> fujionRenderer = new IComponentRenderer<Comboitem, Resource>() {
        
        @Override
        public Comboitem render(Resource resource) {
            Comboitem item = new Comboitem();
            item.setData(resource);
            item.setLabel(resource.getFilename());
            item.setHint(getPath(resource));
            return item;
        }
        
        private String getPath(Resource resource) {
            try {
                String[] pcs = resource.getURL().toString().split("!", 2);
                
                if (pcs.length == 1) {
                    return pcs[0];
                }
                
                int i = pcs[0].lastIndexOf('/') + 1;
                return pcs[0].substring(i) + ":\n\n" + pcs[1];
            } catch (Exception e) {
                throw MiscUtil.toUnchecked(e);
            }
        }
        
    };
    
    private static SchemaInfo schemaInfo = new SchemaInfo();

    static {
        // Initializes schema info for the component tree.
        Tag rootTag = schemaInfo.addTag(null);
        rootTag.addChildren("fsp");

        ComponentRegistry.getInstance().forEach(comp -> {
            String parentTag = comp.getTag();
            
            if (parentTag.startsWith("#")) {
                return;
            }
            
            Tag tag = schemaInfo.addTag(parentTag);
            rootTag.addChildren(parentTag);

            for (String childTag : comp.getChildTags().keySet()) {
                for (ComponentDefinition childDef : ComponentRegistry.getInstance().getMatching(childTag)) {
                    String cTag = childDef.getTag();
                    
                    if (!cTag.startsWith("#") && childDef.isParentTag(parentTag)) {
                        tag.addChildren(cTag);
                    }
                }
            }
            
            for (Entry<String, Method> setter : comp.getSetters().entrySet()) {
                Method method = setter.getValue();
                int p = method == null ? -1 : method.getParameterCount();
                Class<?> type = p != 1 ? null : method.getParameterTypes()[0];
                String name = setter.getKey();
                
                if (type == null || name.startsWith("#")) {
                    continue;
                } else if (type == boolean.class || type == Boolean.class) {
                    tag.addAttribute(name, "true", "false");
                } else if (type.isEnum()) {
                    Object[] members = type.getEnumConstants();
                    String[] values = new String[members.length];
                    
                    for (int i = 0; i < members.length; i++) {
                        values[i] = members[i].toString().toLowerCase();
                    }
                    
                    tag.addAttribute(name, values);
                } else {
                    tag.addAttribute(name);
                }
            }
            
        });
    }

    // Start of auto-wired section
    
    @WiredComponent
    private CodeMirrorXML editor;
    
    @WiredComponent
    private Combobox cboFujion;
    
    @WiredComponent<commit_msg>Add factory parameters to component attributes.<commit_after>/*
 * #%L
 * fujion
 * %%
 * Copyright (C) 2018 Fujion Framework
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * #L%
 */
package org.fujion.sandbox;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.fujion.ancillary.ComponentRegistry;
import org.fujion.ancillary.IAutoWired;
import org.fujion.annotation.ComponentDefinition;
import org.fujion.annotation.EventHandler;
import org.fujion.annotation.WiredComponent;
import org.fujion.codemirror.CodeMirrorXML;
import org.fujion.codemirror.CodeMirrorXML.SchemaInfo;
import org.fujion.codemirror.CodeMirrorXML.Tag;
import org.fujion.common.MiscUtil;
import org.fujion.component.BaseComponent;
import org.fujion.component.Combobox;
import org.fujion.component.Comboitem;
import org.fujion.component.Label;
import org.fujion.component.Namespace;
import org.fujion.component.Window;
import org.fujion.component.Window.Mode;
import org.fujion.event.EventUtil;
import org.fujion.model.IComponentRenderer;
import org.fujion.model.ListModel;
import org.fujion.page.PageUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;

/**
 * Plugin to facilitate testing of Fujion layouts.
 */
public class MainController implements IAutoWired, ApplicationContextAware {
    
    private static final Mode[] REPLACE_MODES = { Mode.MODAL, Mode.POPUP };
    
    private static final Comparator<Resource> resourceComparator = (r1, r2) -> {
        return r1.getFilename().compareToIgnoreCase(r2.getFilename());
    };
    
    private static final IComponentRenderer<Comboitem, Resource> fujionRenderer = new IComponentRenderer<Comboitem, Resource>() {
        
        @Override
        public Comboitem render(Resource resource) {
            Comboitem item = new Comboitem();
            item.setData(resource);
            item.setLabel(resource.getFilename());
            item.setHint(getPath(resource));
            return item;
        }
        
        private String getPath(Resource resource) {
            try {
                String[] pcs = resource.getURL().toString().split("!", 2);
                
                if (pcs.length == 1) {
                    return pcs[0];
                }
                
                int i = pcs[0].lastIndexOf('/') + 1;
                return pcs[0].substring(i) + ":\n\n" + pcs[1];
            } catch (Exception e) {
                throw MiscUtil.toUnchecked(e);
            }
        }
        
    };
    
    private static SchemaInfo schemaInfo = new SchemaInfo();

    static {
        // Initializes schema info for the component tree.
        Tag rootTag = schemaInfo.addTag(null);
        rootTag.addChildren("fsp");

        ComponentRegistry.getInstance().forEach(comp -> {
            String parentTag = comp.getTag();
            
            if (parentTag.startsWith("#")) {
                return;
            }
            
            Tag tag = schemaInfo.addTag(parentTag);
            rootTag.addChildren(parentTag);

            for (String childTag : comp.getChildTags().keySet()) {
                for (ComponentDefinition childDef : ComponentRegistry.getInstance().getMatching(childTag)) {
                    String cTag = childDef.getTag();
                    
                    if (!cTag.startsWith("#") && childDef.isParentTag(parentTag)) {
                        tag.addChildren(cTag);
                    }
                }
            }
            
            addAttributes(comp.getSetters(), tag);
            addAttributes(comp.getFactoryParameters(), tag);
        });
    }
    
    private static void addAttributes(Map<String, Method> methods, Tag tag) {
        for (Entry<String, Method> entry : methods.entrySet()) {
            Method method = entry.getValue();
            int p = method == null ? -1 : method.getParameterCount();
            Class<?> type = p != 1 ? null : method.getParameterTypes()[0];
            String name = entry.getKey();
            
            if (type == null || name.startsWith("#")) {
                continue;
            } else if (type == boolean.class || type == Boolean.class) {
                tag.addAttribute(name, "true", "false");
            } else if (type.isEnum()) {
                Object[] members = type.getEnumConstants();
                String[] values = new String[members.length];
                
                for (int i = 0; i < members.length; i++) {
                    values[i] = members[i].toString().toLowerCase();
                }
                
                tag.addAttribute(name, values);
            } else {
                tag.addAttribute(name);
            }
        }
    }

    // Start of auto-wired section
    
    @WiredComponent
    private CodeMirrorXML editor;
    
    @WiredComponent
    private Combobox cboFujion;
    
    @WiredComponent
{'fraction_non_alphanumeric': 0.10572957795911204, 'fraction_numerical': 0.0040361498639992985, 'mean_word_length': 2.162597114317425, 'pattern_counts': {'":': 2, '<': 16, '<?xml version=': 0, '>': 18, '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': '679012', 'n_tokens_mistral': 3137, 'n_tokens_neox': 3047, 'n_words': 716}