/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/msgcntr/trunk/messageforums-component-impl/src/java/org/sakaiproject/component/app/messageforums/DiscussionForumServiceImpl.java $ * $Id: DiscussionForumServiceImpl.java 9227 2006-05-15 15:02:42Z cwen@iupui.edu $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.component.app.messageforums; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import java.util.Vector; import java.util.HashSet; import java.util.ArrayList; import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.codec.binary.Base64; import org.sakaiproject.api.app.messageforums.Area; import org.sakaiproject.api.app.messageforums.Attachment; import org.sakaiproject.api.app.messageforums.DiscussionTopic; import org.sakaiproject.api.app.messageforums.AreaManager; import org.sakaiproject.api.app.messageforums.DiscussionForumService; import org.sakaiproject.api.app.messageforums.DiscussionForum; import org.sakaiproject.api.app.messageforums.MessageForumsForumManager; import org.sakaiproject.api.app.messageforums.MessageForumsMessageManager; import org.sakaiproject.api.app.messageforums.MessageForumsTypeManager; import org.sakaiproject.api.app.messageforums.PermissionLevel; import org.sakaiproject.api.app.messageforums.PermissionsMask; import org.sakaiproject.api.app.messageforums.ui.DiscussionForumManager; import org.sakaiproject.api.app.messageforums.DBMembershipItem; import org.sakaiproject.api.app.messageforums.PermissionLevelManager; import org.sakaiproject.authz.api.AuthzGroup; import org.sakaiproject.authz.cover.AuthzGroupService; import org.sakaiproject.authz.api.GroupNotDefinedException; import org.sakaiproject.authz.api.Role; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.EntityTransferrer; import org.sakaiproject.entity.api.EntityTransferrerRefMigrator; import org.sakaiproject.entity.api.HttpAccess; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.cover.EntityManager; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.content.api.ContentHostingService; import org.sakaiproject.content.api.ContentResource; import org.sakaiproject.service.gradebook.shared.GradebookService; import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.cover.SiteService; import org.sakaiproject.tool.cover.ToolManager; import org.sakaiproject.util.Validator; import org.sakaiproject.util.cover.LinkMigrationHelper; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DiscussionForumServiceImpl implements DiscussionForumService, EntityTransferrer, EntityTransferrerRefMigrator { private static final String MESSAGEFORUM = "messageforum"; private static final String DISCUSSION_FORUM = "discussion_forum"; private static final String DISCUSSION_TOPIC = "discussion_topic"; private static final String DISCUSSION_FORUM_TITLE = "category"; private static final String DISCUSSION_FORUM_DESC = "body"; private static final String DISCUSSION_FORUM_SHORT_DESC = "summary"; private static final String TOPIC_TITLE = "subject"; private static final String DRAFT = "draft"; private static final String LOCKED = "locked"; private static final String MODERATED = "moderated"; private static final String POST_FIRST = "post_first"; private static final String SORT_INDEX = "sort_index"; private static final String PROPERTIES = "properties"; private static final String PROPERTY = "property"; private static final String TOPIC_SHORT_DESC = "Classic:bboardForums_description"; private static final String TOPIC_LONG_DESC = "Classic:bboardForums_content"; private static final String NAME = "name"; private static final String ENCODE = "enc"; private static final String BASE64 = "BASE64"; private static final String VALUE = "value"; private static final String ATTACHMENT = "attachment"; private static final String ATTACH_ID = "relative-url"; private static final String PERMISSIONS = "permissions"; private static final String PERMISSION = "permission"; private static final String PERMISSION_TYPE = "permission_type"; private static final String PERMISSION_NAME = "permission_name"; private static final String PERMISSION_LEVEL_NAME = "permission_level_name"; private static final String CUSTOM_PERMISSIONS = "permission_levels"; private static final String ARCHIVE_VERSION = "2.4"; // in case new features are added in future exports private static final String VERSION_ATTR = "version"; private MessageForumsForumManager forumManager; private AreaManager areaManager; private MessageForumsMessageManager messageManager; private MessageForumsTypeManager typeManager; private DiscussionForumManager dfManager; private PermissionLevelManager permissionManager; private ContentHostingService contentHostingService; public void setContentHostingService(ContentHostingService contentHostingService) { this.contentHostingService = contentHostingService; } private static final Log LOG = LogFactory.getLog(DiscussionForumService.class); public void init() throws Exception { LOG.info("init()"); EntityManager.registerEntityProducer(this, REFERENCE_ROOT); } public String archive(String siteId, Document doc, Stack stack, String archivePath, List attachments) { Base64 base64Encoder = new Base64(); StringBuilder results = new StringBuilder(); try { int forumCount = 0; results.append("archiving " + getLabel() + " context " + Entity.SEPARATOR + siteId + Entity.SEPARATOR + SiteService.MAIN_CONTAINER + ".\n"); // start with an element with our very own (service) name Element element = doc.createElement(DiscussionForumService.class.getName()); element.setAttribute(VERSION_ATTR, ARCHIVE_VERSION); ((Element) stack.peek()).appendChild(element); stack.push(element); if (siteId != null && siteId.trim().length() > 0) { Area dfArea = areaManager.getAreaByContextIdAndTypeId(siteId, typeManager.getDiscussionForumType()); if (dfArea != null) { Element dfElement = doc.createElement(MESSAGEFORUM); //List forums = dfManager.getDiscussionForumsByContextId(siteId); List forums = dfManager.getDiscussionForumsWithTopicsMembershipNoAttachments(siteId); if (forums != null && !forums.isEmpty()) { Iterator forumsIter = forums.iterator(); while (forumsIter.hasNext()) { DiscussionForum forum = (DiscussionForum)forumsIter.next(); if (forum != null) { forumCount++; Element df_data = doc.createElement(DISCUSSION_FORUM); df_data.setAttribute(DISCUSSION_FORUM_TITLE, forum.getTitle()); df_data.setAttribute(DRAFT, forum.getDraft().toString()); df_data.setAttribute(LOCKED, forum.getLocked().toString()); df_data.setAttribute(MODERATED, forum.getModerated().toString()); df_data.setAttribute(SORT_INDEX, forum.getSortIndex().toString()); try { String encoded = new String(base64Encoder.encode(forum.getExtendedDescription().getBytes())); df_data.setAttribute(DISCUSSION_FORUM_DESC, encoded); } catch(Exception e) { //LOG.warn("Encode DF Extended Desc - " + e); df_data.setAttribute(DISCUSSION_FORUM_DESC, ""); } try { String encoded = new String(base64Encoder.encode(forum.getShortDescription().getBytes())); df_data.setAttribute(DISCUSSION_FORUM_SHORT_DESC, encoded); } catch(Exception e) { //LOG.warn("Encode DF Short Desc - " + e); df_data.setAttribute(DISCUSSION_FORUM_SHORT_DESC, ""); } List atts = forumManager.getForumById(true, forum.getId()).getAttachments(); for (int i = 0; i < atts.size(); i++) { Element forum_attachment = doc.createElement(ATTACHMENT); String attachId = ((Attachment)atts.get(i)).getAttachmentId(); forum_attachment.setAttribute(ATTACH_ID, attachId); df_data.appendChild(forum_attachment); } Set forumMembershipItems = forum.getMembershipItemSet(); if (forumMembershipItems != null && forumMembershipItems.size() > 0) { Element forum_permissions = doc.createElement(PERMISSIONS); Iterator membershipIter = forumMembershipItems.iterator(); while (membershipIter.hasNext()) { DBMembershipItem membershipItem = (DBMembershipItem) membershipIter.next(); Element permission = doc.createElement(PERMISSION); permission.setAttribute(PERMISSION_TYPE, membershipItem.getType().toString()); permission.setAttribute(PERMISSION_NAME, membershipItem.getName()); permission.setAttribute(PERMISSION_LEVEL_NAME, membershipItem.getPermissionLevelName()); if (PermissionLevelManager.PERMISSION_LEVEL_NAME_CUSTOM.equals(membershipItem.getPermissionLevelName())){ List customPerms = permissionManager.getCustomPermissions(); if (customPerms != null && customPerms.size() > 0) { Element customPermissions = doc.createElement(CUSTOM_PERMISSIONS); for (int i = 0; i < customPerms.size(); i++) { String name = (String)customPerms.get(i); String hasPermission = permissionManager.getCustomPermissionByName(name, membershipItem.getPermissionLevel()).toString(); customPermissions.setAttribute(name, hasPermission); } permission.appendChild(customPermissions); } } forum_permissions.appendChild(permission); } df_data.appendChild(forum_permissions); } List topicList = dfManager.getTopicsByIdWithMessagesMembershipAndAttachments(forum.getId()); if (topicList != null && topicList.size() > 0) { Iterator topicIter = topicList.iterator(); while (topicIter.hasNext()) { DiscussionTopic topic = (DiscussionTopic) topicIter.next(); Element topic_data = doc.createElement(DISCUSSION_TOPIC); topic_data.setAttribute(TOPIC_TITLE, topic.getTitle()); topic_data.setAttribute(DRAFT, topic.getDraft().toString()); topic_data.setAttribute(LOCKED, topic.getLocked().toString()); topic_data.setAttribute(MODERATED, topic.getModerated().toString()); if (topic.getSortIndex() != null) { topic_data.setAttribute(SORT_INDEX, topic.getSortIndex().toString()); } else { topic_data.setAttribute(SORT_INDEX, ""); } Element topic_properties = doc.createElement(PROPERTIES); Element topic_short_desc = doc.createElement(PROPERTY); try { String encoded = new String(base64Encoder.encode(topic.getShortDescription().getBytes())); topic_short_desc.setAttribute(NAME, TOPIC_SHORT_DESC); topic_short_desc.setAttribute(ENCODE, BASE64); topic_short_desc.setAttribute(VALUE, encoded); } catch(Exception e) { //LOG.warn("Encode Topic Short Desc - " + e); topic_short_desc.setAttribute(NAME, TOPIC_SHORT_DESC); topic_short_desc.setAttribute(ENCODE, BASE64); topic_short_desc.setAttribute(VALUE, ""); } topic_properties.appendChild(topic_short_desc); Element topic_long_desc = doc.createElement(PROPERTY); try { String encoded = new String(base64Encoder.encode(topic.getExtendedDescription().getBytes())); topic_long_desc.setAttribute(NAME, TOPIC_LONG_DESC); topic_long_desc.setAttribute(ENCODE, BASE64); topic_long_desc.setAttribute(VALUE, encoded); } catch(Exception e) { //LOG.warn("Encode Topic Ext Desc - " + e); topic_long_desc.setAttribute(NAME, TOPIC_LONG_DESC); topic_long_desc.setAttribute(ENCODE, BASE64); topic_long_desc.setAttribute(VALUE, ""); } topic_properties.appendChild(topic_long_desc); topic_data.appendChild(topic_properties); // permissions Set topicMembershipItems = topic.getMembershipItemSet(); if (topicMembershipItems != null && topicMembershipItems.size() > 0) { Element topic_permissions = doc.createElement(PERMISSIONS); Iterator topicMembershipIter = topicMembershipItems.iterator(); while (topicMembershipIter.hasNext()) { DBMembershipItem membershipItem = (DBMembershipItem) topicMembershipIter.next(); Element permission = doc.createElement(PERMISSION); permission.setAttribute(PERMISSION_TYPE, membershipItem.getType().toString()); permission.setAttribute(PERMISSION_NAME, membershipItem.getName()); permission.setAttribute(PERMISSION_LEVEL_NAME, membershipItem.getPermissionLevelName()); topic_permissions.appendChild(permission); if (PermissionLevelManager.PERMISSION_LEVEL_NAME_CUSTOM.equals(membershipItem.getPermissionLevelName())){ List customPerms = permissionManager.getCustomPermissions(); if (customPerms != null && customPerms.size() > 0) { Element customPermissions = doc.createElement(CUSTOM_PERMISSIONS); for (int i = 0; i < customPerms.size(); i++) { String name = (String)customPerms.get(i); String hasPermission = permissionManager.getCustomPermissionByName(name, membershipItem.getPermissionLevel()).toString(); customPermissions.setAttribute(name, hasPermission); } permission.appendChild(customPermissions); } } } topic_data.appendChild(topic_permissions); } List topicAtts = forumManager.getTopicByIdWithAttachments(topic.getId()).getAttachments(); for (int j = 0; j < topicAtts.size(); j++) { Element topic_attachment = doc.createElement(ATTACHMENT); String attachId = ((Attachment)topicAtts.get(j)).getAttachmentId(); topic_attachment.setAttribute(ATTACH_ID, attachId); topic_data.appendChild(topic_attachment); } df_data.appendChild(topic_data); } } dfElement.appendChild(df_data); } } } results.append("archiving " + getLabel() + ": (" + forumCount + ") messageforum DF items archived successfully.\n"); ((Element) stack.peek()).appendChild(dfElement); stack.push(dfElement); } else { results.append("archiving " + getLabel() + ": empty messageforum DF archived.\n"); } } stack.pop(); } catch (DOMException e) { LOG.error(e.getMessage(), e); } return results.toString(); } public Entity getEntity(Reference ref) { // TODO Auto-generated method stub return null; } public Collection getEntityAuthzGroups(Reference ref, String userId) { // TODO Auto-generated method stub return null; } public String getEntityDescription(Reference ref) { // TODO Auto-generated method stub return null; } public ResourceProperties getEntityResourceProperties(Reference ref) { // TODO Auto-generated method stub return null; } public String getEntityUrl(Reference ref) { // TODO Auto-generated method stub return null; } public HttpAccess getHttpAccess() { // TODO Auto-generated method stub return null; } public String getLabel() { return "messageforum"; } public String[] myToolIds() { String[] toolIds = { "sakai.messagecenter", "sakai.forums" }; return toolIds; } public void transferCopyEntities(String fromContext, String toContext, List resourceIds) { transferCopyEntitiesRefMigrator(fromContext, toContext, resourceIds); } public Map<String, String> transferCopyEntitiesRefMigrator(String fromContext, String toContext, List resourceIds) { Map<String, String> transversalMap = new HashMap<String, String>(); boolean importOpenCloseDates = ServerConfigurationService.getBoolean("msgcntr.forums.import.openCloseDates", false); try { LOG.debug("transfer copy mc items by transferCopyEntities"); //List fromDfList = dfManager.getDiscussionForumsByContextId(fromContext); List fromDfList = dfManager.getDiscussionForumsWithTopicsMembershipNoAttachments(fromContext); List existingForums = dfManager.getDiscussionForumsByContextId(toContext); int numExistingForums = existingForums.size(); if (fromDfList != null && !fromDfList.isEmpty()) { for (int currForum = 0; currForum < fromDfList.size(); currForum++) { DiscussionForum fromForum = (DiscussionForum)fromDfList.get(currForum); Long fromForumId = fromForum.getId(); DiscussionForum newForum = forumManager.createDiscussionForum(); if(newForum != null){ newForum.setTitle(fromForum.getTitle()); if (fromForum.getShortDescription() != null && fromForum.getShortDescription().length() > 0) newForum.setShortDescription(fromForum.getShortDescription()); if (fromForum.getExtendedDescription() != null && fromForum.getExtendedDescription().length() > 0) newForum.setExtendedDescription(fromForum.getExtendedDescription()); newForum.setDraft(fromForum.getDraft()); newForum.setLocked(fromForum.getLocked()); newForum.setModerated(fromForum.getModerated()); newForum.setPostFirst(fromForum.getPostFirst()); newForum.setAutoMarkThreadsRead(fromForum.getAutoMarkThreadsRead()); if(importOpenCloseDates){ newForum.setOpenDate(fromForum.getOpenDate()); newForum.setCloseDate(fromForum.getCloseDate()); newForum.setAvailability(fromForum.getAvailability()); newForum.setAvailabilityRestricted(fromForum.getAvailabilityRestricted()); } // set the forum order. any existing forums will be first // if the "from" forum has a 0 sort index, there is no sort order Integer fromSortIndex = fromForum.getSortIndex(); if (fromSortIndex != null && fromSortIndex.intValue() > 0) { newForum.setSortIndex(Integer.valueOf(fromForum.getSortIndex().intValue() + numExistingForums)); } // get permissions for "from" site Set membershipItemSet = fromForum.getMembershipItemSet(); List allowedPermNames = this.getSiteRolesAndGroups(toContext); if (membershipItemSet != null && !membershipItemSet.isEmpty() && allowedPermNames != null && !allowedPermNames.isEmpty()) { Iterator membershipIter = membershipItemSet.iterator(); while (membershipIter.hasNext()) { DBMembershipItem oldItem = (DBMembershipItem)membershipIter.next(); if(allowedPermNames.contains(oldItem.getName())) { DBMembershipItem newItem = getMembershipItemCopy(oldItem); if (newItem != null) { permissionManager.saveDBMembershipItem(newItem); newForum.addMembershipItem(newItem); } } } } // get/add the forum's attachments List fromAttach = forumManager.getForumById(true, fromForumId).getAttachments(); if (fromAttach != null && !fromAttach.isEmpty()) { for (int currAttach=0; currAttach < fromAttach.size(); currAttach++) { Attachment thisAttach = (Attachment)fromAttach.get(currAttach); Attachment newAttachment = copyAttachment(thisAttach.getAttachmentId(), toContext); if (newAttachment != null) newForum.addAttachment(newAttachment); } } // get/add the gradebook assignment associated with the forum settings GradebookService gradebookService = (org.sakaiproject.service.gradebook.shared.GradebookService) ComponentManager.get("org.sakaiproject.service.gradebook.GradebookService"); String gradebookUid = null; // if this code is called from a quartz job, like SIS, then getCurrentPlacement() will return null. // so just use the fromContext which gives the site id. if (ToolManager.getCurrentPlacement() != null) gradebookUid = ToolManager.getCurrentPlacement().getContext(); else gradebookUid = fromContext; if (gradebookService.isGradebookDefined(gradebookUid)) { String fromAssignmentTitle = fromForum.getDefaultAssignName(); if (gradebookService.isAssignmentDefined(gradebookUid, fromAssignmentTitle)) { newForum.setDefaultAssignName(fromAssignmentTitle); } } // save the forum, since this is copying over a forum, send "false" for parameter otherwise //it will create a default forum as well Area area = areaManager.getDiscussionArea(toContext, false); newForum.setArea(area); if ("false".equalsIgnoreCase(ServerConfigurationService.getString("import.importAsDraft"))) { forumManager.saveDiscussionForum(newForum, newForum.getDraft().booleanValue()); } else { newForum.setDraft(Boolean.valueOf("true")); forumManager.saveDiscussionForum(newForum, true); } //add the ref's for the old and new forum transversalMap.put("forum/" + fromForumId, "forum/" + newForum.getId()); // get/add the topics List topicList = dfManager.getTopicsByIdWithMessagesMembershipAndAttachments(fromForumId); if (topicList != null && !topicList.isEmpty()) { for (int currTopic = 0; currTopic < topicList.size(); currTopic++) { DiscussionTopic fromTopic = (DiscussionTopic)topicList.get(currTopic); Long fromTopicId = fromTopic.getId(); DiscussionTopic newTopic = forumManager.createDiscussionForumTopic(newForum); newTopic.setTitle(fromTopic.getTitle()); if (fromTopic.getShortDescription() != null && fromTopic.getShortDescription().length() > 0) newTopic.setShortDescription(fromTopic.getShortDescription()); if (fromTopic.getExtendedDescription() != null && fromTopic.getExtendedDescription().length() > 0) newTopic.setExtendedDescription(fromTopic.getExtendedDescription()); newTopic.setLocked(fromTopic.getLocked()); newTopic.setDraft(fromTopic.getDraft()); newTopic.setModerated(fromTopic.getModerated()); newTopic.setPostFirst(fromTopic.getPostFirst()); newTopic.setSortIndex(fromTopic.getSortIndex()); newTopic.setAutoMarkThreadsRead(fromTopic.getAutoMarkThreadsRead()); if(importOpenCloseDates){ newTopic.setOpenDate(fromTopic.getOpenDate()); newTopic.setCloseDate(fromTopic.getCloseDate()); newTopic.setAvailability(fromTopic.getAvailability()); newTopic.setAvailabilityRestricted(fromTopic.getAvailabilityRestricted()); } // Get/set the topic's permissions Set topicMembershipItemSet = fromTopic.getMembershipItemSet(); if (topicMembershipItemSet != null && !topicMembershipItemSet.isEmpty() && allowedPermNames != null && !allowedPermNames.isEmpty()) { Iterator membershipIter = topicMembershipItemSet.iterator(); while (membershipIter.hasNext()) { DBMembershipItem oldItem = (DBMembershipItem)membershipIter.next(); if(allowedPermNames.contains(oldItem.getName())) { DBMembershipItem newItem = getMembershipItemCopy(oldItem); if (newItem != null) { permissionManager.saveDBMembershipItem(newItem); newTopic.addMembershipItem(newItem); } } } } // Add the attachments List fromTopicAttach = forumManager.getTopicByIdWithAttachments(fromTopicId).getAttachments(); if (fromTopicAttach != null && !fromTopicAttach.isEmpty()) { for (int topicAttach=0; topicAttach < fromTopicAttach.size(); topicAttach++) { Attachment thisAttach = (Attachment)fromTopicAttach.get(topicAttach); Attachment newAttachment = copyAttachment(thisAttach.getAttachmentId(), toContext); if (newAttachment != null) newTopic.addAttachment(newAttachment); } } // get/add the gradebook assignment associated with the topic if (gradebookService.isGradebookDefined(gradebookUid)) { String fromAssignmentTitle = fromTopic.getDefaultAssignName(); if (gradebookService.isAssignmentDefined(gradebookUid, fromAssignmentTitle)) { newTopic.setDefaultAssignName(fromAssignmentTitle); } } forumManager.saveDiscussionForumTopic(newTopic, newForum.getDraft().booleanValue()); //add the ref's for the old and new topic transversalMap.put("forum_topic/" + fromTopicId, "forum_topic/" + newTopic.getId()); } } } } } } catch (Exception e) { e.printStackTrace(); LOG.error(e.getMessage(), e); } return transversalMap; } public String merge(String siteId, Element root, String archivePath, String fromSiteId, Map attachmentNames, Map userIdTrans, Set userListAllowImport) { List existingForums = dfManager.getDiscussionForumsByContextId(siteId); int numExistingForums = existingForums.size(); Base64 base64Encoder = new Base64(); StringBuilder results = new StringBuilder(); if (siteId != null && siteId.trim().length() > 0) { try { NodeList allChildrenNodes = root.getChildNodes(); int length = allChildrenNodes.getLength(); for (int i = 0; i < length; i++) { Node siteNode = allChildrenNodes.item(i); if (siteNode.getNodeType() == Node.ELEMENT_NODE) { Element siteElement = (Element) siteNode; if (siteElement.getTagName().equals(MESSAGEFORUM)) { NodeList allForumNodes = siteElement.getChildNodes(); int lengthForum = allForumNodes.getLength(); for (int j = 0; j < lengthForum; j++) { Node child1 = allForumNodes.item(j); if (child1.getNodeType() == Node.ELEMENT_NODE) { Element forumElement = (Element) child1; if (forumElement.getTagName().equals(DISCUSSION_FORUM)) { DiscussionForum dfForum = forumManager.createDiscussionForum(); String forumTitle = forumElement.getAttribute(DISCUSSION_FORUM_TITLE); dfForum.setTitle(forumTitle); String forumDraft = forumElement.getAttribute(DRAFT); if(forumDraft != null && forumDraft.length() >0) dfForum.setDraft(Boolean.valueOf(forumDraft)); String forumLocked = forumElement.getAttribute(LOCKED); if(forumLocked != null && forumLocked.length() >0) dfForum.setLocked(Boolean.valueOf(forumLocked)); String forumModerated = forumElement.getAttribute(MODERATED); if(forumModerated != null && forumModerated.length() >0) { dfForum.setModerated(Boolean.valueOf(forumModerated)); } else { dfForum.setModerated(Boolean.FALSE); } String forumPostFirst = forumElement.getAttribute(POST_FIRST); if(forumPostFirst != null && forumPostFirst.length() >0) { dfForum.setPostFirst(Boolean.valueOf(forumPostFirst)); } else { dfForum.setPostFirst(Boolean.FALSE); } String forumSortIndex = forumElement.getAttribute(SORT_INDEX); if(forumSortIndex != null && forumSortIndex.length() > 0) { try { Integer sortIndex = Integer.valueOf(forumSortIndex); sortIndex = Integer.valueOf(sortIndex.intValue() + numExistingForums); dfForum.setSortIndex(sortIndex); } catch (NumberFormatException nfe) { // do nothing b/c invalid } } String forumDesc = forumElement.getAttribute(DISCUSSION_FORUM_DESC); String trimBody = null; if(forumDesc != null && forumDesc.length() >0) { trimBody = trimToNull(forumDesc); if (trimBody != null && trimBody.length() >0) { byte[] decoded = base64Encoder.decode(trimBody.getBytes()); trimBody = new String(decoded, "UTF-8"); } } if(trimBody != null) { dfForum.setExtendedDescription(trimBody); } String forumShortDesc = forumElement.getAttribute(DISCUSSION_FORUM_SHORT_DESC); String trimSummary = null; if(forumShortDesc != null && forumShortDesc.length() >0) { trimSummary = trimToNull(forumShortDesc); if (trimSummary != null && trimSummary.length() >0) { byte[] decoded = base64Encoder.decode(trimSummary.getBytes()); trimSummary = new String(decoded, "UTF-8"); } } if(trimSummary != null) { dfForum.setShortDescription(trimSummary); } NodeList forumDetailNodes = forumElement.getChildNodes(); boolean hasTopic = false; for(int k=0; k<forumDetailNodes.getLength(); k++) { Node forumChild = forumDetailNodes.item(k); if(forumChild.getNodeType() == Node.ELEMENT_NODE) { Element forumChildElement = (Element) forumChild; if (forumChildElement.getTagName().equals(ATTACHMENT)) { String oldAttachId = forumChildElement.getAttribute(ATTACH_ID); if (oldAttachId != null && oldAttachId.trim().length() > 0) { String oldUrl = oldAttachId; if (oldUrl.startsWith("/content/attachment/")) { String newUrl = (String) attachmentNames.get(oldUrl); if (newUrl != null) { oldAttachId = Validator.escapeQuestionMark(newUrl); } } else if (oldUrl.startsWith("/content/group/" + fromSiteId + "/")) { String newUrl = "/content/group/" + siteId + oldUrl.substring(15 + fromSiteId.length()); oldAttachId = Validator.escapeQuestionMark(newUrl); } Attachment newAttachment = copyAttachment(oldAttachId, siteId); if (newAttachment != null) dfForum.addAttachment(newAttachment); } } // PERMISSIONS else if(forumChildElement.getTagName().equals(PERMISSIONS)) { Set membershipItemSet = getMembershipItemSetFromPermissionElement(forumChildElement, siteId); if (membershipItemSet != null && membershipItemSet.size() > 0) { Iterator membershipIter = membershipItemSet.iterator(); while (membershipIter.hasNext()) { DBMembershipItem oldItem = (DBMembershipItem)membershipIter.next(); DBMembershipItem newItem = getMembershipItemCopy(oldItem); if (newItem != null) { permissionManager.saveDBMembershipItem(newItem); dfForum.addMembershipItem(newItem); } } } } else if(forumChildElement.getTagName().equals(DISCUSSION_TOPIC)) { DiscussionTopic dfTopic = forumManager.createDiscussionForumTopic(dfForum); String topicTitle = forumChildElement.getAttribute(TOPIC_TITLE); dfTopic.setTitle(topicTitle); String topicDraft = forumChildElement.getAttribute(DRAFT); if(topicDraft != null && topicDraft.length() >0) dfTopic.setDraft(Boolean.valueOf(topicDraft)); String topicLocked = forumChildElement.getAttribute(LOCKED); if(topicLocked != null && topicLocked.length() >0) dfTopic.setLocked(Boolean.valueOf(topicLocked)); String topicModerated = forumChildElement.getAttribute(MODERATED); if(topicModerated != null && topicModerated.length() >0) dfTopic.setModerated(Boolean.valueOf(topicModerated)); else dfTopic.setModerated(Boolean.FALSE); String topicPostFirst = forumChildElement.getAttribute(POST_FIRST); if(topicPostFirst != null && topicPostFirst.length() >0) dfTopic.setPostFirst(Boolean.valueOf(topicPostFirst)); else dfTopic.setPostFirst(Boolean.FALSE); String sortIndex = forumChildElement.getAttribute(SORT_INDEX); if (sortIndex != null) { try { Integer sortIndexAsInt = Integer.valueOf(sortIndex); dfTopic.setSortIndex(sortIndexAsInt); } catch (NumberFormatException nfe) { dfTopic.setSortIndex(null); } } NodeList topicPropertiesNodes = forumChildElement.getChildNodes(); for(int m=0; m<topicPropertiesNodes.getLength(); m++) { Node propertiesNode = topicPropertiesNodes.item(m); if(propertiesNode.getNodeType() == Node.ELEMENT_NODE) { Element propertiesElement = (Element)propertiesNode; if(propertiesElement.getTagName().equals(PROPERTIES)) { NodeList propertyList = propertiesElement.getChildNodes(); for(int n=0; n<propertyList.getLength(); n++) { Node propertyNode = propertyList.item(n); if(propertyNode.getNodeType() == Node.ELEMENT_NODE) { Element propertyElement = (Element)propertyNode; if(propertyElement.getTagName().equals(PROPERTY)) { if(TOPIC_SHORT_DESC.equals(propertyElement.getAttribute(NAME))) { if(BASE64.equals(propertyElement.getAttribute(ENCODE))) { String topicDesc = propertyElement.getAttribute(VALUE); String trimDesc = null; if(topicDesc != null && topicDesc.length() >0) { trimDesc = trimToNull(topicDesc); if (trimDesc != null && trimDesc.length() >0) { byte[] decoded = base64Encoder.decode(trimDesc.getBytes()); trimDesc = new String(decoded, "UTF-8"); } } if(trimDesc != null) { dfTopic.setShortDescription(trimDesc); } } else dfTopic.setShortDescription(propertyElement.getAttribute(VALUE)); } if(TOPIC_LONG_DESC.equals(propertyElement.getAttribute(NAME))) { if(BASE64.equals(propertyElement.getAttribute(ENCODE))) { String topicDesc = propertyElement.getAttribute(VALUE); String trimDesc = null; if(topicDesc != null && topicDesc.length() >0) { trimDesc = trimToNull(topicDesc); if (trimDesc != null && trimDesc.length() >0) { byte[] decoded = base64Encoder.decode(trimDesc.getBytes()); trimDesc = new String(decoded, "UTF-8"); } } if(trimDesc != null) { dfTopic.setExtendedDescription(trimDesc); } } else dfTopic.setExtendedDescription(propertyElement.getAttribute(VALUE)); } } } } } else if (propertiesElement.getTagName().equals(ATTACHMENT)) { String oldAttachId = propertiesElement.getAttribute(ATTACH_ID); if (oldAttachId != null && oldAttachId.trim().length() > 0) { String oldUrl = oldAttachId; if (oldUrl.startsWith("/content/attachment/")) { String newUrl = (String) attachmentNames.get(oldUrl); if (newUrl != null) { oldAttachId = Validator.escapeQuestionMark(newUrl); } } else if (oldUrl.startsWith("/content/group/" + fromSiteId + "/")) { String newUrl = "/content/group/" + siteId + oldUrl.substring(15 + fromSiteId.length()); oldAttachId = Validator.escapeQuestionMark(newUrl); } Attachment newAttachment = copyAttachment(oldAttachId, siteId); if (newAttachment != null) dfTopic.addAttachment(newAttachment); } } else if (propertiesElement.getTagName().equals(PERMISSIONS)) { Set membershipItemSet = getMembershipItemSetFromPermissionElement(propertiesElement, siteId); if (membershipItemSet != null && membershipItemSet.size() > 0) { Iterator membershipIter = membershipItemSet.iterator(); while (membershipIter.hasNext()) { DBMembershipItem oldItem = (DBMembershipItem)membershipIter.next(); DBMembershipItem newItem = getMembershipItemCopy(oldItem); if (newItem != null) { permissionManager.saveDBMembershipItem(newItem); dfTopic.addMembershipItem(newItem); } } } } } } if(!hasTopic) { Area area = areaManager.getDiscussionArea(siteId); dfForum.setArea(area); if ("false".equalsIgnoreCase(ServerConfigurationService.getString("import.importAsDraft"))) { forumManager.saveDiscussionForum(dfForum, dfForum.getDraft().booleanValue()); } else { dfForum.setDraft(Boolean.valueOf("true")); forumManager.saveDiscussionForum(dfForum, true); } } hasTopic = true; forumManager.saveDiscussionForumTopic(dfTopic, dfForum.getDraft().booleanValue()); } } } if(!hasTopic) { Area area = areaManager.getDiscussionArea(siteId); dfForum.setArea(area); if ("false".equalsIgnoreCase(ServerConfigurationService.getString("import.importAsDraft"))) { forumManager.saveDiscussionForum(dfForum, dfForum.getDraft().booleanValue()); } else { dfForum.setDraft(Boolean.valueOf("true")); forumManager.saveDiscussionForum(dfForum, true); } } } } } } } } } catch (Exception e) { results.append("merging " + getLabel() + " failed.\n"); e.printStackTrace(); } } return null; } public boolean parseEntityReference(String reference, Reference ref) { if (reference.startsWith(REFERENCE_ROOT)) { // /syllabus/siteid/syllabusid String[] parts = split(reference, Entity.SEPARATOR); String subType = null; String context = null; String id = null; String container = null; if (parts.length > 2) { // the site/context context = parts[2]; // the id if (parts.length > 3) { id = parts[3]; } } ref.set(SERVICE_NAME, subType, id, container, context); return true; } return false; } public boolean willArchiveMerge() { return true; } protected String[] split(String source, String splitter) { // hold the results as we find them Vector rv = new Vector(); int last = 0; int next = 0; do { // find next splitter in source next = source.indexOf(splitter, last); if (next != -1) { // isolate from last thru before next rv.add(source.substring(last, next)); last = next + splitter.length(); } } while (next != -1); if (last < source.length()) { rv.add(source.substring(last, source.length())); } // convert to array return (String[]) rv.toArray(new String[rv.size()]); } // split public MessageForumsForumManager getForumManager() { return forumManager; } public void setForumManager(MessageForumsForumManager forumManager) { this.forumManager = forumManager; } public AreaManager getAreaManager() { return areaManager; } public void setAreaManager(AreaManager areaManager) { this.areaManager = areaManager; } public String trimToNull(String value) { if (value == null) return null; value = value.trim(); if (value.length() == 0) return null; return value; } private Attachment copyAttachment(String attachmentId, String toContext) { try { ContentResource oldAttachment = contentHostingService.getResource(attachmentId); ContentResource attachment = contentHostingService.addAttachmentResource( oldAttachment.getProperties().getProperty( ResourceProperties.PROP_DISPLAY_NAME), toContext, ToolManager.getTool( "sakai.forums").getTitle(), oldAttachment.getContentType(), oldAttachment.getContent(), oldAttachment.getProperties()); Attachment thisDFAttach = dfManager.createDFAttachment( attachment.getId(), attachment.getProperties().getProperty(ResourceProperties.PROP_DISPLAY_NAME)); return thisDFAttach; } catch (IdUnusedException iue) { LOG.error("Error with attachment id: " + attachmentId); LOG.error(iue.getMessage(), iue); } catch (Exception e) { //e.printStackTrace(); LOG.error("Error with attachment id: " + attachmentId); LOG.error(e.getMessage(), e); } return null; } private Set getMembershipItemSetFromPermissionElement(Element permissionsElement, String siteId) { Set membershipItemSet = new HashSet(); List allowedPermNames = getSiteRolesAndGroups(siteId); List allowedPermLevels = permissionManager.getOrderedPermissionLevelNames(); // add the custom level, as well if (allowedPermLevels != null && !allowedPermLevels.contains(PermissionLevelManager.PERMISSION_LEVEL_NAME_CUSTOM)) { allowedPermLevels.add(PermissionLevelManager.PERMISSION_LEVEL_NAME_CUSTOM); } NodeList permissionsNodes = permissionsElement.getChildNodes(); for (int m=0; m < permissionsNodes.getLength(); m++) { Node permissionsNode = permissionsNodes.item(m); if (permissionsNode.getNodeType() == Node.ELEMENT_NODE) { Element permissionElement = (Element)permissionsNode; if(permissionElement.getTagName().equals(PERMISSION)) { try { if (permissionElement.getAttribute(PERMISSION_NAME) != null && permissionElement.getAttribute(PERMISSION_LEVEL_NAME) != null && permissionElement.getAttribute(PERMISSION_TYPE) != null) { String permissionName = permissionElement.getAttribute(PERMISSION_NAME); String permissionLevelName = permissionElement.getAttribute(PERMISSION_LEVEL_NAME); if (allowedPermNames != null && allowedPermLevels != null && allowedPermNames.contains(permissionName) && allowedPermLevels.contains(permissionLevelName)) { Integer permissionType = Integer.valueOf(permissionElement.getAttribute(PERMISSION_TYPE)); DBMembershipItem membershipItem = permissionManager.createDBMembershipItem(permissionName, permissionLevelName, permissionType); if (PermissionLevelManager.PERMISSION_LEVEL_NAME_CUSTOM.equals(membershipItem.getPermissionLevelName())){ NodeList customPermNodes = permissionElement.getChildNodes(); for (int l=0; l < customPermNodes.getLength(); l++) { Node customPermNode = customPermNodes.item(l); if (customPermNode.getNodeType() == Node.ELEMENT_NODE) { Element customPermElement = (Element)customPermNode; if (customPermElement.getTagName().equals(CUSTOM_PERMISSIONS)) { PermissionsMask mask = new PermissionsMask(); List customPermList = permissionManager.getCustomPermissions(); for (int c=0; c < customPermList.size(); c++) { String customPermName = (String) customPermList.get(c); Boolean hasPermission = Boolean.valueOf(customPermElement.getAttribute(customPermName)); mask.put(customPermName, hasPermission); } PermissionLevel level = permissionManager.createPermissionLevel(membershipItem.getPermissionLevelName(), typeManager.getCustomLevelType(), mask); membershipItem.setPermissionLevel(level); } } } } // save DBMembershipItem here to get an id so we can add to the set permissionManager.saveDBMembershipItem(membershipItem); membershipItemSet.add(membershipItem); } } } catch (NumberFormatException nfe) { LOG.error(nfe); } catch (Exception e) { LOG.error(e); } } } } return membershipItemSet; } private List getSiteRolesAndGroups(String contextId) { // get the roles in the site AuthzGroup realm; List rolesAndGroups = new ArrayList(); try { realm = AuthzGroupService.getAuthzGroup("/site/" + contextId); Set roleSet = realm.getRoles(); if (roleSet != null && roleSet.size() > 0) { Iterator roleIter = roleSet.iterator(); while (roleIter.hasNext()) { Role role = (Role) roleIter.next(); if (role != null) { rolesAndGroups.add(role.getId()); } } } // get any groups/sections in site Site currentSite = SiteService.getSite(contextId); Collection groups = currentSite.getGroups(); for (Iterator groupIterator = groups.iterator(); groupIterator.hasNext();) { Group currentGroup = (Group) groupIterator.next(); rolesAndGroups.add(currentGroup.getTitle()); } } catch (GroupNotDefinedException e) { // TODO Auto-generated catch block LOG.error("GroupNotDefinedException retrieving site's roles and groups", e); } catch (Exception e) { LOG.error("Exception retrieving site's roles and groups", e); } return rolesAndGroups; } private DBMembershipItem getMembershipItemCopy(DBMembershipItem itemToCopy) { DBMembershipItem newItem = permissionManager.createDBMembershipItem(itemToCopy.getName(), itemToCopy.getPermissionLevelName(), itemToCopy.getType()); PermissionLevel oldPermLevel = itemToCopy.getPermissionLevel(); if (newItem.getPermissionLevelName().equals(PermissionLevelManager.PERMISSION_LEVEL_NAME_CUSTOM)) { PermissionsMask mask = new PermissionsMask(); List customPermList = permissionManager.getCustomPermissions(); for (int c=0; c < customPermList.size(); c++) { String customPermName = (String) customPermList.get(c); Boolean hasPermission = permissionManager.getCustomPermissionByName(customPermName, oldPermLevel); mask.put(customPermName, hasPermission); } PermissionLevel level = permissionManager.createPermissionLevel(newItem.getPermissionLevelName(), typeManager.getCustomLevelType(), mask); newItem.setPermissionLevel(level); } return newItem; } public MessageForumsMessageManager getMessageManager() { return messageManager; } public void setMessageManager(MessageForumsMessageManager messageManager) { this.messageManager = messageManager; } public MessageForumsTypeManager getTypeManager() { return typeManager; } public void setTypeManager(MessageForumsTypeManager typeManager) { this.typeManager = typeManager; } public DiscussionForumManager getDfManager() { return dfManager; } public void setDfManager(DiscussionForumManager dfManager) { this.dfManager = dfManager; } public void setPermissionManager(PermissionLevelManager permissionManager) { this.permissionManager = permissionManager; } public PermissionLevelManager getPermissionManager() { return permissionManager; } public void transferCopyEntities(String fromContext, String toContext, List ids, boolean cleanup) { transferCopyEntitiesRefMigrator(fromContext, toContext, ids, cleanup); } public Map<String, String> transferCopyEntitiesRefMigrator(String fromContext, String toContext, List ids, boolean cleanup) { Map<String, String> transversalMap = new HashMap<String, String>(); try { if(cleanup == true) { try { List existingForums = dfManager.getDiscussionForumsByContextId(toContext); if (existingForums != null && !existingForums.isEmpty()) { for (int currForum = 0; currForum < existingForums.size(); currForum++) { DiscussionForum fromForum = (DiscussionForum)existingForums.get(currForum); forumManager.deleteDiscussionForum(fromForum); } } } catch(Exception e) { LOG.debug ("Remove Forums from Site Import failed" + e); } } transversalMap.putAll(transferCopyEntitiesRefMigrator(fromContext, toContext, ids)); } catch(Exception e) { LOG.debug ("Forums transferCopyEntities failed" + e); } return transversalMap; } /** * {@inheritDoc} */ public void updateEntityReferences(String toContext, Map<String, String> transversalMap){ if(transversalMap != null && transversalMap.size() > 0){ Set<Entry<String, String>> entrySet = (Set<Entry<String, String>>) transversalMap.entrySet(); List existingForums = dfManager.getDiscussionForumsByContextId(toContext); if (existingForums != null && !existingForums.isEmpty()) { for (int currForum = 0; currForum < existingForums.size(); currForum++) { boolean updateForum = false; DiscussionForum fromForum = (DiscussionForum)existingForums.get(currForum); //check long Desc: String fLongDesc = fromForum.getExtendedDescription(); if(fLongDesc != null){ fLongDesc = replaceAllRefs(fLongDesc, entrySet); if(!fLongDesc.equals(fromForum.getExtendedDescription())){ fromForum.setExtendedDescription(fLongDesc); updateForum = true; } } if(updateForum){ //update forum dfManager.saveForum(fromForum); } List topics = fromForum.getTopics(); if(topics != null && !topics.isEmpty()){ //check topics too: for(int currTopic = 0; currTopic < topics.size(); currTopic++){ boolean updateTopic = false; DiscussionTopic topic = (DiscussionTopic) topics.get(currTopic); //check long Desc: String tLongDesc = topic.getExtendedDescription(); if(tLongDesc != null){ tLongDesc = replaceAllRefs(tLongDesc, entrySet); if(!tLongDesc.equals(topic.getExtendedDescription())){ topic.setExtendedDescription(tLongDesc); updateTopic = true; } } if(updateTopic){ //update forum dfManager.saveTopic(topic); } } } } } } } private String replaceAllRefs(String msgBody, Set<Entry<String, String>> entrySet){ if(msgBody != null){ msgBody = LinkMigrationHelper.migrateAllLinks(entrySet, msgBody); } return msgBody; } }