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.lists;
35
36 import java.util.Collection;
37
38 import info.magnolia.cms.beans.config.VersionConfig;
39 import info.magnolia.cms.core.Content;
40 import info.magnolia.cms.gui.control.ContextMenu;
41 import info.magnolia.cms.gui.control.ContextMenuItem;
42 import info.magnolia.cms.gui.control.FunctionBar;
43 import info.magnolia.cms.gui.control.FunctionBarItem;
44 import info.magnolia.cms.gui.controlx.list.ListColumn;
45 import info.magnolia.cms.gui.controlx.list.ListControl;
46 import info.magnolia.cms.gui.controlx.list.ListModel;
47 import info.magnolia.cms.gui.controlx.version.VersionListModel;
48 import info.magnolia.cms.i18n.MessagesManager;
49 import info.magnolia.cms.security.AccessDeniedException;
50 import info.magnolia.cms.util.AlertUtil;
51 import info.magnolia.freemarker.FreemarkerUtil;
52 import info.magnolia.module.admininterface.VersionUtil;
53 import info.magnolia.context.MgnlContext;
54 import info.magnolia.cms.core.HierarchyManager;
55
56 import javax.jcr.InvalidItemStateException;
57 import javax.jcr.PathNotFoundException;
58 import javax.jcr.RepositoryException;
59 import javax.jcr.UnsupportedRepositoryOperationException;
60 import javax.jcr.version.Version;
61 import javax.servlet.http.HttpServletRequest;
62 import javax.servlet.http.HttpServletResponse;
63
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67
68
69
70
71
72 public abstract class VersionsList extends AbstractList {
73
74 private static Logger log = LoggerFactory.getLogger(VersionsList.class);
75
76
77
78
79 private String repository;
80
81
82
83
84 protected String path;
85
86
87
88
89 private String versionLabel;
90
91 private String jsExecutedAfterSaving;
92
93
94
95
96
97
98
99 public VersionsList(String name, HttpServletRequest request, HttpServletResponse response) throws Exception {
100 super(name, request, response);
101 }
102
103
104
105
106 @Override
107 public ListModel getModel() {
108 try {
109 Content node = getNode();
110 return new VersionListModel(node, this.getMaxShowedVersions());
111 }
112 catch (Exception e) {
113 log.error("can't find node for version list {}", this.path);
114 }
115 return null;
116 }
117
118
119
120
121 protected int getMaxShowedVersions() {
122 return Math.min((int)VersionConfig.getInstance().getMaxVersionAllowed(), 50);
123 }
124
125 @Override
126 public void configureList(ListControl list) {
127
128 list.setRenderer(new AdminListControlRenderer() {
129 @Override
130 public String onDblClick(ListControl list, Integer index) {
131 return list.getName() + ".showItem()";
132 }
133
134 @Override
135 public String getJavaScriptClass() {
136 return "mgnl.admininterface.VersionsList";
137 }
138
139 @Override
140 protected String buildJavaScriptObject(ListControl list, Object value) {
141 return super.buildJavaScriptObject(list, value) + ", versionLabel: '" + list.getIteratorValue("versionLabel") + "'";
142 }
143
144 @Override
145 public String getConstructorArguments(ListControl list) {
146 return super.getConstructorArguments(list) + ", '"+repository+"', '"+path+"', " + getOnShowFunction() + ", " + getOnDiffFunction() ;
147 }
148
149 });
150
151 list.addGroupableField("userName");
152 list.addSortableField("created");
153 list.addColumn(new ListColumn("name", "Name", "150", true));
154 list.addColumn(new ListColumn("created", "Date", "100", true));
155 list.addColumn(new ListColumn("userName", "User", "100", true));
156 list.addColumn(new ListColumn("comment", "Comment", "150", true));
157 }
158
159
160
161
162 public abstract String getOnShowFunction();
163
164 @Override
165 protected void configureContextMenu(ContextMenu menu) {
166 ContextMenuItem show = new ContextMenuItem("show");
167 show.setLabel(MessagesManager.get("versions.show"));
168 show.setOnclick(this.getList().getName() + ".showItem()");
169 show.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/note_view.gif");
170 show.addJavascriptCondition("function(){return " + getList().getName()+".isSelected()}");
171
172 ContextMenuItem restore = new ContextMenuItem("restore");
173 restore.setLabel(MessagesManager.get("versions.restore"));
174 restore.setOnclick(this.getList().getName() + ".restore()");
175 restore.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/undo.gif");
176 restore.addJavascriptCondition("function(){return " + getList().getName()+".isSelected()}");
177
178 menu.addMenuItem(show);
179 menu.addMenuItem(restore);
180
181 if(isSupportsDiff()){
182 ContextMenuItem diffWithCurrent = new ContextMenuItem("diffWithCurrent");
183 diffWithCurrent.setLabel(MessagesManager.get("versions.compareWithCurrent"));
184 diffWithCurrent.setOnclick(this.getList().getName() + ".diffItemWithCurrent()");
185 diffWithCurrent.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/compare_with_current.gif");
186 diffWithCurrent.addJavascriptCondition("function(){return " + getList().getName()+".isSelected()}");
187
188 ContextMenuItem diffWithPrevious = new ContextMenuItem("diffWithPrevious");
189 diffWithPrevious.setLabel(MessagesManager.get("versions.compareWithPrevious"));
190 diffWithPrevious.setOnclick(this.getList().getName() + ".diffItemWithPrevious()");
191 diffWithPrevious.setIcon(MgnlContext.getContextPath() + "/.resources/icons/16/compare_with_previous.gif");
192 diffWithPrevious.addJavascriptCondition("function(){return " + getList().getName()+".hasPreviousVersion()}");
193
194 menu.addMenuItem(diffWithCurrent);
195 menu.addMenuItem(diffWithPrevious);
196 }
197 }
198
199 protected boolean isSupportsDiff() {
200 return false;
201 }
202
203
204
205
206 @Override
207 protected void configureFunctionBar(FunctionBar bar) {
208 bar.addMenuItem(new FunctionBarItem(this.getContextMenu().getMenuItemByName("show")));
209 bar.addMenuItem(new FunctionBarItem(this.getContextMenu().getMenuItemByName("restore")));
210
211 if(isSupportsDiff()){
212 bar.addMenuItem(new FunctionBarItem(this.getContextMenu().getMenuItemByName("diffWithCurrent")));
213 bar.addMenuItem(new FunctionBarItem(this.getContextMenu().getMenuItemByName("diffWithPrevious")));
214 }
215 }
216
217
218
219
220
221
222
223 protected Content getNode() throws PathNotFoundException, RepositoryException, AccessDeniedException {
224 HierarchyManager hm = MgnlContext.getHierarchyManager(this.getRepository());
225 Content node = hm.getContent(this.getPath());
226 return node;
227 }
228
229 public String restore() {
230 try {
231 final Content node = this.getNode();
232 final String version = this.getVersionLabel();
233 node.addVersion();
234 try {
235 node.restore(version, true);
236 } catch (InvalidItemStateException e) {
237 node.refresh(false);
238 node.restore(version, true);
239 }
240 AlertUtil.setMessage(MessagesManager.get("versions.restore.latest.success"));
241 }
242 catch (Exception e) {
243 log.error("can't restore", e);
244 AlertUtil.setMessage(MessagesManager.get("versions.restore.exception", new String[]{e.getMessage()}));
245 }
246 return show();
247 }
248
249 public String restoreRecursive() {
250 try {
251 restoreRecursive(this.getNode(), this.getVersionLabel());
252 AlertUtil.setMessage(MessagesManager.get("versions.restore.latest.success"));
253 } catch (Exception e) {
254 log.error("can't restore", e);
255 AlertUtil.setMessage(MessagesManager.get("versions.restore.exception", new String[]{e.getMessage()}));
256 }
257 return show();
258 }
259
260 private String restoreRecursive(Content node, String version) throws UnsupportedRepositoryOperationException, RepositoryException {
261 node.addVersion();
262
263 try {
264 node.restore(version, true);
265 } catch (InvalidItemStateException e) {
266 node.refresh(false);
267 node.restore(version, true);
268 }
269
270
271 for (Content child : node.getChildren()) {
272
273 Collection<Version> versions = VersionUtil.getSortedNotDeletedVersions(child);
274 if (versions.size() > 0) {
275 String childVersion = versions.iterator().next().getName();
276 restoreRecursive(child, childVersion);
277 }
278 }
279 return show();
280 }
281
282
283
284
285 public String getPath() {
286 return this.path;
287 }
288
289
290
291
292 public void setPath(String path) {
293 this.path = path;
294 }
295
296
297
298
299 public String getRepository() {
300 return this.repository;
301 }
302
303
304
305
306 public void setRepository(String repository) {
307 this.repository = repository;
308 }
309
310 @Override
311 public String onRender() {
312 return FreemarkerUtil.process(VersionsList.class, this);
313 }
314
315
316
317
318 public String getVersionLabel() {
319 return this.versionLabel;
320 }
321
322
323
324
325 public void setVersionLabel(String versionLabel) {
326 this.versionLabel = versionLabel;
327 }
328
329 public String getOnDiffFunction() {
330 return "function(versionLabel){}";
331 }
332
333 public String getJsExecutedAfterSaving() {
334 return this.jsExecutedAfterSaving;
335 }
336
337 public void setJsExecutedAfterSaving(String jsExecutedAfterSaving) {
338 this.jsExecutedAfterSaving = jsExecutedAfterSaving;
339 }
340 }