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.pages;
35
36 import info.magnolia.cms.beans.config.ContentRepository;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.Content.ContentFilter;
39 import info.magnolia.cms.core.HierarchyManager;
40 import info.magnolia.cms.core.ItemType;
41 import info.magnolia.cms.core.Path;
42 import info.magnolia.cms.i18n.MessagesManager;
43 import info.magnolia.cms.security.AccessDeniedException;
44 import info.magnolia.cms.util.AlertUtil;
45 import info.magnolia.cms.util.ContentUtil;
46 import info.magnolia.cms.util.NodeDataUtil;
47 import info.magnolia.context.MgnlContext;
48 import info.magnolia.importexport.DataTransporter;
49 import info.magnolia.module.ModuleRegistry;
50 import info.magnolia.module.admininterface.TemplatedMVCHandler;
51 import info.magnolia.module.files.BasicFileExtractor;
52 import info.magnolia.module.files.FileExtractor;
53 import info.magnolia.module.files.ModuleFileExtractorTransformer;
54 import info.magnolia.repository.RepositoryConstants;
55
56 import java.io.File;
57 import java.io.FileNotFoundException;
58 import java.io.FileOutputStream;
59 import java.io.IOException;
60 import java.util.HashSet;
61 import java.util.Iterator;
62 import java.util.Set;
63
64 import javax.jcr.PathNotFoundException;
65 import javax.jcr.RepositoryException;
66 import javax.jcr.Session;
67 import javax.servlet.http.HttpServletRequest;
68 import javax.servlet.http.HttpServletResponse;
69
70 import org.apache.commons.io.IOUtils;
71 import org.apache.commons.lang.StringUtils;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75
76
77
78
79
80
81 public class DevelopmentUtilsPage extends TemplatedMVCHandler {
82
83 private boolean templates;
84
85 private boolean paragraphs;
86
87 private boolean dialogs;
88
89 private boolean pages;
90
91 private boolean website;
92
93 private boolean users;
94
95 private boolean groups;
96
97 private boolean roles;
98
99 private boolean virtualURIs;
100
101 private String rootdir;
102
103 private String parentpath;
104
105 private String repository;
106
107 private String module;
108
109 private ContentFilter chieldFilter;
110
111
112
113
114 public static Logger log = LoggerFactory.getLogger(DevelopmentUtilsPage.class);
115
116
117
118
119
120
121 public DevelopmentUtilsPage(String name, HttpServletRequest request, HttpServletResponse response) {
122 super(name, request, response);
123
124 rootdir = StringUtils.defaultIfEmpty(NodeDataUtil.getString(
125 RepositoryConstants.CONFIG,
126 "/modules/adminInterface/config/developmentUtils/exportpath"), "WEB-INF/bootstrap/common");
127 module = StringUtils.defaultIfEmpty(NodeDataUtil.getString(
128 RepositoryConstants.CONFIG,
129 "/modules/adminInterface/config/developmentUtils/module"), "templating");
130 }
131
132
133
134
135
136 public boolean isTemplates() {
137 return this.templates;
138 }
139
140
141
142
143
144 public boolean isParagraphs() {
145 return this.paragraphs;
146 }
147
148
149
150
151
152 public boolean isDialogs() {
153 return this.dialogs;
154 }
155
156
157
158
159
160 public boolean isPages() {
161 return this.pages;
162 }
163
164
165
166
167
168
169 public void setChieldFilter(ContentFilter chieldFilter) {
170 this.chieldFilter = chieldFilter;
171 }
172
173
174
175
176
177 public void setPages(boolean pages) {
178 this.pages = pages;
179 }
180
181
182
183
184
185 public boolean isWebsite() {
186 return this.website;
187 }
188
189
190
191
192
193 public boolean isUsers() {
194 return this.users;
195 }
196
197
198
199
200
201 public boolean isGroups() {
202 return this.groups;
203 }
204
205
206
207
208
209 public boolean isRoles() {
210 return this.roles;
211 }
212
213
214
215
216
217 public String getRootdir() {
218 return this.rootdir;
219 }
220
221
222
223
224
225 public String getParentpath() {
226 return this.parentpath;
227 }
228
229
230
231
232
233 public String getRepository() {
234 return this.repository;
235 }
236
237
238
239
240
241 public void setDialogs(boolean dialogs) {
242 this.dialogs = dialogs;
243 }
244
245
246
247
248
249 public void setParagraphs(boolean paragraphs) {
250 this.paragraphs = paragraphs;
251 }
252
253
254
255
256
257 public void setTemplates(boolean templates) {
258 this.templates = templates;
259 }
260
261
262
263
264
265 public void setRootdir(String rootdir) {
266 this.rootdir = rootdir;
267 }
268
269
270
271
272
273 public void setWebsite(boolean website) {
274 this.website = website;
275 }
276
277
278
279
280
281 public void setParentpath(String parentpath) {
282 this.parentpath = parentpath;
283 }
284
285
286
287
288
289 public void setGroups(boolean groups) {
290 this.groups = groups;
291 }
292
293
294
295
296
297 public void setRoles(boolean roles) {
298 this.roles = roles;
299 }
300
301
302
303
304
305 public void setUsers(boolean users) {
306 this.users = users;
307 }
308
309
310
311
312
313 public String getModule() {
314 return this.module;
315 }
316
317
318
319
320
321 public void setModule(String module) {
322 this.module = module;
323 }
324
325
326
327
328
329 public void setRepository(String repository) {
330 this.repository = repository;
331 }
332
333
334
335
336
337 public boolean isVirtualURIs() {
338 return this.virtualURIs;
339 }
340
341
342
343
344
345 public void setVirtualURIs(boolean virtualURIs) {
346 this.virtualURIs = virtualURIs;
347 }
348
349 public Iterator getRepositories() {
350 return ContentRepository.getAllRepositoryNames();
351 }
352
353 public Set getModules() {
354 return ModuleRegistry.Factory.getInstance().getModuleNames();
355 }
356
357
358 public String extractModuleFiles() {
359 final FileExtractor extractor = new BasicFileExtractor();
360 try {
361 extractor.extractFiles(new ModuleFileExtractorTransformer(module));
362 AlertUtil.setMessage("Files extracted");
363 }
364 catch (IOException e) {
365 AlertUtil.setMessage("Could not extract files for module " + module + ": " + e.getMessage(), e);
366 }
367
368 return this.show();
369 }
370
371 public String reloadI18nMessages() {
372 try {
373 MessagesManager.getInstance().reload();
374 AlertUtil.setMessage("Messages reloaded.");
375 }
376 catch (Exception e) {
377 e.printStackTrace();
378 AlertUtil.setMessage("Can't reload: " + e.getMessage(), e);
379 }
380
381 return this.show();
382 }
383
384 public String backup() {
385 HierarchyManager hm = MgnlContext.getHierarchyManager(RepositoryConstants.CONFIG);
386 Session session = hm.getWorkspace().getSession();
387
388 try {
389 Content moduleroot = hm.getContent("/modules/" + module);
390 if (templates) {
391 exportChildren(RepositoryConstants.CONFIG, session, moduleroot, "templates", new ItemType[]{
392 ItemType.CONTENT,
393 ItemType.CONTENTNODE}, false);
394 }
395 if (paragraphs) {
396 exportChildren(RepositoryConstants.CONFIG, session, moduleroot, "paragraphs", new ItemType[]{
397 ItemType.CONTENT,
398 ItemType.CONTENTNODE}, false);
399 }
400 if (pages) {
401 exportChildren(RepositoryConstants.CONFIG, session, moduleroot, "pages", new ItemType[]{
402 ItemType.CONTENT,
403 ItemType.CONTENTNODE}, false);
404 }
405 if (dialogs) {
406 exportChildren(RepositoryConstants.CONFIG, session, moduleroot, "dialogs", new ItemType[]{
407 ItemType.CONTENT,
408 ItemType.CONTENTNODE}, true);
409 }
410 if (virtualURIs) {
411 exportChildren(
412 RepositoryConstants.CONFIG,
413 session,
414 moduleroot,
415 "virtualURIMapping",
416 new ItemType[]{ItemType.CONTENTNODE},
417 true);
418 }
419 AlertUtil.setMessage("Backup done to "
420 + new File(Path.getAbsoluteFileSystemPath(rootdir)).getCanonicalPath());
421 }
422 catch (Exception e) {
423 log.error(e.getMessage(), e);
424 AlertUtil.setMessage("Error while processing module " + module, e);
425 }
426
427 if (website) {
428 extractWorkspaceRoots(RepositoryConstants.WEBSITE);
429 }
430
431 if (users) {
432 backupChildren(RepositoryConstants.USERS, "/admin");
433 }
434
435 if (groups) {
436 extractWorkspaceRoots(RepositoryConstants.USER_GROUPS);
437 }
438
439 if (roles) {
440 extractWorkspaceRoots(RepositoryConstants.USER_ROLES);
441 }
442
443 return this.show();
444 }
445
446
447
448
449 private void extractWorkspaceRoots(String repositoryName) {
450 try {
451 HierarchyManager hm = MgnlContext.getHierarchyManager(repositoryName);
452 Content wesiteRoot = hm.getRoot();
453
454 Iterator children = wesiteRoot.getChildren(ContentUtil.MAGNOLIA_FILTER).iterator();
455 while (children.hasNext()) {
456 Content exported = (Content) children.next();
457 exportNode(repositoryName, hm.getWorkspace().getSession(), exported);
458 }
459 }
460 catch (Exception e) {
461 log.error(e.getMessage(), e);
462 AlertUtil.setMessage("Error while processing " + repositoryName + " repository", e);
463 }
464 }
465
466 public String backupChildren() {
467 backupChildren(this.repository, this.parentpath);
468
469 String path = Path.getAbsoluteFileSystemPath(rootdir);
470
471 try {
472 path = new File(path).getCanonicalPath();
473 }
474 catch (IOException e) {
475
476 }
477
478 AlertUtil.setMessage("Backup done to " + path);
479
480 return this.show();
481 }
482
483 private void backupChildren(String repository, String parentpath) {
484 HierarchyManager hm = MgnlContext.getHierarchyManager(repository);
485
486 Content parentNode = null;
487 try {
488 parentNode = hm.getContent(parentpath);
489 }
490 catch (RepositoryException e) {
491
492 return;
493 }
494 try {
495 this.chieldFilter = this.chieldFilter!=null?this.chieldFilter:ContentUtil.ALL_NODES_EXCEPT_JCR_CONTENT_FILTER;
496 Iterator children = parentNode.getChildren(this.chieldFilter).iterator();
497 while (children.hasNext()) {
498 Content exported = (Content) children.next();
499 exportNode(repository, hm.getWorkspace().getSession(), exported);
500 }
501
502 }
503 catch (Exception e) {
504 log.error(e.getMessage(), e);
505 AlertUtil.setMessage("Error while processing actions", e);
506 }
507
508 }
509
510
511
512
513
514
515
516
517
518
519
520 private void exportChildren(String repository, Session session, Content moduleroot, String path,
521 ItemType[] itemTypes, boolean exportContentContainingContentNodes) throws PathNotFoundException,
522 RepositoryException, AccessDeniedException, FileNotFoundException, IOException {
523 Content templateRoot = null;
524 try {
525 templateRoot = moduleroot.getContent(path);
526 }
527 catch (PathNotFoundException e) {
528
529 return;
530 }
531
532
533 Set alreadyExported = new HashSet();
534
535 Iterator children = ContentUtil.collectAllChildren(templateRoot, itemTypes).iterator();
536 while (children.hasNext()) {
537 Content exported = (Content) children.next();
538 if (!exported.getNodeDataCollection().isEmpty()
539 || (exportContentContainingContentNodes && exported.hasChildren(ItemType.CONTENTNODE.getSystemName()))) {
540
541 String current = exported.getHandle();
542 boolean dontexport = false;
543
544 for (Iterator iterator = alreadyExported.iterator(); iterator.hasNext();) {
545 String already = (String) iterator.next();
546 if (current.startsWith(already)) {
547 dontexport = true;
548 break;
549 }
550 }
551
552 if (!dontexport) {
553 alreadyExported.add(exported.getHandle() + "/");
554 exportNode(repository, session, exported);
555 }
556 }
557 }
558 }
559
560
561
562
563
564
565
566 private void exportNode(String repository, Session session, Content exported) throws FileNotFoundException,
567 IOException {
568 String handle = exported.getHandle();
569 String xmlName = repository + StringUtils.replace(handle, "/", ".") + ".xml";
570 xmlName = DataTransporter.encodePath(xmlName, ".", "UTF-8");
571
572 File folder = new File(Path.getAbsoluteFileSystemPath(rootdir));
573 folder.mkdirs();
574 File xmlFile = new File(folder.getAbsoluteFile(), xmlName);
575 FileOutputStream fos = new FileOutputStream(xmlFile);
576
577 try {
578 DataTransporter.executeExport(fos, false, true, session, handle, repository, DataTransporter.XML);
579 }
580 finally {
581 IOUtils.closeQuietly(fos);
582 }
583 }
584 }