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.module.admininterface;
35
36 import info.magnolia.cms.beans.config.ObservedManager;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.util.SystemContentWrapper;
40 import info.magnolia.content2bean.Content2BeanUtil;
41 import info.magnolia.objectfactory.Classes;
42 import info.magnolia.objectfactory.Components;
43
44 import java.lang.reflect.Constructor;
45 import java.util.Collection;
46 import java.util.HashMap;
47 import java.util.Map;
48
49 import javax.inject.Singleton;
50 import javax.jcr.RepositoryException;
51 import javax.servlet.http.HttpServletRequest;
52 import javax.servlet.http.HttpServletResponse;
53
54 import org.apache.commons.lang.StringUtils;
55
56 @Singleton
57 public class TreeHandlerManager<H extends AdminTreeMVCHandler> extends ObservedManager {
58
59 private static final String ND_CLASS = "class";
60
61 private static final String ND_REPOSITORY = "repository";
62
63 private static final String ND_NAME = "name";
64
65
66
67
68
69 private final Map<String, TreeHandlerConfig> treeHandlers = new HashMap<String, TreeHandlerConfig>();
70
71
72
73
74
75
76
77
78 public AdminTreeMVCHandler getTreeHandler(String name, HttpServletRequest request, HttpServletResponse response) {
79
80 TreeHandlerConfig th = treeHandlers.get(name);
81
82 if (th == null) {
83 throw new InvalidTreeHandlerException(name);
84 }
85
86 Class<H> treeHandlerClass = th.getHandler();
87
88 try {
89 Constructor<H> constructor = treeHandlerClass.getConstructor(String.class, HttpServletRequest.class, HttpServletResponse.class);
90 AdminTreeMVCHandler newInstance = constructor.newInstance(name, request, response);
91 Content2BeanUtil.setProperties(newInstance, th.getTreeDefinition(), true);
92 return newInstance;
93 }
94 catch (Exception e) {
95 throw new InvalidTreeHandlerException(name, e);
96 }
97 }
98
99 protected void registerTreeHandler(String name, String repository, Class<H> treeHandler, Content treeDefinition) {
100 log.info("Registering tree handler {}", name);
101 treeHandlers.put(name, new TreeHandlerConfig(treeHandler, repository, treeDefinition));
102 }
103
104 @Override
105 protected void onRegister(Content defNode) {
106 Collection<Content> trees = defNode.getChildren(ItemType.CONTENTNODE.getSystemName());
107 for (Object tree1 : trees) {
108 Content tree = (Content) tree1;
109 String name = tree.getNodeData(ND_NAME).getString();
110
111 if (StringUtils.isEmpty(name)) {
112 name = tree.getName();
113 }
114
115 String repository = tree.getNodeData(ND_REPOSITORY).getString();
116 String className = tree.getNodeData(ND_CLASS).getString();
117
118 if (StringUtils.isEmpty(repository)) {
119 repository = name;
120 }
121
122 try {
123 final Class<H> treeHandler = Classes.getClassFactory().forName(className);
124 this.registerTreeHandler(name, repository, treeHandler, new SystemContentWrapper(tree));
125 }
126 catch (ClassNotFoundException e) {
127 log.error("Can't register tree handler [{}]: class [{}] not found", name, className);
128 }
129
130
131 try {
132
133 if (tree.hasContent("commands")) {
134 log.error("The definition of commands at the tree level is no longer supported. Move them to the modules commands node! [" + tree.getHandle() + "]");
135 }
136 }
137 catch (RepositoryException e) {
138 log.error("Can't check commands node of the tree node [" + tree.getHandle() + "]", e);
139 }
140 }
141 }
142
143
144
145
146 public static <H extends AdminTreeMVCHandler> TreeHandlerManager<H> getInstance() {
147 return Components.getSingleton(TreeHandlerManager.class);
148 }
149
150
151
152
153 @Override
154 protected void onClear() {
155 this.treeHandlers.clear();
156 }
157
158 class TreeHandlerConfig {
159
160 private Class<H> handler;
161
162 private String repository;
163
164 private Content treeDefinition;
165
166 TreeHandlerConfig(Class<H> handler, String repository, Content treeDefinition) {
167 this.handler = handler;
168 this.repository = repository;
169 this.treeDefinition = treeDefinition;
170 }
171
172 public Class<H> getHandler() {
173 return this.handler;
174 }
175
176 public String getRepository() {
177 return this.repository;
178 }
179
180 public Content getTreeDefinition() {
181 return treeDefinition;
182 }
183 }
184
185 }