TMP
[juplo-dialect] / src / main / java / de / juplo / thymeleaf / AbstractSubstituteAttrProcessor.java
1 package de.juplo.thymeleaf;
2
3
4 import java.util.HashMap;
5 import java.util.Map;
6 import org.thymeleaf.context.ITemplateContext;
7 import org.thymeleaf.engine.AttributeName;
8 import org.thymeleaf.engine.EngineEventUtils;
9 import org.thymeleaf.model.IAttribute;
10 import org.thymeleaf.model.ICloseElementTag;
11 import org.thymeleaf.model.IModel;
12 import org.thymeleaf.model.IModelFactory;
13 import org.thymeleaf.model.IProcessableElementTag;
14 import org.thymeleaf.model.ITemplateEvent;
15 import org.thymeleaf.processor.element.AbstractAttributeModelProcessor;
16 import org.thymeleaf.processor.element.IElementModelStructureHandler;
17 import org.thymeleaf.templatemode.TemplateMode;
18
19
20 /**
21  * Subsitutes the element, that is marked with this attribute-processor.
22  *
23  * @author kai
24  */
25 public abstract class AbstractSubstituteAttrProcessor
26     extends
27       AbstractAttributeModelProcessor
28 {
29   public static final int ATTR_PRECEDENCE = 100;
30
31
32   private final String attributeName;
33   private final String substituteName;
34
35
36   public AbstractSubstituteAttrProcessor(
37       final String prefix,
38       final String attribute,
39       final String substitute
40       )
41   {
42     super(
43         TemplateMode.HTML,
44         prefix,
45         null,
46         false,
47         attribute,
48         true,
49         ATTR_PRECEDENCE,
50         false
51         );
52     this.attributeName = attribute;
53     this.substituteName = substitute;
54   }
55
56
57   @Override
58   protected void doProcess(
59       final ITemplateContext context,
60       final IModel model,
61       final AttributeName attributeName,
62       final String attributeValue,
63       final IElementModelStructureHandler handler
64       )
65   {
66     final IProcessableElementTag element = (IProcessableElementTag) model.get(0);
67     final Object result =
68         EngineEventUtils.computeAttributeExpression(
69             context,
70             element,
71             attributeName,
72             attributeValue
73             )
74             .execute(context);
75
76     if (result == null || !(result instanceof Boolean))
77     {
78       return;
79     }
80
81
82     IModelFactory factory = context.getModelFactory();
83
84     if ((Boolean)result)
85     {
86       Map<String, String> attributes = new HashMap<>();
87
88       for (IAttribute attribute : element.getAllAttributes())
89       {
90         String name =
91             attribute
92                 .getAttributeDefinition()
93                 .getAttributeName()
94                 .getAttributeName()
95                 .toLowerCase();
96         switch (name)
97         {
98           case "charset":
99           case "coords":
100           case "href":
101           case "hreflang":
102           case "media":
103           case "name":
104           case "rel":
105           case "ref":
106           case "shape":
107           case "target":
108           case "type":
109           // Also remove the title-attribute, because the mouse-over is confusing
110           case "title":
111             break;
112           default:
113             if (name.equals(this.attributeName))
114               continue;
115             attributes.put(attribute.getAttributeCompleteName(), attribute.getValue());
116         }
117       }
118
119       ITemplateEvent tag;
120       tag = factory.createOpenElementTag(substituteName, attributes, null, false);
121       model.replace(0, tag);
122       for (int i = model.size(); i > 0; --i)
123       {
124         tag = model.get(i);
125         if (!(tag instanceof ICloseElementTag))
126           continue;
127         ICloseElementTag close = (ICloseElementTag)tag;
128         if (close.isUnmatched())
129           continue;
130         if (close.getElementCompleteName().equals(element.getElementCompleteName()))
131         {
132           model.replace(i, factory.createCloseElementTag(substituteName, close.isSynthetic(), close.isUnmatched()));
133           break;
134         }
135       }
136     }
137     else
138       model.replace(0, factory.removeAttribute(element, attributeName));
139   }
140 }