1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.internal.context;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.apache.myfaces.tobago.internal.util.FastStringWriter;
25
26 import javax.faces.context.FacesContext;
27 import javax.faces.context.ResponseWriter;
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Map;
32
33
34
35
36
37 public class ResponseWriterDivider {
38
39 private static final Logger LOG = LoggerFactory.getLogger(ResponseWriterDivider.class);
40
41 private List<ResponseWriter> writers;
42 private List<FastStringWriter> buffers;
43
44 private ResponseWriter original;
45
46 private int current;
47
48 private String nameInRequest;
49
50 public static ResponseWriterDivider getInstance(FacesContext facesContext, String nameInRequest) {
51 final Map<String, Object> map = facesContext.getExternalContext().getRequestMap();
52 ResponseWriterDivider divider = (ResponseWriterDivider) map.get(nameInRequest);
53 if (divider == null) {
54 divider = new ResponseWriterDivider(facesContext);
55 map.put(nameInRequest, divider);
56 divider.nameInRequest = nameInRequest;
57
58 }
59 return divider;
60 }
61
62 private ResponseWriterDivider(FacesContext facesContext) {
63 writers = new ArrayList<ResponseWriter>();
64 buffers = new ArrayList<FastStringWriter>();
65 current = -1;
66 original = facesContext.getResponseWriter();
67 }
68
69
70
71
72
73
74
75
76 public boolean activateBranch(FacesContext facesContext) {
77
78 assert writers.size() == buffers.size();
79
80 boolean created = true;
81 current++;
82 if (writers.size() == current) {
83 FastStringWriter buffer = new FastStringWriter();
84 buffers.add(buffer);
85 ResponseWriter newWriter = facesContext.getResponseWriter().cloneWithWriter(buffer);
86 writers.add(newWriter);
87 created = false;
88 }
89 facesContext.setResponseWriter(writers.get(current));
90 if (LOG.isDebugEnabled()) {
91 LOG.debug(this.toString());
92 }
93 return created;
94 }
95
96
97
98
99
100
101
102
103 public boolean passivateBranch(FacesContext facesContext) {
104
105 assert writers.size() == buffers.size();
106
107 current--;
108 if (current >= 0) {
109 facesContext.setResponseWriter(writers.get(current));
110 if (LOG.isDebugEnabled()) {
111 LOG.debug(this.toString());
112 }
113 return true;
114 } else {
115 facesContext.setResponseWriter(original);
116 if (LOG.isDebugEnabled()) {
117 LOG.debug(this.toString());
118 }
119 return false;
120 }
121 }
122
123
124
125
126
127 public void writeOutAndCleanUp(FacesContext facesContext) throws IOException {
128 facesContext.setResponseWriter(original);
129 for (FastStringWriter buffer : buffers) {
130 original.write(buffer.toString());
131 }
132
133 final Map<String, Object> map = facesContext.getExternalContext().getRequestMap();
134 map.remove(nameInRequest);
135 }
136
137 @Override
138 public String toString() {
139 StringBuilder builder = new StringBuilder();
140 builder.append("StringBuilder(");
141 builder.append(System.identityHashCode(this));
142 builder.append(") current=");
143 builder.append(current);
144 builder.append("\n");
145 int i = 0;
146 for (FastStringWriter buffer : buffers) {
147 builder.append("\n- buffer ");
148 builder.append(i++);
149 builder.append(" ------------------------------------------------------------\n");
150 builder.append(buffer.toString());
151 }
152 builder.append("\n-----------------------------------------------------------------------\n");
153 return builder.toString();
154 }
155 }