Package com.psddev.cms.db

Source Code of com.psddev.cms.db.LayoutTag$Static

package com.psddev.cms.db;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.DynamicAttributes;
import javax.servlet.jsp.tagext.TryCatchFinally;

import com.psddev.dari.util.HtmlGrid;
import com.psddev.dari.util.HtmlObject;
import com.psddev.dari.util.HtmlWriter;
import com.psddev.dari.util.ObjectUtils;
import com.psddev.dari.util.TypeReference;

public class LayoutTag extends BodyTagSupport implements DynamicAttributes, TryCatchFinally {

    private static final long serialVersionUID = 1L;

    private static final String ATTRIBUTE_PREFIX = LayoutTag.class.getName() + ".";
    private static final String GRID_CSS_WRITTEN_ATTRIBUTE = ATTRIBUTE_PREFIX + "gridCssWritten";
    private static final String GRID_CSS_CLASS_WRITTEN_ATTRIBUTE_PREFIX = ATTRIBUTE_PREFIX + "gridCssClassWritten.";
    private static final String GRID_CSS_COMMON_WRITTEN_ATTRIBUTE = ATTRIBUTE_PREFIX + "gridCssCommonWritten";
    private static final String GRID_JAVASCRIPT_WRITTEN_ATTRIBUTE = ATTRIBUTE_PREFIX + "gridJavaScriptWritten";
    private static final String GRIDS_ATTRIBUTE = ATTRIBUTE_PREFIX + "grids";

    private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();

    private transient HtmlWriter writer;
    private transient List<CssClassHtmlGrid> cssGrids;
    private transient List<String> cssClasses;
    private transient String extraCss;
    private transient Map<String, Object> areas;

    public Map<String, Object> getAreas() {
        return areas;
    }

    // --- DynamicAttributes support ---

    @Override
    public void setDynamicAttribute(String uri, String localName, Object value) {
        if (value != null) {
            attributes.put(localName, value);
        }
    }

    // --- TryCatchFinally support ---

    @Override
    public void doCatch(Throwable error) throws Throwable {
        throw error;
    }

    @Override
    public void doFinally() {
        attributes.clear();

        writer = null;
        cssGrids = null;
        cssClasses = null;
        extraCss = null;
        areas = null;
    }

    // --- TagSupport support ---

    protected HtmlGrid getGrid(HttpServletRequest request, Object area) {
        if (area instanceof Integer) {
            int areaInt = (Integer) area;
            int gridOffset = 0;

            for (CssClassHtmlGrid entry : cssGrids) {
                HtmlGrid grid = entry.grid;
                int gridAreaSize = entry.grid.getAreas().size();

                if (areaInt < gridOffset + gridAreaSize) {
                    return grid;

                } else {
                    gridOffset += gridAreaSize;
                }
            }

        } else if (cssGrids != null && !cssGrids.isEmpty()) {
            return cssGrids.iterator().next().grid;
        }

        return null;
    }

    public Object getAreaName(HttpServletRequest request, Object area) {
        if (area instanceof Integer) {
            int areaInt = (Integer) area;
            int gridOffset = 0;

            for (CssClassHtmlGrid entry : cssGrids) {
                int gridAreaSize = entry.grid.getAreas().size();

                if (areaInt < gridOffset + gridAreaSize) {
                    return areaInt - gridOffset;

                } else {
                    gridOffset += gridAreaSize;
                }
            }
        }

        return area;
    }

    @Override
    public int doStartTag() throws JspException {
        ServletContext context = pageContext.getServletContext();
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();

        try {
            writer = new HtmlWriter(pageContext.getOut());
            cssGrids = new ArrayList<CssClassHtmlGrid>();
            cssClasses = ObjectUtils.to(new TypeReference<List<String>>() { }, attributes.remove("class"));
            Set<String> gridCssClasses = new HashSet<String>();
            extraCss = ObjectUtils.to(String.class, attributes.remove("extraClass"));

            if (cssClasses != null) {
                for (Object cssClassObject : cssClasses) {
                    if (cssClassObject != null) {
                        String cssClassString = cssClassObject.toString();

                        for (String cssClass : cssClassString.split(" ")) {
                            cssClass = cssClass.trim();
                            @SuppressWarnings("unchecked")
                            Map<String, HtmlGrid> grids = (Map<String, HtmlGrid>) request.getAttribute(GRIDS_ATTRIBUTE);

                            if (grids == null) {
                                grids = HtmlGrid.Static.findAll(context, request);
                                request.setAttribute(GRIDS_ATTRIBUTE, grids);
                            }

                            HtmlGrid grid = grids.get("." + cssClass);

                            if (grid != null) {
                                cssGrids.add(new CssClassHtmlGrid(cssClassString, grid));
                                gridCssClasses.add(cssClass);
                            }
                        }
                    }
                }
            }

            if (cssGrids.isEmpty()) {
                areas = null;
                writer.writeStart("div",
                        attributes,
                        "class", cssClasses != null && !cssClasses.isEmpty() ?
                                cssClasses.get(0) + " " + extraCss :
                                extraCss);

            } else {
                areas = new LinkedHashMap<String, Object>();
                LayoutTag.Static.writeGridCssByClasses(writer, context, request, gridCssClasses);
                LayoutTag.Static.writeGridJavaScript(writer, context, request);
            }

        } catch (IOException error) {
            throw new JspException(error);
        }

        return areas != null ? EVAL_BODY_BUFFERED : EVAL_BODY_INCLUDE;
    }

    @Override
    public int doEndTag() throws JspException {
        try {
            if (cssGrids.isEmpty()) {
                writer.writeEnd();

            } else {
                List<Object> areasList = new ArrayList<Object>(areas.values());
                int areaSize = areasList.size();
                int gridOffset = 0;

                for (CssClassHtmlGrid cssGrid : cssGrids) {
                    String cssClass = cssGrid.cssClass;
                    HtmlGrid grid = cssGrid.grid;
                    Map<String, GridItem> items = new LinkedHashMap<String, GridItem>();
                    int gridAreaSize = grid.getAreas().size();

                    for (Map.Entry<String, Object> areaEntry : areas.entrySet()) {
                        items.put(areaEntry.getKey(), new GridItem(areaEntry.getValue()));
                    }

                    int i = 0;

                    for (; i < gridAreaSize && gridOffset + i < areaSize; ++ i) {
                        items.put(String.valueOf(i), new GridItem(areasList.get(gridOffset + i)));
                    }

                    for (; i < gridAreaSize; ++ i) {
                        items.put(String.valueOf(i), null);
                    }

                    gridOffset += gridAreaSize;

                    if (extraCss != null) {
                        cssClass += " " + extraCss;
                    }

                    writer.writeStart("div", attributes, "class", cssClass);
                        writer.writeGrid(items, grid);
                    writer.writeEnd();
                }
            }

        } catch (IOException error) {
            throw new JspException(error);
        }

        return EVAL_PAGE;
    }

    /** {@link LayoutTag} utility methods. */
    public static final class Static {

        private Static() {
        }

        /**
         * Writes all grid CSS found in the given {@code context} to the
         * given {@code writer} unless it's already been written within the
         * given {@code request}.
         *
         * @param writer Can't be {@code null}.
         * @param context Can't be {@code null}.
         * @param request Can't be {@code null}.
         */
        public static void writeGridCss(HtmlWriter writer, ServletContext context, HttpServletRequest request) throws IOException {
            if (request.getAttribute(GRID_CSS_WRITTEN_ATTRIBUTE) == null) {
                writer.writeStart("style", "type", "text/css");
                    writer.writeAllGridCss(context, request);
                writer.writeEnd();
                request.setAttribute(GRID_CSS_WRITTEN_ATTRIBUTE, Boolean.TRUE);
            }
        }

        /**
         * Writes all grid CSS related to the given {@code cssClasses found
         * in the given {@code context} to the given {@code writer} unless
         * it's already been written within the given {@code request}.
         *
         * @param writer Can't be {@code null}.
         * @param context Can't be {@code null}.
         * @param request Can't be {@code null}.
         * @param cssClasses May be {@code null}.
         */
        public static void writeGridCssByClasses(
                HtmlWriter writer,
                ServletContext context,
                HttpServletRequest request,
                Collection<String> cssClasses)
                throws IOException {

            if (request.getAttribute(GRID_CSS_WRITTEN_ATTRIBUTE) != null) {
                return;
            }

            boolean styleStarted = false;

            if (request.getAttribute(GRID_CSS_COMMON_WRITTEN_ATTRIBUTE) == null) {
                request.setAttribute(GRID_CSS_COMMON_WRITTEN_ATTRIBUTE, Boolean.TRUE);

                if (!styleStarted) {
                    styleStarted = true;
                    writer.writeStart("style", "type", "text/css");
                }

                writer.writeCommonGridCss();
            }

            if (cssClasses != null) {
                Map<String, HtmlGrid> grids = HtmlGrid.Static.findAll(context, request);

                for (String cssClass : cssClasses) {
                    for (Map.Entry<String, HtmlGrid> entry : grids.entrySet()) {
                        String selector = entry.getKey();

                        if (selector.contains(cssClass)) {
                            String attr = GRID_CSS_CLASS_WRITTEN_ATTRIBUTE_PREFIX + selector;

                            if (request.getAttribute(attr) == null) {
                                request.setAttribute(attr, Boolean.TRUE);

                                if (!styleStarted) {
                                    styleStarted = true;
                                    writer.writeStart("style", "type", "text/css");
                                }

                                writer.writeGridCss(selector, entry.getValue());
                            }
                        }
                    }
                }
            }

            if (styleStarted) {
                writer.writeEnd();
            }
        }

        /**
         * Writes all grid JavaScript found in the given {@code context} to the
         * given {@code writer} unless it's already been written within the
         * given {@code request}.
         *
         * @param writer Can't be {@code null}.
         * @param context Can't be {@code null}.
         * @param request Can't be {@code null}.
         */
        public static void writeGridJavaScript(HtmlWriter writer, ServletContext context, HttpServletRequest request) throws IOException {
            if (request.getAttribute(GRID_JAVASCRIPT_WRITTEN_ATTRIBUTE) == null) {
                writer.writeStart("script", "type", "text/javascript");
                    writer.writeAllGridJavaScript(context, request);
                writer.writeEnd();
                request.setAttribute(GRID_JAVASCRIPT_WRITTEN_ATTRIBUTE, Boolean.TRUE);
            }
        }
    }

    private static class CssClassHtmlGrid {

        public final String cssClass;
        public final HtmlGrid grid;

        public CssClassHtmlGrid(String cssClass, HtmlGrid grid) {
            this.cssClass = cssClass;
            this.grid = grid;
        }
    }

    private class GridItem implements HtmlObject {

        private final Object item;

        public GridItem(Object item) {
            this.item = item;
        }

        @Override
        public void format(HtmlWriter writer) throws IOException {
            if (item != null) {
                writer.write(item.toString());
            }
        }
    }
}
TOP

Related Classes of com.psddev.cms.db.LayoutTag$Static

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.