001package org.nasdanika.html.model.html.gen;
002
003import java.util.List;
004import java.util.Map;
005import java.util.Map.Entry;
006
007import org.eclipse.emf.common.notify.impl.AdapterImpl;
008import org.eclipse.emf.ecore.EObject;
009import org.eclipse.emf.ecore.EStructuralFeature;
010import org.nasdanika.common.BiSupplier;
011import org.nasdanika.common.Context;
012import org.nasdanika.common.Function;
013import org.nasdanika.common.FunctionFactory;
014import org.nasdanika.common.ListCompoundSupplierFactory;
015import org.nasdanika.common.MapCompoundSupplierFactory;
016import org.nasdanika.common.ProgressMonitor;
017import org.nasdanika.emf.EObjectAdaptable;
018import org.nasdanika.html.Container;
019import org.nasdanika.html.model.html.HtmlPackage;
020
021/**
022 * Base class for HTML Element adapters providing common functionality
023 * @author Pavel
024 *
025 * @param <M>
026 * @param <T>
027 */
028public abstract class HtmlElementAdapter<M extends org.nasdanika.html.model.html.HtmlElement, T extends org.nasdanika.html.HTMLElement<?>> extends AdapterImpl {
029        
030        protected HtmlElementAdapter(M htmlElement) {
031                setTarget(htmlElement);
032        }
033        
034        /**
035         * Creates a function which configures the element and returns it.
036         * This implementation applies attributes and adds content. Override to implement additional configuration.
037         * You may chain configuration functions with <code>.then</code>
038         * @param context
039         * @return
040         * @throws Exception
041         */
042        protected Function<T, T> createConfigureFunction(Context context) throws Exception {
043                MapCompoundSupplierFactory<String,Object> attributesFactory = new MapCompoundSupplierFactory<>("Attributes");
044                for (Entry<String, EObject> ae: getTarget().getAttributes()) {
045                        EObject value = ae.getValue();
046                        attributesFactory.put(ae.getKey(), EObjectAdaptable.adaptToSupplierFactoryNonNull(value, Object.class));                        
047                }
048                
049                ListCompoundSupplierFactory<Object> contentFactory = new ListCompoundSupplierFactory<>("Content", EObjectAdaptable.adaptToSupplierFactoryNonNull(getContent(), Object.class));                          
050                
051                MapCompoundSupplierFactory<EStructuralFeature,Object> configurationFactory = new MapCompoundSupplierFactory<>("Attributes and Content");
052                configurationFactory.put(HtmlPackage.Literals.HTML_ELEMENT__ATTRIBUTES, attributesFactory);
053                configurationFactory.put(HtmlPackage.Literals.HTML_ELEMENT__CONTENT, contentFactory);
054                
055                FunctionFactory<BiSupplier<T, Map<EStructuralFeature, Object>>, T> applyAttributesAndContentFunctionFactory = HtmlElementAdapter::createApplyAttributesAndContentFunction;
056                FunctionFactory<T, BiSupplier<T, Map<EStructuralFeature, Object>>> configurationFunctionFactory = configurationFactory.asFunctionFactory();
057                return configurationFunctionFactory.then(applyAttributesAndContentFunctionFactory).create(context);
058        }
059
060        /**
061         * This implementation returns target content. Override to customize.
062         * @return
063         */
064        protected List<EObject> getContent() {
065                return getTarget().getContent();
066        }
067        
068        public static <T extends org.nasdanika.html.HTMLElement<?>> Function<BiSupplier<T, Map<EStructuralFeature, Object>>, T> createApplyAttributesAndContentFunction(Context context) {
069                return new Function<BiSupplier<T,Map<EStructuralFeature,Object>>, T>() {
070                        
071                        @Override
072                        public double size() {
073                                return 1;
074                        }
075                        
076                        @Override
077                        public String name() {
078                                return "Apply attributes";
079                        }
080                        
081                        @SuppressWarnings("unchecked")
082                        @Override
083                        public T execute(BiSupplier<T, Map<EStructuralFeature, Object>> input, ProgressMonitor progressMonitor) throws Exception {
084                                T ret = input.getFirst();
085                                Map<EStructuralFeature, Object> config = input.getSecond();
086                                for (Entry<String, Object> ae: ((Map<String,Object>) config.get(HtmlPackage.Literals.HTML_ELEMENT__ATTRIBUTES)).entrySet()) {
087                                        ret.attribute(ae.getKey(), ae.getValue());
088                                }
089                                for (Object c: (List<Object>) config.get(HtmlPackage.Literals.HTML_ELEMENT__CONTENT)) {
090                                        if (ret instanceof Container) {
091                                                ((Container<?>) ret).content(c);
092                                        } else {
093                                                ret.getContent().add(c);
094                                        }
095                                }
096                                return ret;
097                        }
098                };
099                
100        }
101        
102        @SuppressWarnings("unchecked")
103        @Override
104        public M getTarget() {
105                return (M) super.getTarget();
106        }
107
108}