1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.rendering.listeners;
35
36 import info.magnolia.rendering.engine.OutputProvider;
37 import info.magnolia.rendering.template.RenderableDefinition;
38
39 import java.io.IOException;
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.Map;
43
44 import javax.jcr.Node;
45 import javax.jcr.RepositoryException;
46
47 import org.apache.commons.lang3.StringUtils;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52
53
54 public abstract class AbstractInjectionListener extends AbstractRenderingListener {
55
56 private static final Logger log = LoggerFactory.getLogger(AbstractInjectionListener.class);
57
58 private boolean skipRendering = false;
59 private String before = null;
60 private String after = null;
61 private Collection<String> arguments = new ArrayList<String>();
62
63 protected abstract boolean shouldInclude(Node content, RenderableDefinition definition) throws RepositoryException;
64
65 @Override
66 public AbstractRenderingListener copy() {
67 AbstractInjectionListener copy = (AbstractInjectionListener) super.copy();
68 copy.setSkipRendering(skipRendering);
69 copy.setBefore(before);
70 copy.setAfter(after);
71 copy.setArguments(arguments);
72 return copy;
73 }
74
75 @Override
76 public RenderingListenerReturnCode before(Node content, RenderableDefinition definition, Map<String, Object> contextObjects, OutputProvider out) throws RepositoryException {
77 if (before != null && this.shouldInclude(content, definition)) {
78 this.include(content, definition, out, this.getBefore());
79 if (skipRendering) {
80 return RenderingListenerReturnCode.SKIP;
81 }
82 }
83 return null;
84 }
85
86 @Override
87 public RenderingListenerReturnCode after(Node content, RenderableDefinition definition, Map<String, Object> contextObjects, OutputProvider out) throws RepositoryException {
88 if (after != null && this.shouldInclude(content, definition)) {
89 this.include(content, definition, out, this.getAfter());
90 }
91 return null;
92 }
93
94 private void include(Node content, RenderableDefinition definition, OutputProvider out, String text) throws RepositoryException {
95 try {
96 out.getAppendable().append(this.processBeforeInjection(text, content, definition));
97 } catch (IOException e) {
98 throw new RepositoryException(String.format("Cannot inject text '%s' into component.", text), e);
99 }
100 }
101
102 protected String processBeforeInjection(String text, Node content, RenderableDefinition definition) throws RepositoryException {
103 for (String argument : arguments) {
104 if (content.hasProperty(argument)) {
105 text = StringUtils.replaceOnce(text, "${" + argument + "}", content.getProperty(argument).getString());
106 } else {
107 log.warn("Cannot replace '{}' since '{}' doesn't have such property.", "${" + argument + "}", content);
108 }
109 }
110 return text;
111 }
112
113 public String getBefore() {
114 return before;
115 }
116
117 public void setBefore(String before) {
118 this.before = before;
119 }
120
121 public String getAfter() {
122 return after;
123 }
124
125 public void setAfter(String after) {
126 this.after = after;
127 }
128
129 public boolean isSkipRendering() {
130 return skipRendering;
131 }
132
133 public void setSkipRendering(boolean skipRendering) {
134 this.skipRendering = skipRendering;
135 }
136
137 public Collection<String> getArguments() {
138 return arguments;
139 }
140
141 public void setArguments(Collection<String> arguments) {
142 this.arguments = arguments;
143 }
144
145 }