Kawai Wiki

Rev

Rev 113 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.kawai.tag.kcode;

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

import javax.servlet.jsp.JspException;

import org.kawai.model.Page;
import org.mentawai.tag.util.PrintTag;

public class KCodeHandler extends PrintTag {
       
        private static final Map<String, String> EMPTY_MAP = new HashMap<String, String>();
        private static final List<KCode> codes = new ArrayList<KCode>();
       
        public static void add(KCode code) {
                codes.add(code);
        }
       
        public static void add(String tag) {
               
                String klassName = tag;
               
                try {
                        if (!klassName.contains(".")) {
                                klassName = "org.kawai.tag.kcode." + klassName;
                        }
                       
                        Class<?> klass = Class.forName(klassName);
                        KCode code = (KCode) klass.newInstance();
                        add(code);
                       
                } catch(Exception e) {
                        throw new RuntimeException("Cannot add kcode tag: " + tag + " / " + klassName);
                }
        }
       
        private String name;
       
        public void setName(String name) {
                this.name = name;
        }
       
        @Override
        public String getStringToPrint() throws JspException {
               
                Page page = (Page) pageContext.findAttribute(name);
                if (page == null) {
                        throw new JspException("Cannot find page with name: " + name);
                }
               
                String body = page.getBody();
               
                for(KCode code : codes) {
                        String tag = code.getTag();
                        while(checkForTag(tag, body)) {
                                String[] parts = splitCodeBlock(tag, body, code.hasBody());
                                if (parts == null) {
                                        break;
                                }
                                Map<String, String> attributes = parseAttributes(parts[0]);
                                StringBuilder sb = new StringBuilder(1024 * 10);
                                sb.append(parts[1]);
                                sb.append(code.process(pageContext, attributes, parts[2]));
                                sb.append(parts[3]);
                                body = sb.toString();
                        }
                }
               
                return body;
        }
       
        private static final boolean checkForTag(String tag, String body) {
                int start = body.indexOf("[" + tag);
                if (start == -1) return false;
                int end = body.indexOf(']', start);
                return end != -1;
        }
       
        private static String[] splitCodeBlock(String tag, String body, boolean hasBody) {
               
                if (hasBody) {
               
                        int start = body.indexOf("[" + tag);
                        if (start == -1) return null;
                        int closingBracketIndex = body.indexOf("]", start);
                        if (closingBracketIndex == -1) return null;
                        int end = body.indexOf("[/" + tag + "]");
                        if (end > start) {
                                // body tag...
                                String part1 = "";
                                if (start > 0) {
                                        part1 = body.substring(0, start);
                                }
                                String part2 = "";
                                int len = ("[/" + tag + "]").length();
                                if (end < body.length() - len - 1) {
                                        part2 = body.substring(end + len, body.length());
                                }
                                String contents = "";
                                int contentsStart = body.indexOf("]", start) + 1;
                                int contentsEnd = end;
                                if (contentsEnd > contentsStart) {
                                        contents = body.substring(contentsStart, contentsEnd);
                                }
                                String tagAttributes = "";
                                len = ("[" + tag).length();
                                if (closingBracketIndex > start + len) {
                                        tagAttributes = body.substring(start + len, closingBracketIndex).trim();
                                }
                               
                                return new String[] { tagAttributes, part1, contents, part2 };
                        }
                       
                        return null;
               
                } else {
                       
                        int start = body.indexOf("[" + tag);
                        if (start == -1) return null;
                        int closingBracketIndex = body.indexOf("/]", start);
                        if (closingBracketIndex == -1) return null;
                        int end = closingBracketIndex + 2;
                        if (end > start) {
                                String part1 = "";
                                if (start > 0) {
                                        part1 = body.substring(0, start);
                                }
                                String part2 = "";
                                if (end < body.length()) {
                                        part2 = body.substring(end, body.length());
                                }
                                String contents = null;
                                String tagAttributes = "";
                                int len = ("[" + tag).length();
                                if (closingBracketIndex > start + len) {
                                        tagAttributes = body.substring(start + len, closingBracketIndex).trim();
                                }
                               
                                return new String[] { tagAttributes, part1, contents, part2 };
                        }
                       
                        return null;
                       
                }
        }
       
        private static Map<String, String> parseAttributes(String attrs) {
                if (attrs.trim().equals("")) return EMPTY_MAP;
                Map<String, String> map = new HashMap<String, String>();
                String[] temp = attrs.split("\" +");
                for(int i = 0; i < temp.length; i++) {
                        String s = temp[i];
                        if (i != temp.length - 1) {
                                s = s + "\"";
                        }
                        String[] temp2 = s.split("\\=");
                        if (temp2.length == 2) {
                                String key = temp2[0];
                                String val = temp2[1];
                        if (val.startsWith("\"") && val.endsWith("\"")) {
                                val = val.substring(1, val.length() - 1);
                                map.put(key, val);
                        } else {
                                if (val.startsWith("\"")) {
                                        val = val.substring(1);
                                }
                                map.put(key, val);
                        }
                        }
                }
                return map;
        }
       
        public static void main(String[] args) {
               
                String x1 = "house";
                String x2 = "home";
               
                String s = "aaaaaa [code a=\"asfadf\" bbb=\"asfasfffff\"]" + x1 + "[/code] bbbbb [code ]" + x2 + "[/code] cccccccccccc";
               
                String[] blocks = splitCodeBlock("code", s, true);
               
                for(String x : blocks) System.out.println("{" + x + "}");
               
                blocks = splitCodeBlock("code", blocks[3], true);
               
                for(String x : blocks) System.out.println("{" + x + "}");
               
                s = "aaaaaa [code flip=\"1\" flop=\"2\"   /]";
               
                blocks = splitCodeBlock("code", s, false);
               
                for(String x : blocks) System.out.println("{" + x + "}");

                s = "aaaaaa [code /]";
               
                blocks = splitCodeBlock("code", s, false);
               
                for(String x : blocks) System.out.println("{" + x + "}");

               
        }
}