1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.esigate.esi;
16
17 import java.io.IOException;
18 import java.io.Writer;
19 import java.util.Map;
20 import java.util.regex.Pattern;
21
22 import org.apache.http.HttpStatus;
23 import org.esigate.HttpErrorPage;
24 import org.esigate.Parameters;
25 import org.esigate.Renderer;
26 import org.esigate.impl.DriverRequest;
27 import org.esigate.parser.Parser;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31
32
33
34
35
36
37
38
39
40 public class EsiRenderer implements Renderer, Appendable {
41
42 private static final Logger LOG = LoggerFactory.getLogger(EsiRenderer.class);
43
44 private static final Pattern PATTERN = Pattern
45 .compile("(<esi:\\w+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>)|(</esi:[^>]*>)");
46 private static final Pattern PATTERN_COMMENTS = Pattern.compile("(<!--esi)|(-->)");
47
48 private final Parser parser = new Parser(PATTERN, IncludeElement.TYPE, CommentElement.TYPE, RemoveElement.TYPE,
49 VarsElement.TYPE, ChooseElement.TYPE, WhenElement.TYPE, OtherwiseElement.TYPE, TryElement.TYPE,
50 AttemptElement.TYPE, ExceptElement.TYPE, InlineElement.TYPE, ReplaceElement.TYPE, FragmentElement.TYPE);
51
52 private final Parser parserComments = new Parser(PATTERN_COMMENTS, Comment.TYPE);
53
54 private Writer out;
55
56 private Map<String, CharSequence> fragmentsToReplace;
57
58 private final String page;
59
60 private final String name;
61
62 private boolean write = true;
63
64 private boolean found = false;
65
66 public String getName() {
67 return name;
68 }
69
70 public void setWrite(boolean write) {
71 this.write = write;
72 }
73
74
75
76
77 public EsiRenderer() {
78 page = null;
79 name = null;
80 }
81
82
83
84
85
86
87
88
89
90 public EsiRenderer(String page, String name) {
91 this.page = page;
92 this.name = name;
93 write = false;
94 }
95
96 public Map<String, CharSequence> getFragmentsToReplace() {
97 return fragmentsToReplace;
98 }
99
100 public void setFragmentsToReplace(Map<String, CharSequence> fragmentsToReplace) {
101 this.fragmentsToReplace = fragmentsToReplace;
102 }
103
104 @Override
105 public void render(DriverRequest originalRequest, String content, Writer outWriter) throws IOException,
106 HttpErrorPage {
107 if (name != null) {
108 LOG.debug("Rendering fragment {} in page {}", name, page);
109 }
110 this.out = outWriter;
111 if (content == null) {
112 return;
113 }
114
115
116 StringBuilder contentWithoutComments = new StringBuilder(Parameters.DEFAULT_BUFFER_SIZE);
117 parserComments.setHttpRequest(originalRequest);
118 parserComments.parse(content, contentWithoutComments);
119
120
121 parser.setHttpRequest(originalRequest);
122 parser.parse(contentWithoutComments, this);
123
124 if (name != null && !this.found) {
125 throw new HttpErrorPage(HttpStatus.SC_BAD_GATEWAY, "Fragment " + name + " not found", "Fragment " + name
126 + " not found");
127 }
128 }
129
130 @Override
131 public Appendable append(CharSequence csq) throws IOException {
132 if (write) {
133 out.append(csq);
134 }
135 return this;
136 }
137
138 @Override
139 public Appendable append(char c) throws IOException {
140 if (write) {
141 out.append(c);
142 }
143 return this;
144 }
145
146 @Override
147 public Appendable append(CharSequence csq, int start, int end) throws IOException {
148 if (write) {
149 out.append(csq, start, end);
150 }
151 return this;
152 }
153
154 public boolean isWrite() {
155 return this.write;
156 }
157
158 public void setFound(boolean found) {
159 this.found = found;
160
161 }
162
163 }