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.templating.elements;
35
36 import info.magnolia.cms.beans.config.ServerConfiguration;
37 import info.magnolia.cms.security.operations.OperationPermissionDefinition;
38 import info.magnolia.context.WebContext;
39 import info.magnolia.i18nsystem.I18nizer;
40 import info.magnolia.objectfactory.Components;
41 import info.magnolia.registry.RegistrationException;
42 import info.magnolia.rendering.context.RenderingContext;
43 import info.magnolia.rendering.engine.AppendableOnlyOutputProvider;
44 import info.magnolia.rendering.engine.RenderException;
45 import info.magnolia.rendering.engine.RenderingEngine;
46 import info.magnolia.rendering.template.AreaDefinition;
47 import info.magnolia.rendering.template.ComponentAvailability;
48 import info.magnolia.rendering.template.assignment.TemplateDefinitionAssignment;
49 import info.magnolia.templating.module.TemplatingModule;
50
51 import java.io.IOException;
52 import java.util.HashMap;
53 import java.util.Map;
54
55 import javax.inject.Inject;
56 import javax.inject.Provider;
57 import javax.jcr.Node;
58 import javax.jcr.RepositoryException;
59 import javax.jcr.Session;
60
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64
65
66
67 public class ComponentElement extends AbstractContentTemplatingElement {
68
69 private static final Logger log = LoggerFactory.getLogger(ComponentElement.class);
70 public static final String CMS_COMPONENT_TAG = "cms:component";
71
72 private Map<String, Object> contextAttributes = new HashMap<>();
73
74 private boolean renderEditbar = true;
75 private OperationPermissionDefinition permissions;
76
77 private final RenderingEngine renderingEngine;
78 private final TemplateDefinitionAssignment templateDefinitionAssignment;
79
80 @Inject
81 public ComponentElement(ServerConfiguration server, RenderingContext renderingContext, RenderingEngine renderingEngine, TemplateDefinitionAssignment templateDefinitionAssignment, WebContext webContext, Provider<TemplatingModule> templatingModuleProvider) {
82 super(server, renderingContext, templatingModuleProvider, webContext);
83 this.renderingEngine = renderingEngine;
84 this.templateDefinitionAssignment = templateDefinitionAssignment;
85 }
86
87
88
89
90 @Deprecated
91 public ComponentElement(ServerConfiguration server, RenderingContext renderingContext, RenderingEngine renderingEngine, TemplateDefinitionAssignment templateDefinitionAssignment, I18nizer i18nizer, WebContext webContext) {
92 this(server, renderingContext, renderingEngine, templateDefinitionAssignment, webContext, () -> Components.getComponent(TemplatingModule.class));
93 }
94
95 @Override
96 public void begin(Appendable out) throws IOException, RenderException {
97
98 setContent(getPassedContent());
99
100 if (getContent() == null) {
101 throw new RenderException("The 'content' or 'workspace' and 'path' attribute have to be set to render a component.");
102 }
103
104 if (renderComments()) {
105
106 try {
107 setTemplateDefinition(templateDefinitionAssignment.getAssignedTemplateDefinition(getContent()));
108 } catch (RegistrationException e) {
109 throw new RenderException("No template definition found for the current content", e);
110 }
111
112 MarkupHelper helper = new MarkupHelper(out);
113
114 helper.openComment(CMS_COMPONENT_TAG);
115 setPageEditorAttributes(helper, getContent());
116 helper.append(" -->\n");
117 }
118
119
120
121 getWebContext().push(getWebContext().getRequest(), getWebContext().getResponse());
122 setAttributesInWebContext(contextAttributes, WebContext.LOCAL_SCOPE);
123
124 try {
125 if (getTemplateDefinition() != null) {
126 renderingEngine.render(getContent(), getTemplateDefinition() , new HashMap<>(), new AppendableOnlyOutputProvider(out));
127 } else {
128 renderingEngine.render(getContent(), new AppendableOnlyOutputProvider(out));
129 }
130 } finally {
131 getWebContext().pop();
132 restoreAttributesInWebContext(contextAttributes, WebContext.LOCAL_SCOPE);
133 }
134 }
135
136 protected void setPageEditorAttributes(MarkupHelper helper, Node node) throws IOException, RenderException {
137 final AreaDefinition areaDefinition = this.getRenderingContext().getParentAreaDefinition();
138 permissions = null;
139
140 if (areaDefinition != null) {
141 String componentId = getTemplateDefinition().getId();
142 ComponentAvailability componentAvailability = null;
143 for (ComponentAvailability availability : areaDefinition.getAvailableComponents().values()) {
144 if (availability.getId().equals(componentId)) {
145 componentAvailability = availability;
146 break;
147 }
148 }
149 if (componentAvailability != null && componentAvailability.getPermissions() != null) {
150 permissions = componentAvailability.getPermissions();
151 }
152 }
153
154 super.setPageEditorAttributes(helper, "component");
155 }
156
157 private boolean hasPermission(Node node) {
158 try {
159 return node.getSession().hasPermission(node.getPath(), Session.ACTION_SET_PROPERTY);
160 } catch (RepositoryException e) {
161 log.error("Could not determine permission for node {}", node);
162 }
163 return false;
164 }
165
166 @Override
167 public void end(Appendable out) throws IOException, RenderException {
168 if (renderComments()) {
169 new MarkupHelper(out).closeComment("cms:component");
170 }
171 }
172
173 public Map<String, Object> getContextAttributes() {
174 return contextAttributes;
175 }
176
177 public void setContextAttributes(Map<String, Object> contextAttributes) {
178 this.contextAttributes = contextAttributes;
179 }
180
181 public boolean isRenderEditbar() {
182 return renderEditbar;
183 }
184
185 public void setRenderEditbar(boolean renderEditbar) {
186 this.renderEditbar = renderEditbar;
187 }
188
189 @Override
190 protected boolean renderComments() {
191 return this.renderEditbar && isAdmin() && !getWebContext().getAggregationState().isPreviewMode() && hasPermission(getContent());
192 }
193
194 public OperationPermissionDefinition getPermissions() {
195 return permissions;
196 }
197 }