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