1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.wiki.mow.core.api.wiki;
18
19 import org.chromattic.api.ChromatticSession;
20 import org.chromattic.api.DuplicateNameException;
21 import org.chromattic.api.RelationshipType;
22 import org.chromattic.api.annotations.*;
23 import org.chromattic.api.annotations.Property;
24 import org.chromattic.ext.ntdef.NTFolder;
25 import org.chromattic.ext.ntdef.Resource;
26 import org.exoplatform.portal.config.model.PortalConfig;
27 import org.exoplatform.services.jcr.RepositoryService;
28 import org.exoplatform.services.jcr.ext.common.SessionProvider;
29 import org.exoplatform.services.log.ExoLogger;
30 import org.exoplatform.services.log.Log;
31 import org.exoplatform.services.security.ConversationState;
32 import org.exoplatform.services.security.Identity;
33 import org.exoplatform.wiki.WikiException;
34 import org.exoplatform.wiki.chromattic.ext.ntdef.NTVersion;
35 import org.exoplatform.wiki.chromattic.ext.ntdef.UncachedMixin;
36 import org.exoplatform.wiki.chromattic.ext.ntdef.VersionableMixin;
37 import org.exoplatform.wiki.mow.api.Permission;
38 import org.exoplatform.wiki.mow.core.api.MOWService;
39 import org.exoplatform.wiki.rendering.converter.ConfluenceToXWiki2Transformer;
40 import org.exoplatform.wiki.rendering.util.Utils;
41 import org.exoplatform.wiki.resolver.TitleResolver;
42 import org.exoplatform.wiki.mow.api.PermissionType;
43 import org.exoplatform.wiki.utils.WikiConstants;
44 import org.xwiki.component.manager.ComponentManager;
45 import org.xwiki.rendering.syntax.Syntax;
46
47 import javax.jcr.*;
48 import javax.jcr.query.Query;
49 import javax.jcr.version.Version;
50 import javax.jcr.version.VersionIterator;
51 import java.util.*;
52 import java.util.Map.Entry;
53
54 @PrimaryType(name = WikiNodeType.WIKI_PAGE)
55 public abstract class PageImpl extends NTFolder {
56
57 private static final Log LOG = ExoLogger.getLogger(PageImpl.class.getName());
58
59 private MOWService mowService;
60
61 private PermissionImpl permission = new PermissionImpl();
62
63 private ComponentManager componentManager;
64
65
66
67
68 private List<PageImpl> relatedPages = null;
69
70 private boolean isMinorEdit = false;
71
72 public String getID() throws RepositoryException {
73 return this.getJCRPageNode().getUUID();
74 }
75 public void setMOWService(MOWService mowService) {
76 this.mowService = mowService;
77 permission.setMOWService(mowService);
78 }
79
80 public MOWService getMOWService() {
81 return mowService;
82 }
83
84 public ChromatticSession getChromatticSession() {
85 return mowService.getSession();
86 }
87
88 public Session getJCRSession() {
89 return getChromatticSession().getJCRSession();
90 }
91
92 public void setComponentManager(ComponentManager componentManager) {
93 this.componentManager = componentManager;
94 }
95
96 public Node getJCRPageNode() throws RepositoryException {
97 return (Node) getChromatticSession().getJCRSession().getItem(getPath());
98 }
99
100 @Name
101 @Override
102 public abstract String getName();
103 public abstract void setName(String name);
104
105 @Path
106 public abstract String getPath();
107
108 @WorkspaceName
109 public abstract String getWorkspace();
110
111 @OneToOne
112 @Owner
113 @MappedBy(WikiNodeType.Definition.CONTENT)
114 protected abstract AttachmentImpl getContentByChromattic();
115
116 protected abstract void setContentByChromattic(AttachmentImpl content);
117
118 @Create
119 protected abstract AttachmentImpl createContent();
120
121 public AttachmentImpl getContent() {
122 AttachmentImpl content = getContentByChromattic();
123 if (content == null) {
124 content = createContent();
125 setContentByChromattic(content);
126 content.setText("");
127 } else {
128 String syntax = getSyntax();
129 if (Syntax.CONFLUENCE_1_0.toIdString().equals(syntax)) {
130 content.setText(ConfluenceToXWiki2Transformer.transformContent(content.getText(), componentManager));
131 setSyntax(Syntax.XWIKI_2_0.toIdString());
132 setContentByChromattic(content);
133 }
134 }
135 return content;
136 }
137
138 @Property(name = WikiNodeType.Definition.TITLE)
139 public abstract String getTitleByChromattic();
140 public abstract void setTitleByChromattic(String title);
141
142 public String getTitle() {
143 String title = getTitleByChromattic();
144 return (title != null) ? title : getName();
145 }
146
147 public void setTitle(String title) {
148 setTitleByChromattic(title);
149 }
150
151 @Property(name = WikiNodeType.Definition.SYNTAX)
152 public abstract String getSyntax();
153 public abstract void setSyntax(String syntax);
154
155 @Property(name = WikiNodeType.Definition.COMMENT)
156 @DefaultValue({""})
157 public abstract String getComment();
158 public abstract void setComment(String comment);
159
160 @Property(name = WikiNodeType.Definition.OWNER)
161 public abstract String getOwner();
162 public abstract void setOwner(String owner);
163
164 @Property(name = WikiNodeType.Definition.AUTHOR)
165 public abstract String getAuthor();
166 public abstract void setAuthor(String author);
167
168 @Property(name = WikiNodeType.Definition.CREATED_DATE)
169 public abstract Date getCreatedDate();
170 public abstract void setCreatedDate(Date date);
171
172 @Property(name = WikiNodeType.Definition.UPDATED_DATE)
173 public abstract Date getUpdatedDate();
174 public abstract void setUpdatedDate(Date date);
175
176 @Property(name = WikiNodeType.Definition.URL)
177 public abstract String getURL();
178 public abstract void setURL(String url);
179
180 @OneToOne(type = RelationshipType.EMBEDDED)
181 @Owner
182 public abstract ActivityInfoMixin getActivityInfoMixin();
183 public abstract void setActivityInfoMixin(ActivityInfoMixin activity);
184
185 @OneToOne(type = RelationshipType.EMBEDDED)
186 @Owner
187 public abstract MovedMixin getMovedMixin();
188 public abstract void setMovedMixin(MovedMixin move);
189
190 @OneToOne(type = RelationshipType.EMBEDDED)
191 @Owner
192 public abstract RemovedMixin getRemovedMixin();
193 public abstract void setRemovedMixin(RemovedMixin remove);
194
195 @OneToOne(type = RelationshipType.EMBEDDED)
196 @Owner
197 public abstract RenamedMixin getRenamedMixin();
198 public abstract void setRenamedMixin(RenamedMixin mix);
199
200 @OneToOne(type = RelationshipType.EMBEDDED)
201 @Owner
202 public abstract UncachedMixin getUncachedMixin();
203 public abstract void setUncachedMixin(UncachedMixin mix);
204
205 @OneToOne(type = RelationshipType.EMBEDDED)
206 @Owner
207 public abstract WatchedMixin getWatchedMixin();
208 public abstract void setWatchedMixin(WatchedMixin mix);
209
210 @Create
211 protected abstract WatchedMixin createWatchedMixin();
212
213 @OneToOne(type = RelationshipType.EMBEDDED)
214 @Owner
215 public abstract MigratingMixin getMigratingMixin();
216 public abstract void setMigratingMixin(MigratingMixin mix);
217
218 @Create
219 protected abstract MigratingMixin createMigratingMixin();
220
221 public void makeWatched() {
222 WatchedMixin watchedMixin = getWatchedMixin();
223 if (watchedMixin == null) {
224 watchedMixin = createWatchedMixin();
225 setWatchedMixin(watchedMixin);
226 }
227 }
228
229 public VersionableMixin getVersionableMixin() {
230 try {
231 migrateLegacyData();
232 } catch (Exception e) {
233 if (LOG.isWarnEnabled()) {
234 LOG.warn("Can not migrate legacy version data", e.getMessage());
235 }
236 }
237 return getContent().getVersionableMixin();
238 }
239
240 public void makeVersionable() {
241 this.getContent().makeVersionable();
242 }
243
244
245
246 public NTVersion checkin() throws RepositoryException {
247 PageDescriptionMixin description = getContent().getPageDescriptionMixin();
248 description.setAuthor(ConversationState.getCurrent().getIdentity().getUserId());
249 description.setUpdatedDate(GregorianCalendar.getInstance().getTime());
250 description.setComment(this.getComment());
251
252 NTVersion ret = getContent().checkin();
253 return ret;
254 }
255
256
257 public void checkout() throws RepositoryException {
258 getContent().checkout();
259 }
260
261
262 public void restore(String versionName, boolean removeExisting) throws WikiException {
263 getContent().restore(versionName, removeExisting);
264 }
265
266 @Create
267 public abstract AttachmentImpl createAttachment();
268
269 public AttachmentImpl createAttachment(String fileName, Resource contentResource) throws WikiException {
270 if (fileName == null) {
271 throw new NullPointerException();
272 }
273 Iterator<AttachmentImpl> attIter= getAttachments().iterator();
274 while (attIter.hasNext()) {
275 AttachmentImpl att = attIter.next();
276 if (att.getName().equals(fileName)) {
277 att.remove();
278 }
279 }
280
281 AttachmentImpl file = createAttachment();
282 file.setName(TitleResolver.getId(fileName, false));
283 addAttachment(file);
284 if (fileName.lastIndexOf(".") > 0) {
285 file.setTitle(fileName.substring(0, fileName.lastIndexOf(".")));
286 file.setFileType(fileName.substring(fileName.lastIndexOf(".")));
287 } else {
288 file.setTitle(fileName);
289 }
290
291 if (contentResource != null) {
292 file.setContentResource(contentResource);
293 }
294 getChromatticSession().save();
295 setFullPermissionForOwner(file);
296 return file;
297 }
298
299 private void setFullPermissionForOwner(AttachmentImpl file) throws WikiException {
300 ConversationState conversationState = ConversationState.getCurrent();
301
302 if (conversationState != null) {
303 HashMap<String, String[]> permissions = file.getPermission();
304 permissions.put(conversationState.getIdentity().getUserId(), org.exoplatform.services.jcr.access.PermissionType.ALL);
305 file.setPermission(permissions);
306 }
307 }
308
309 @OneToMany
310 public abstract Collection<AttachmentImpl> getAttachmentsByChromattic();
311
312 public Collection<AttachmentImpl> getAttachments() {
313 return getAttachmentsByChromattic();
314 }
315
316 public Collection<AttachmentImpl> getAttachmentsExcludeContent() throws RepositoryException {
317 List<AttachmentImpl> atts = new ArrayList<AttachmentImpl>();
318 String path = this.getPath();
319 StringBuilder statement = new StringBuilder("SELECT * FROM ");
320 statement.append(WikiNodeType.WIKI_ATTACHMENT)
321 .append(" WHERE jcr:path LIKE '").append(path)
322 .append("/%' AND NOT jcr:path LIKE '").append(path).append("/%/%'");
323 NodeIterator iter = getChromatticSession().getJCRSession().getWorkspace()
324 .getQueryManager().createQuery(statement.toString(), Query.SQL)
325 .execute().getNodes();
326 while (iter.hasNext()) {
327 Node node = iter.nextNode();
328 AttachmentImpl att = this.getChromatticSession().findByNode(AttachmentImpl.class, node);
329 if ((att.hasPermission(PermissionType.VIEW_ATTACHMENT)
330 || att.hasPermission(PermissionType.EDIT_ATTACHMENT))
331 && !WikiNodeType.Definition.CONTENT.equals(att.getName())) {
332 atts.add(att);
333 }
334 }
335 Collections.sort(atts);
336 return atts;
337 }
338
339 public Collection<AttachmentImpl> getAttachmentsExcludeContentByRootPermisison() {
340 Collection<AttachmentImpl> attachments = getAttachmentsByChromattic();
341 List<AttachmentImpl> atts = new ArrayList<AttachmentImpl>(attachments.size());
342 for (AttachmentImpl attachment : attachments) {
343 if (!WikiNodeType.Definition.CONTENT.equals(attachment.getName())) {
344 atts.add(attachment);
345 }
346 }
347 Collections.sort(atts);
348 return atts;
349 }
350
351 public AttachmentImpl getAttachment(String attachmentId) {
352 for (AttachmentImpl attachment : getAttachments()) {
353 if (attachment.getName().equals(attachmentId)
354 && (attachment.hasPermission(PermissionType.VIEW_ATTACHMENT)
355 || attachment.hasPermission(PermissionType.EDIT_ATTACHMENT))) {
356 return attachment;
357 }
358 }
359 return null;
360 }
361
362 public AttachmentImpl getAttachmentByRootPermisison(String attachmentId) throws Exception {
363 for (AttachmentImpl attachment : getAttachments()) {
364 if (attachment.getName().equals(attachmentId)) {
365 return attachment;
366 }
367 }
368 return null;
369 }
370
371 public void addAttachment(AttachmentImpl attachment) throws DuplicateNameException {
372 getAttachments().add(attachment);
373 }
374
375 public void removeAttachment(String attachmentId) {
376 AttachmentImpl attachment = getAttachment(attachmentId);
377 if(attachment != null){
378 attachment.remove();
379 }
380 }
381
382 @ManyToOne
383 public abstract PageImpl getParentPage();
384 public abstract void setParentPage(PageImpl page);
385
386 @ManyToOne
387 public abstract Trash getTrash();
388 public abstract void setTrash(Trash trash);
389
390 @OneToMany
391 protected abstract Map<String, PageImpl> getChildrenContainer();
392
393 public Map<String, PageImpl> getChildPages() {
394 TreeMap<String, PageImpl> result = new TreeMap<>(new Comparator<String>() {
395 @Override
396 public int compare(String o1, String o2) {
397 return o1.compareTo(o2);
398 }
399 });
400 List<PageImpl> pages = new ArrayList<PageImpl>(getChildrenContainer().values());
401
402 for (int i = 0; i < pages.size(); i++) {
403 PageImpl page = pages.get(i);
404 if (page != null && page.hasPermission(PermissionType.VIEWPAGE)) {
405 result.put(page.getName(), page);
406 }
407 }
408 return result;
409 }
410
411 public Map<String, PageImpl> getChildrenByRootPermission() {
412 TreeMap<String, PageImpl> result = new TreeMap<String, PageImpl>(new Comparator<String>() {
413 @Override
414 public int compare(String o1, String o2) {
415 return o1.compareTo(o2);
416 }
417 });
418 List<PageImpl> pages = new ArrayList<PageImpl>(getChildrenContainer().values());
419
420 for (int i = 0; i < pages.size(); i++) {
421 PageImpl page = pages.get(i);
422 if (page != null) {
423 result.put(page.getTitle(), page);
424 }
425 }
426 return result;
427 }
428
429 @Property(name = WikiNodeType.Definition.OVERRIDEPERMISSION)
430 public abstract boolean getOverridePermission();
431 public abstract void setOverridePermission(boolean isOverridePermission);
432
433 public boolean hasPermission(PermissionType permissionType) {
434 return permission.hasPermission(permissionType, getPath());
435 }
436
437 public boolean hasPermission(PermissionType permissionType, Identity user) {
438 return permission.hasPermission(permissionType, getPath(), user);
439 }
440
441 public HashMap<String, String[]> getPermission() throws WikiException {
442 return permission.getPermission(getPath());
443 }
444
445 public void setPermission(HashMap<String, String[]> permissions) throws WikiException {
446 permission.setPermission(permissions, getPath());
447 }
448
449 public void setNonePermission() throws WikiException {
450 setPermission(null);
451 }
452
453 public String getActivityId() {
454 String activityId = null;
455 ActivityInfoMixin activityInfoMixin = this.getActivityInfoMixin();
456 if(activityInfoMixin != null) {
457 activityId = activityInfoMixin.getActivityId();
458 }
459 return activityId;
460 }
461
462 public void setActivityId(String activityId) {
463 ActivityInfoMixin activityInfoMixin = this.getActivityInfoMixin();
464 if(activityInfoMixin == null) {
465 ChromatticSession session = mowService.getSession();
466 this.setActivityInfoMixin(session.create(ActivityInfoMixin.class));
467 ActivityInfoMixin mixin = this.getActivityInfoMixin();
468 mixin.setActivityId(activityId);
469 } else if(!activityId.equals(activityInfoMixin.getActivityId())) {
470 ActivityInfoMixin mixin = this.getActivityInfoMixin();
471 mixin.setActivityId(activityId);
472 }
473 }
474
475 protected void addPage(String pageName, PageImpl page) {
476 Map<String, PageImpl> children = getChildrenContainer();
477 if (children.containsKey(pageName)) {
478 throw new IllegalStateException("Page with name " + pageName + " already exists");
479 }
480 children.put(pageName, page);
481 }
482
483 public void addWikiPage(PageImpl page) {
484 addPage(page.getName(), page);
485 }
486
487 public void addPublicPage(PageImpl page) throws WikiException {
488 addWikiPage(page);
489 page.setNonePermission();
490 }
491
492 public PageImpl getWikiPage(String pageId) throws Exception{
493 if(WikiConstants.WIKI_HOME_NAME.equalsIgnoreCase(pageId)){
494 return this;
495 }
496 Iterator<PageImpl> iter = getChildPages().values().iterator();
497 while(iter.hasNext()) {
498 PageImpl page = (PageImpl)iter.next() ;
499 if (pageId.equals(page.getName())) return page ;
500 }
501 return null ;
502 }
503
504 public WikiImpl getWiki() {
505 WikiHome wikiHome = getWikiHome();
506 if (wikiHome != null) {
507 PortalWiki portalWiki = wikiHome.getPortalWiki();
508 GroupWiki groupWiki = wikiHome.getGroupWiki();
509 UserWiki userWiki = wikiHome.getUserWiki();
510 if (portalWiki != null) {
511 return portalWiki;
512 } else if (groupWiki != null) {
513 return groupWiki;
514 } else {
515 return userWiki;
516 }
517 }
518 return null;
519 }
520
521 public WikiHome getWikiHome() {
522 PageImpl parent = this.getParentPage();
523 if (this instanceof WikiHome) {
524 parent = this;
525 } else
526 while (parent != null && !(parent instanceof WikiHome)) {
527 parent = parent.getParentPage();
528 }
529 return (WikiHome) parent;
530 }
531
532 public boolean isMinorEdit() {
533 return isMinorEdit;
534 }
535
536 public void setMinorEdit(boolean isMinorEdit) {
537 this.isMinorEdit = isMinorEdit;
538 }
539
540 @Destroy
541 public abstract void remove();
542
543
544
545
546
547
548
549
550
551 public synchronized String addRelatedPage(PageImpl page) throws RepositoryException {
552 Map<String, Value> referredUUIDs = getReferredUUIDs();
553 Session jcrSession = getJCRSession();
554 Node myJcrNode = (Node) jcrSession.getItem(getPath());
555 Node referredJcrNode = (Node) jcrSession.getItem(page.getPath());
556 String referedUUID = referredJcrNode.getUUID();
557 if (referredUUIDs.containsKey(referedUUID)) {
558 return null;
559 }
560 Value value2Add = jcrSession.getValueFactory().createValue(referredJcrNode);
561 referredUUIDs.put(referedUUID, value2Add);
562
563 myJcrNode.setProperty(WikiNodeType.Definition.RELATION,
564 referredUUIDs.values().toArray(new Value[referredUUIDs.size()]));
565 myJcrNode.save();
566
567 if (relatedPages != null) relatedPages.add(page);
568 return referedUUID;
569 }
570
571 public List<PageImpl> getRelatedPages() throws RepositoryException {
572 if (relatedPages == null) {
573 relatedPages = new ArrayList<>();
574 Iterator<Entry<String, Value>> refferedIter = getReferredUUIDs().entrySet().iterator();
575 ChromatticSession chSession = getChromatticSession();
576 while (refferedIter.hasNext()) {
577 Entry<String, Value> entry = refferedIter.next();
578 PageImpl page = chSession.findById(PageImpl.class, entry.getValue().getString());
579 if(page != null && page.hasPermission(PermissionType.VIEWPAGE)){
580 relatedPages.add(page);
581 }
582 }
583 }
584 return new ArrayList<>(relatedPages);
585 }
586
587
588
589
590
591
592
593
594 public synchronized String removeRelatedPage(PageImpl page) throws RepositoryException {
595 Map<String, Value> referedUUIDs = getReferredUUIDs();
596 Session jcrSession = getJCRSession();
597 Node referredJcrNode = (Node) jcrSession.getItem(page.getPath());
598 Node myJcrNode = (Node) jcrSession.getItem(getPath());
599 String referredUUID = referredJcrNode.getUUID();
600 if (!referedUUIDs.containsKey(referredUUID)) {
601 return null;
602 }
603 referedUUIDs.remove(referredUUID);
604 myJcrNode.setProperty(WikiNodeType.Definition.RELATION,
605 referedUUIDs.values().toArray(new Value[referedUUIDs.size()]));
606 myJcrNode.save();
607
608 if (relatedPages != null) relatedPages.remove(page);
609 return referredUUID;
610 }
611
612
613
614
615
616
617
618 public Map<String, Value> getReferredUUIDs() throws RepositoryException {
619 Session jcrSession = getJCRSession();
620 Node myJcrNode = (Node) jcrSession.getItem(getPath());
621 Map<String, Value> referedUUIDs = new HashMap<String, Value>();
622 if (myJcrNode.hasProperty(WikiNodeType.Definition.RELATION)) {
623 Value[] values = myJcrNode.getProperty(WikiNodeType.Definition.RELATION).getValues();
624 if (values != null && values.length > 0) {
625 for (Value value : values) {
626 referedUUIDs.put(value.getString(), value);
627 }
628 }
629 }
630 return referedUUIDs;
631 }
632
633 public synchronized void removeAllRelatedPages() throws Exception {
634 Session jcrSession = getJCRSession();
635 Node myJcrNode = (Node) jcrSession.getItem(getPath());
636 myJcrNode.setProperty(WikiNodeType.Definition.RELATION, (Value[]) null);
637 myJcrNode.save();
638
639 if (relatedPages != null) relatedPages.clear();
640 }
641
642
643
644
645
646
647 public void migrateLegacyData() throws RepositoryException {
648
649 if (this.getJCRPageNode().isNodeType(WikiNodeType.MIX_VERSIONABLE) &&
650 (this.getContent().getVersionableMixinByChromattic() == null)) {
651 Node pageNode = this.getJCRPageNode();
652 if (LOG.isInfoEnabled()) {
653 LOG.info("Migrating history for wiki page: " + pageNode.getPath());
654 }
655
656 List<VersionData> versions = new ArrayList<VersionData>();
657 VersionIterator iter = pageNode.getVersionHistory().getAllVersions();
658 while (iter.hasNext()) {
659 Version v = iter.nextVersion();
660 if (v.hasNode(WikiNodeType.JCR_FROZEN_NODE)) {
661 String name = v.getName();
662 Node frozenNode = v.getNode(WikiNodeType.JCR_FROZEN_NODE);
663 String author = (frozenNode.hasProperty(WikiNodeType.Definition.AUTHOR) ?
664 frozenNode.getProperty(WikiNodeType.Definition.AUTHOR).getString() : "");
665 Calendar calendar = (frozenNode.hasProperty(WikiNodeType.Definition.UPDATED_DATE) ?
666 frozenNode.getProperty(WikiNodeType.Definition.UPDATED_DATE).getDate() :
667 GregorianCalendar.getInstance());
668 String content = (frozenNode.getNode(WikiNodeType.Definition.CONTENT)
669 .getNode(WikiNodeType.Definition.ATTACHMENT_CONTENT)
670 .getProperty(WikiNodeType.Definition.DATA).getString());
671 String comment = (frozenNode.hasProperty(WikiNodeType.Definition.COMMENT) ?
672 frozenNode.getProperty(WikiNodeType.Definition.COMMENT).getString() : "");
673 versions.add(new VersionData(name, author, calendar, content, comment));
674 }
675 }
676 Collections.sort(versions);
677
678 MigratingMixin migrateMix = this.createMigratingMixin();
679 this.setMigratingMixin(migrateMix);
680
681 this.makeVersionable();
682 AttachmentImpl content = this.getContent();
683
684 String currentContent = content.getText();
685
686 for (int i = 0; i < versions.size(); i++) {
687 if ((i % 10 == 0) && LOG.isInfoEnabled()) {
688 LOG.info("Creating new version: " + i);
689 }
690 PageDescriptionMixin description = content.getPageDescriptionMixin();
691 description.setAuthor(versions.get(i).getAuthor());
692 description.setUpdatedDate(versions.get(i).getCalendar().getTime());
693 content.setText(versions.get(i).getContent());
694 description.setComment(versions.get(i).getComment());
695 content.checkin();
696 content.checkout();
697 }
698
699 content.setText(currentContent);
700 this.getChromatticSession().setEmbedded(this, MigratingMixin.class, null);
701 pageNode.save();
702
703 removeMixVersionable(pageNode);
704 }
705 }
706
707 @OneToOne(type = RelationshipType.EMBEDDED)
708 @Owner
709 public abstract UpdateAttachmentMixin getUpdateAttachmentMixin();
710
711 public abstract void setUpdateAttachmentMixin(UpdateAttachmentMixin mix);
712
713 @Create
714 public abstract UpdateAttachmentMixin createUpdateAttachmentMixin();
715
716
717 public void migrateAttachmentPermission() throws WikiException {
718
719 boolean isGroupWiki = PortalConfig.GROUP_TYPE.equals(this.getWiki().getType());
720 UpdateAttachmentMixin updateAttachment = this.getUpdateAttachmentMixin();
721 if (updateAttachment == null) {
722 Collection<AttachmentImpl> attachments = this.getAttachmentsExcludeContentByRootPermisison();
723 Set<String> permissionKeys = new HashSet<String> (this.getPermission().keySet());
724 for (AttachmentImpl attachment : attachments) {
725 HashMap<String, String[]> permissions = attachment.getPermission();
726 Iterator<Entry<String, String[]>> permissionIterator = permissions.entrySet().iterator();
727 while (permissionIterator.hasNext()) {
728 Entry<String, String[]> attachmentPermissionEntry = permissionIterator.next();
729 String attachmentPermissionKey = attachmentPermissionEntry.getKey();
730 if (permissionKeys.contains(attachmentPermissionKey)) {
731 permissionKeys.remove(attachmentPermissionKey);
732 } else {
733 permissionIterator.remove();
734 }
735 }
736 for (String permissionEntry : permissionKeys) {
737 if (isGroupWiki && permissionEntry.contains(this.getWiki().getOwner())) {
738 permissions.put(permissionEntry, org.exoplatform.services.jcr.access.PermissionType.ALL);
739 } else {
740 permissions.put(permissionEntry, new String[] {org.exoplatform.services.jcr.access.PermissionType.READ});
741 }
742 }
743 attachment.setPermission(permissions);
744 }
745 updateAttachment = this.createUpdateAttachmentMixin();
746 this.setUpdateAttachmentMixin(updateAttachment);
747 }
748 }
749
750 private void removeMixVersionable(Node node) {
751 (new Thread(new RemoveMixVersionable(node))).start();
752 }
753
754 public class RemoveMixVersionable implements Runnable {
755 private String ws;
756 private String nodePath;
757
758 public RemoveMixVersionable(Node node) {
759 try {
760 ws = node.getSession().getWorkspace().getName();
761 nodePath = node.getPath();
762 } catch (RepositoryException e) {
763 ws = "";
764 nodePath = "";
765 }
766 }
767
768 public void run() {
769 if (LOG.isInfoEnabled()) {
770 LOG.info("Removing " + WikiNodeType.MIX_VERSIONABLE + " from " + ws + ": " + nodePath);
771 }
772 SessionProvider provider = SessionProvider.createSystemProvider();
773 try {
774 Session session = provider.getSession(ws, Utils.getService(RepositoryService.class).getCurrentRepository());
775 Node node = (Node)session.getItem(nodePath);
776 node.removeMixin(WikiNodeType.MIX_VERSIONABLE);
777 node.save();
778 if (LOG.isInfoEnabled()) {
779 LOG.info(WikiNodeType.MIX_VERSIONABLE + " was removed from " + ws + ": " + nodePath);
780 }
781 } catch (LoginException e) {
782 if (LOG.isWarnEnabled()) {
783 LOG.warn(WikiNodeType.MIX_VERSIONABLE + " cannot be removed from " + ws + ": " + nodePath);
784 }
785 } catch (NoSuchWorkspaceException e) {
786 if (LOG.isWarnEnabled()) {
787 LOG.warn(WikiNodeType.MIX_VERSIONABLE + " cannot be removed from " + ws + ": " + nodePath);
788 }
789 } catch (RepositoryException e) {
790 if (LOG.isWarnEnabled()) {
791 LOG.warn(WikiNodeType.MIX_VERSIONABLE + " cannot be removed from " + ws + ": " + nodePath);
792 }
793 }
794 provider.close();
795 }
796
797
798 }
799
800 public class VersionData implements Comparable<VersionData>{
801 private String name;
802 private String author;
803 private Calendar calendar;
804 private String content;
805 private String comment;
806
807 public String getName() { return name; }
808
809 public void setName(String name) { this.name = name; }
810
811 public String getAuthor() { return author; }
812
813 public void setAuthor(String author) { this.author = author; }
814
815 public Calendar getCalendar() { return calendar; }
816
817 public void setCalendar(Calendar calendar) { this.calendar = calendar; }
818
819 public String getContent() { return content; }
820
821 public void setContent(String content) { this.content = content; }
822
823 public String getComment() { return comment; }
824
825 public void setComment(String comment) { this.comment = comment; }
826
827
828 public VersionData(String name, String author, Calendar calendar, String content, String comment) {
829 this.name = name;
830 this.author = author;
831 this.calendar = calendar;
832 this.content = content;
833 this.comment = comment;
834 }
835
836 @Override
837 public int compareTo(VersionData arg0) {
838 return name.length() != arg0.name.length() ?
839 new Integer(name.length()).compareTo(arg0.name.length()) :
840 name.compareTo(arg0.name);
841 }
842
843 }
844 }