Permalink
Browse files

Merge remote-tracking branch 'mirror/sakai-2.8.x' into sakai-2.8.x

  • Loading branch information...
2 parents ef3cc2b + 9ab57b9 commit 893531d3919ad29d79c31d81a6b8f1baa9b7f258 @buckett buckett committed Jan 24, 2012
View
8 announcement-api/api/src/java/org/sakaiproject/announcement/api/AnnouncementService.java
@@ -100,6 +100,9 @@
/** retract date property names for announcements */
public static final String RETRACT_DATE = "retractDate";
+ /** modified date property names for announcements */
+ public static final String MOD_DATE = "modDate";
+
/** assignment reference property for announcements */
public static final String ASSIGNMENT_REFERENCE = "assignmentReference";
@@ -151,4 +154,9 @@ public AnnouncementChannelEdit addAnnouncementChannel(String ref) throws IdUsedE
*/
public boolean isMessageViewable(AnnouncementMessage message);
+ /**
+ * clears the message cache for this channel
+ * @param channelRef
+ */
+ public void clearMessagesCache(String channelRef);
}
View
8 announcement-api/api/src/java/org/sakaiproject/announcement/cover/AnnouncementService.java
@@ -35,6 +35,7 @@
*/
public class AnnouncementService
{
+ public static final String MOD_DATE = org.sakaiproject.announcement.api.AnnouncementService.MOD_DATE;
public static final String RELEASE_DATE = org.sakaiproject.announcement.api.AnnouncementService.RELEASE_DATE;
public static final String RETRACT_DATE = org.sakaiproject.announcement.api.AnnouncementService.RETRACT_DATE;
public static final String ASSIGNMENT_REFERENCE = org.sakaiproject.announcement.api.AnnouncementService.ASSIGNMENT_REFERENCE;
@@ -330,4 +331,11 @@ public static boolean isMessageViewable(AnnouncementMessage param0)
return service.isMessageViewable(param0);
}
+
+ public static void clearMessagesCache(String channelRef){
+ org.sakaiproject.announcement.api.AnnouncementService service = getInstance();
+ if (service != null){
+ service.clearMessagesCache(channelRef);
+ }
+ }
}
View
4 announcement-impl/impl/pom.xml
@@ -69,6 +69,10 @@
<version>2.6.2</version>
<type>jar</type>
</dependency>
+ <dependency>
+ <groupId>org.sakaiproject</groupId>
+ <artifactId>sakai-mergedlist-util</artifactId>
+ </dependency>
</dependencies>
<build>
<resources>
View
1 announcement-impl/impl/src/bundle/annc-noti-prefs.properties
@@ -1,4 +1,5 @@
prefs_title = Announcements
+prefs_description=
prefs_opt3 = Send me each notification separately
prefs_opt2 = Send me one email per day summarizing all low priority announcements
prefs_opt1 = Do not send me low priority announcements
View
5 ...cement-impl/impl/src/java/org/sakaiproject/announcement/impl/BaseAnnouncementService.java
@@ -1803,8 +1803,11 @@ public void transferCopyEntities(String fromContext, String toContext, List ids,
{
M_log.debug("transferCopyEntities: End removing Announcement data");
}
-// transversalMap.putAll(transferCopyEntitiesRefMigrator(fromContext, toContext, ids));
+ transferCopyEntitiesRefMigrator(fromContext, toContext, ids);
return null;
}
+ public void clearMessagesCache(String channelRef){
+ m_threadLocalManager.set(channelRef + ".msgs", null);
+ }
}
View
106 ...ment-impl/impl/src/java/org/sakaiproject/announcement/impl/SiteEmailNotificationAnnc.java
@@ -21,11 +21,13 @@
package org.sakaiproject.announcement.impl;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.sakaiproject.announcement.api.AnnouncementChannel;
import org.sakaiproject.announcement.api.AnnouncementMessage;
import org.sakaiproject.announcement.api.AnnouncementMessageEdit;
import org.sakaiproject.announcement.api.AnnouncementMessageHeader;
@@ -45,18 +47,20 @@
import org.sakaiproject.event.api.NotificationService;
import org.sakaiproject.event.cover.EventTrackingService;
import org.sakaiproject.exception.IdUnusedException;
+import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.message.api.MessageHeader;
import org.sakaiproject.site.api.Group;
import org.sakaiproject.site.api.Site;
+import org.sakaiproject.site.api.ToolConfiguration;
import org.sakaiproject.site.cover.SiteService;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.time.cover.TimeService;
-import org.sakaiproject.tool.cover.SessionManager;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserNotDefinedException;
import org.sakaiproject.user.cover.UserDirectoryService;
import org.sakaiproject.util.EmailNotification;
import org.sakaiproject.util.FormattedText;
+import org.sakaiproject.util.MergedList;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.SiteEmailNotification;
@@ -66,18 +70,17 @@
* SiteEmailNotificationAnnc fills the notification message and headers with details from the announcement message that triggered the notification event.
* </p>
*/
-public class SiteEmailNotificationAnnc extends SiteEmailNotification
+public class SiteEmailNotificationAnnc extends SiteEmailNotification
implements ScheduledInvocationCommand
{
private static ResourceLoader rb = new ResourceLoader("siteemaanc");
+ private static final String PORTLET_CONFIG_PARM_MERGED_CHANNELS = "mergedAnnouncementChannels";
/** Our logger. */
private static Log M_log = LogFactory.getLog(SiteEmailNotificationAnnc.class);
private ScheduledInvocationManager scheduledInvocationManager;
-
- private ComponentManager componentManager;
-
+
/**
* Construct.
*/
@@ -103,13 +106,6 @@ public void setScheduledInvocationManager(
}
/**
- * Inject ComponentManager
- */
- public void setComponentManager(ComponentManager componentManager) {
- this.componentManager = componentManager;
- }
-
- /**
* @inheritDoc
*/
protected String getResourceAbility()
@@ -380,24 +376,73 @@ protected String getFromAddress(Event event)
*/
protected void addSpecialRecipients(List users, Reference ref)
{
- // include any users who have AnnouncementService.SECURE_ALL_GROUPS and getResourceAbility() in the context
- String contextRef = SiteService.siteReference(ref.getContext());
+ //SAK-18433 - "if students can see the announcement, they should also be receiving the emails"
+ Site site = null;
+ AnnouncementChannel anncChannel = null;
+ String initMergeList = null;
+
+ try {
+ site = SiteService.getSite(ref.getContext());
+ String channelRef = org.sakaiproject.announcement.cover.AnnouncementService.channelReference(ref.getContext(), ref.getContainer());
+ anncChannel = org.sakaiproject.announcement.cover.AnnouncementService.getAnnouncementChannel(channelRef);
+
+ ToolConfiguration tc=site.getToolForCommonId("sakai.announcements");
+ if (tc!=null){
+ initMergeList = tc.getPlacementConfig().getProperty(PORTLET_CONFIG_PARM_MERGED_CHANNELS);
+ }
+
+ MergedList mergedAnnouncementList = new MergedList();
+ String[] channelArrayFromConfigParameterValue = null;
+
+ //get array of associated channels: similar logic as found in AnnouncementAction.getMessages() for viewing
+ channelArrayFromConfigParameterValue = mergedAnnouncementList.getChannelReferenceArrayFromDelimitedString(anncChannel.getId(), initMergeList);
+ for(int i=0; i<channelArrayFromConfigParameterValue.length;i++)
+ {
+ String mergedSiteId = org.sakaiproject.announcement.cover.AnnouncementService.getChannel(channelArrayFromConfigParameterValue[i]).getContext();
+
+ //skip originating site
+ if(!mergedSiteId.equals(site.getId()))
+ {
+ Site mergedSite = SiteService.getSite(mergedSiteId);
+
+ //similar logic found in SiteEmailNotification.getRecipients()
+ String ability = SiteService.SITE_VISIT;
+ if (!mergedSite.isPublished())
+ {
+ ability = SiteService.SITE_VISIT_UNPUBLISHED;
+ }
- // get the list of users who have SECURE_ALL_GROUPS
- List allGroupUsers = SecurityService.unlockUsers(AnnouncementService.SECURE_ANNC_ALL_GROUPS, contextRef);
+ // get the list of users who can do the right kind of visit
+ List<User> mergedUsers = SecurityService.unlockUsers(ability, mergedSite.getReference());
- // filter down by the permission
- if (getResourceAbility() != null)
+ // get the list of users who have the appropriate access to the resource
+ if (getResourceAbility() != null)
+ {
+ List<User> mergedUsers2 = SecurityService.unlockUsers(getResourceAbility(),mergedSite.getReference());
+
+ //find intersection
+ mergedUsers.retainAll(mergedUsers2);
+ }
+
+ //remove duplicates before combining
+ List<User> temp = new ArrayList(mergedUsers);
+ temp.retainAll(users);
+ mergedUsers.removeAll(temp);
+ users.addAll(mergedUsers);
+ }
+ }
+
+ }
+ catch (NullPointerException e)
{
- List allGroupUsers2 = SecurityService.unlockUsers(getResourceAbility(), contextRef);
- allGroupUsers.retainAll(allGroupUsers2);
+ M_log.error(e.getMessage());
+ }
+ catch (IdUnusedException e) {
+ M_log.error(e.getMessage());
+ }
+ catch (PermissionException e) {
+ M_log.error(e.getMessage());
}
-
- // remove any in the list already
- allGroupUsers.removeAll(users);
-
- // combine
- users.addAll(allGroupUsers);
}
/**
@@ -413,7 +458,7 @@ public void execute(String opaqueContext)
final Reference ref = EntityManager.newReference(opaqueContext);
// needed to access the message
- enableSecurityAdvisor();
+ enableSecurityAdvisorToGetAnnouncement();
final AnnouncementMessage msg = (AnnouncementMessage) ref.getEntity();
final AnnouncementMessageHeader hdr = (AnnouncementMessageHeader) msg.getAnnouncementHeader();
@@ -450,13 +495,16 @@ else if ("n".equals(notification))
* Establish a security advisor to allow the "embedded" azg work to occur
* with no need for additional security permissions.
*/
- protected void enableSecurityAdvisor() {
+ protected void enableSecurityAdvisorToGetAnnouncement() {
// put in a security advisor so we can do our podcast work without need
// of further permissions
SecurityService.pushAdvisor(new SecurityAdvisor() {
public SecurityAdvice isAllowed(String userId, String function,
String reference) {
- return SecurityAdvice.ALLOWED;
+ if (function.equals(AnnouncementService.SECURE_ANNC_READ))
+ return SecurityAdvice.ALLOWED;
+ else
+ return SecurityAdvice.PASS;
}
});
}
View
9 announcement-tool/tool/src/bundle/announcement.properties
@@ -47,8 +47,9 @@ gen.delete2 = Remove
gen.revise = Edit
gen.site = Site
gen.from = Saved By
-gen.date = Date
+gen.date = Modified Date
gen.releasedate = Beginning Date
+gen.mod = Modified Date
gen.retractdate = Ending Date
gen.subject = Subject
gen.attach = attachment
@@ -80,9 +81,9 @@ gen.sortchandesc = Sort by originating site descending
gen.sortbyauth = Sort by author
gen.sortbyauthasc = Sort by author ascending
gen.sortbyauthdesc = Sort by author descending
-gen.sortbydate = Sort by date
-gen.sortbydateasc = Sort by date ascending
-gen.sortbydatedesc = Sort by date descending
+gen.sortbydate = Sort by modified date
+gen.sortbydateasc = Sort by modified date ascending
+gen.sortbydatedesc = Sort by modified date descending
gen.sortbyreleasedate = Sort by release date
gen.sortbyreleasedateasc = Sort by release date ascending
gen.sortbyreleasedatedesc = Sort by release date descending
View
2 announcement-tool/tool/src/bundle/announcement_ca.properties
@@ -241,3 +241,5 @@ widget_date=Data:
widget_time=Hora:
#Sakai 2.7
java.alert.customsize=Només es poden mostrar 20 avisos a la vegada!
+
+announcement.action.msg = Recuperar un anunci bassant-se en la ruta interna empleada pel servici d'anuncis /msg/{siteId}/{channelId}/{announcementId}
View
4 announcement-tool/tool/src/bundle/announcement_es.properties
@@ -239,4 +239,6 @@ reorder.fail.valid.message=\u00A1 Un n\u00FAmero m\u00E1s pequeño que # por fav
revise.notify.ver.dateds_future=Visible y para enviar
revise.notify.ver.dated_future=Visible
revise.notify.ver_summary=La tabla contiene el historial de revisiones. Col 1: fecha revisada; col 2: la preferencia de notificaci\u00F3n usada cuando fue revisada ; col 3: cuando el anuncio se muestra visible si la aparici\u00F3n se retrasa.
-avail.specify.tips=Comenzar a mostrar (opcional) especificando fecha/hora de comienzo y ocultar despu\u00e9s (opcional) especificando fecha/hora de finalizaci\u00f3n.
+avail.specify.tips=Comenzar a mostrar (opcional) especificando fecha/hora de comienzo y ocultar despu\u00e9s (opcional) especificando fecha/hora de finalizaci\u00f3n.
+
+announcement.action.msg = Recuperar un anuncio bas\u00E1ndose en la ruta interna empleada por el servicio de anuncios /msg/{siteId}/{channelId}/{announcementId}
View
2 announcement-tool/tool/src/bundle/announcement_sv.properties
@@ -115,7 +115,7 @@ gen.update=Spara
gen.viewann=Visa meddelande
gen.viewing=Visar
gen.viewing.phrase=Visa {0} - {1} av {2} objekt
-gen.viewing.days.phrase=visar anslag från senaste {0} dagarna
+gen.viewing.days.phrase=visar anslag fr\u00E5n senaste {0} dagarna
gen.visible=Synlig f\u00F6r
group=Grupp
groups=Grupper
View
275 announcement-tool/tool/src/java/org/sakaiproject/announcement/tool/AnnouncementAction.java
@@ -73,6 +73,7 @@
import org.sakaiproject.entity.cover.EntityManager;
import org.sakaiproject.entitybroker.EntityBroker;
import org.sakaiproject.entitybroker.entityprovider.extension.ActionReturn;
+import org.sakaiproject.entitybroker.entityprovider.extension.ActionReturn.Header;
import org.sakaiproject.event.api.NotificationService;
import org.sakaiproject.event.api.SessionState;
import org.sakaiproject.exception.IdInvalidException;
@@ -168,6 +169,8 @@
private static final String SORT_GROUPTITLE = "grouptitle";
private static final String SORT_GROUPDESCRIPTION = "groupdescription";
+
+ private static String SORT_CURRENTORDER = "date";
private static final String CONTEXT_VAR_DISPLAY_OPTIONS = "displayOptions";
@@ -230,7 +233,19 @@
private EntityBroker entityBroker;
- private static int MaxNoOfAnn =0;
+ /*
+ * Returns the current order
+ *
+ */
+ public static String getCurrentOrder() {
+
+ String enableReorder=ServerConfigurationService.getString("sakai.announcement.reorder", "false");
+
+ if (enableReorder.equals("true")){
+ SORT_CURRENTORDER="message_order";
+ }
+ return SORT_CURRENTORDER;
+ }
/**
* Used by callback to convert channel references to channels.
@@ -955,9 +970,17 @@ else if (view.equals(VIEW_MODE_PUBLIC))
{
messages = getMessages(channel, null, true, state, portlet);
}
-
+ //readResourcesPage expects messages to be in session, so put the entire messages list in the session
+ sstate.setAttribute("messages", messages);
+ //readResourcesPage just orders the list correctly, so we can trim a correct list
+ messages = readResourcesPage(sstate, 1, messages.size() + 1);
+ //this will trim the list for us to put into the session
+ messages = trimListToMaxNumberOfAnnouncements(messages, state.getDisplayOptions());
+ //now put it back into the session so we can prepare the page with a correctly sorted and trimmed message list
sstate.setAttribute("messages", messages);
+
messages = prepPage(sstate);
+
sstate.setAttribute(STATE_MESSAGES, messages);
menu_delete = false;
@@ -1525,13 +1548,13 @@ private List getMessages(AnnouncementChannel defaultChannel, Filter filter, bool
{
Collections.reverse(messageList);
}
-
+
// Apply any necessary list truncation.
messageList = getViewableMessages(messageList, ToolManager.getCurrentPlacement().getContext());
- messageList = trimListToMaxNumberOfAnnouncements(messageList, state.getDisplayOptions());
- MaxNoOfAnn=messageList.size();
-
+
+
+
return messageList;
}
@@ -1621,7 +1644,7 @@ private List trimListToMaxNumberOfAnnouncements(List messageList, AnnouncementAc
// We need to go backwards through the list, limiting it to the number
// of announcements that we're allowed to display.
- for (int i = messageList.size() - 1, curAnnouncementCount = 0; i >= 0 && curAnnouncementCount < numberOfAnnouncements; i--)
+ for (int i = 0, curAnnouncementCount = 0; i < messageList.size() && curAnnouncementCount < numberOfAnnouncements; i++)
{
AnnouncementMessage message = (AnnouncementMessage) messageList.get(i);
@@ -1783,23 +1806,53 @@ protected String buildPreviewContext(VelocityPortlet portlet, Context context, R
// Set date
AnnouncementMessageEdit edit = state.getEdit();
+ //set release date
if (tempReleaseDate != null)
{
- context.put("date", tempReleaseDate);
+ context.put("releaseDate", tempReleaseDate);
}
else
{
Time releaseDate = null;
try {
releaseDate = edit.getProperties().getTimeProperty(AnnouncementService.RELEASE_DATE);
- context.put("date", releaseDate);
+ context.put("releaseDate", releaseDate);
}
catch (Exception e) {
// not set so set switch appropriately
- context.put("date", TimeService.newTime());
+ context.put("releaseDate", TimeService.newTime());
}
}
+ //set retract date
+ if (tempRetractDate != null)
+ {
+ context.put("retractDate", tempRetractDate);
+ }
+ else
+ {
+ Time retractDate = null;
+ try {
+ retractDate = edit.getProperties().getTimeProperty(AnnouncementService.RETRACT_DATE);
+ context.put("retractDate", retractDate);
+ }
+ catch (Exception e) {
+ // not set so set switch appropriately
+ context.put("retractDate", TimeService.newTime());
+ }
+ }
+
+ //set modified date
+ Time modDate = null;
+ try {
+ modDate = edit.getProperties().getTimeProperty(AnnouncementService.MOD_DATE);
+ context.put("modDate", modDate);
+ }
+ catch (Exception e) {
+ // not set so set switch appropriately
+ context.put("modDate", TimeService.newTime());
+ }
+
List attachments = state.getAttachments();
context.put("attachments", attachments);
@@ -2211,15 +2264,45 @@ protected String buildShowMetadataContext(VelocityPortlet portlet, Context conte
// get the message object through service
AnnouncementMessage message = channel.getAnnouncementMessage(this.getMessageIDFromReference(messageReference));
- // put release date into context if set. otherwise, put current date
+ // put release date into context if set.
try {
Time releaseDate = message.getProperties().getTimeProperty(AnnouncementService.RELEASE_DATE);
-
- context.put("date", releaseDate);
+ context.put("releaseDate", releaseDate);
}
catch (Exception e) {
- // no release date, put in current time
- context.put("date", TimeService.newTime());
+ // no release date, ignore
+ if (M_log.isDebugEnabled()) {
+ M_log.debug("buildShowMetadataContext releaseDate is empty for message id " + message.getId());
+ }
+ }
+
+ try {
+ Time retractDate = message.getProperties().getTimeProperty(AnnouncementService.RETRACT_DATE);
+ context.put("retractDate", retractDate);
+ }
+ catch (Exception e) {
+ // no retract date, ignore
+ if (M_log.isDebugEnabled()) {
+ M_log.debug("buildShowMetadataContext retractDate is empty for message id " + message.getId());
+ }
+ }
+
+ try {
+ Time modDate = message.getProperties().getTimeProperty(AnnouncementService.MOD_DATE);
+ context.put("modDate", modDate);
+ }
+ catch (Exception e) {
+ // no modified date is available
+ // this can happen as SAK-21071 added the MOD_DATE property
+ // as long as the release date is not set, it is safe to grab the date from the msg header
+ Time releaseDate = null;
+ try {
+ releaseDate = message.getProperties().getTimeProperty(AnnouncementService.RELEASE_DATE);
+ }
+ catch (Exception ee) {
+ // this means there is no release date, so it is safe to get the modDate from the message header
+ context.put("modDate", message.getHeader().getDate());
+ }
}
context.put("message", message);
@@ -2807,9 +2890,50 @@ else if ("n".equals(notification))
header.setSubject(subject);
//set the order of the announcement messages
- MaxNoOfAnn=MaxNoOfAnn+1;
- header.setMessage_order(MaxNoOfAnn);
- //msg.getPropertiesEdit().addProperty("MESSAGE_ORDER", "22");
+ // for example, if this was MESSAGE_ORDER=5 and now becomes MESSAGE_ORDER=12,
+ // we should be modifying the database records for 5-12 and decrementing their message order
+ int oldMessageOrder = header.getMessage_order();
+ List<Message> channelMessages = channel.getMessages(null, true); // ascending order
+ //need to clear the message cache otherwise channel.getMessages stores the old (unsaved) message in cache
+ AnnouncementService.clearMessagesCache(channel.getReference());
+
+
+ // sort the messages by current sort order
+ SortedIterator messSorted = new SortedIterator(channelMessages.iterator(), new AnnouncementComparator(getCurrentOrder(), true));
+
+ int runningCount = 1;
+ while (messSorted.hasNext()) {
+ AnnouncementMessageEdit ame = (AnnouncementMessageEdit) messSorted.next();
+ AnnouncementMessageHeaderEdit amhe = ame.getAnnouncementHeaderEdit();
+ int currentOrder = amhe.getMessage_order();
+
+ // do not attempt to double modify our existing message
+ // skipping will also make sure our runningCount does *not* increment
+ if (ame.getId().equals(msg.getId())) {
+ continue;
+ }
+
+ // only edit the message if we need to modify the order
+ if (currentOrder != runningCount) {
+ amhe.setMessage_order(runningCount);
+ channel.commitMessage_order(ame);
+
+ if (M_log.isDebugEnabled()) {
+ M_log.debug("postOrSaveDraft modifying order: " + ame.getId() + ":"
+ + currentOrder + ":" + runningCount + ":" + oldMessageOrder);
+ }
+ }
+
+ // this max should be correct because we just went through all messages in channel in ascending order
+ runningCount++;
+ }
+
+ // set the message order for our current message to be max
+ header.setMessage_order(runningCount);
+
+ if (M_log.isDebugEnabled()) {
+ M_log.debug("postOrSaveDraft set message order for " + msg.getId() + " to running count " + runningCount);
+ }
// header.setDraft(!post);
// v2.4: Hidden in UI becomes Draft 'behind the scenes'
@@ -2837,15 +2961,17 @@ else if ("n".equals(notification))
releaseDate = TimeService.newTimeLocal(begin_year, begin_month, begin_day, begin_hour, begin_min, 0, 0);
- //SAK-18641: yorkadam, set release date property, also set Date to curr Date, to maintain Date sort
+ // in addition to setting release date property, also set Date to release date so properly sorted
msg.getPropertiesEdit().addProperty(AnnouncementService.RELEASE_DATE, releaseDate.toString());
- header.setDate(TimeService.newTime());
+ // this date is important as the message-api will pick up on it and create a delayed event if in future
+ // the delayed event will then notify() to send the message at the proper time
+ header.setDate(releaseDate);
}
else if (tempReleaseDate != null) // saving from Preview page
{
- //SAK-18641: yorkadam, set release date property, also set Date to curr Date, to maintain Date sort
+ // in addition to setting release date property, also set Date to release date so properly sorted
msg.getPropertiesEdit().addProperty(AnnouncementService.RELEASE_DATE, tempReleaseDate.toString());
- header.setDate(TimeService.newTime());
+ header.setDate(tempReleaseDate);
}
else
{
@@ -2876,13 +3002,16 @@ else if (tempRetractDate != null)
}
else
{
- // they are not using release date so remove
+ // they are not using retract date so remove
if (msg.getProperties().getProperty(AnnouncementService.RETRACT_DATE) != null)
{
msg.getPropertiesEdit().removeProperty(AnnouncementService.RETRACT_DATE);
}
}
+ //modified date
+ msg.getPropertiesEdit().addProperty(AnnouncementService.MOD_DATE, TimeService.newTime().toString());
+
//announceTo
Placement placement = ToolManager.getCurrentPlacement();
//SAK-19516, default motd to pubview so it shows up in rss, motd will fail below try block
@@ -2991,9 +3120,9 @@ else if (announceTo != null && announceTo.equals("groups"))
state.setMessageReference("");
state.setTempAnnounceTo(null);
state.setTempAnnounceToGroups(null);
- state.setCurrentSortedBy(SORT_MESSAGE_ORDER);
+ state.setCurrentSortedBy(getCurrentOrder());
//state.setCurrentSortAsc(Boolean.TRUE.booleanValue());
- sstate.setAttribute(STATE_CURRENT_SORTED_BY, SORT_MESSAGE_ORDER);
+ sstate.setAttribute(STATE_CURRENT_SORTED_BY, getCurrentOrder());
sstate.setAttribute(STATE_CURRENT_SORT_ASC, state.getCurrentSortAsc());
// make sure auto-updates are enabled
@@ -3549,9 +3678,9 @@ public void doCancel(RunData rundata, Context context)
state.setStatus(CANCEL_STATUS);
state.setTempAnnounceTo(null);
state.setTempAnnounceToGroups(null);
- state.setCurrentSortedBy(SORT_MESSAGE_ORDER);
+ state.setCurrentSortedBy(getCurrentOrder());
//state.setCurrentSortAsc(Boolean.TRUE.booleanValue());
- sstate.setAttribute(STATE_CURRENT_SORTED_BY, SORT_MESSAGE_ORDER);
+ sstate.setAttribute(STATE_CURRENT_SORTED_BY, getCurrentOrder());
//sstate.setAttribute(STATE_CURRENT_SORT_ASC, Boolean.FALSE);
sstate.setAttribute(STATE_CURRENT_SORT_ASC, state.getCurrentSortAsc());
@@ -3781,15 +3910,51 @@ public int compare(Object o1, Object o2)
}
else if (m_criteria.equals(SORT_DATE))
{
- // sorted by the discussion message date
- if (((AnnouncementMessage) o1).getAnnouncementHeader().getDate().before(
- ((AnnouncementMessage) o2).getAnnouncementHeader().getDate()))
+
+ Time o1ModDate = null;
+ Time o2ModDate = null;
+
+ try
{
- result = -1;
+ o1ModDate = ((AnnouncementMessage) o1).getProperties().getTimeProperty(AnnouncementService.MOD_DATE);
+ }
+ catch (Exception e)
+ {
+ // release date not set, use the date in header
+ // NOTE: this is an edge use case for courses with pre-existing announcements that do not yet have MOD_DATE
+ o1ModDate = ((AnnouncementMessage) o1).getHeader().getDate();
+ }
+
+ try
+ {
+ o2ModDate = ((AnnouncementMessage) o2).getProperties().getTimeProperty(AnnouncementService.MOD_DATE);
+ }
+ catch (Exception e)
+ {
+ // release date not set, use the date in the header
+ // NOTE: this is an edge use case for courses with pre-existing announcements that do not yet have MOD_DATE
+ o2ModDate = ((AnnouncementMessage) o2).getHeader().getDate();
+ }
+
+ if (o1ModDate != null && o2ModDate != null)
+ {
+ // sorted by the discussion message date
+ if (o1ModDate.before(o2ModDate))
+ {
+ result = -1;
+ }
+ else
+ {
+ result = 1;
+ }
+ }
+ else if (o1ModDate == null)
+ {
+ return 1;
}
else
{
- result = 1;
+ return -1;
}
}
else if (m_criteria.equals(SORT_MESSAGE_ORDER))
@@ -4522,7 +4687,15 @@ public void doReorderUpdate(RunData rundata, Context context)
String[] messageReferences2 = rundata.getParameters().getStrings("selectedMembers2");
if (messageReferences2 != null)
{
+
+
+ try {
+ //grab all messages before the order changes:
+ List<Message> allMessages = AnnouncementService.getChannel(state.getChannelId()).getMessages(null, true);
+ //store the updated message ids so we know which ones didn't get updated
+ List<String> updatedMessageIds = new ArrayList<String>();
Vector v2 = new Vector();
+ int j= allMessages.size();
for (int i = 0; i < messageReferences2.length; i++)
{
// get the message object through service
@@ -4536,9 +4709,9 @@ public void doReorderUpdate(RunData rundata, Context context)
.getMessageIDFromReference(messageReferences2[i]));
AnnouncementMessageEdit msg =(AnnouncementMessageEdit)message2;
AnnouncementMessageHeaderEdit header2 = msg.getAnnouncementHeaderEdit();
- header2.setMessage_order(i+1);
+ header2.setMessage_order(j--);
channel2.commitMessage_order(msg);
-
+ updatedMessageIds.add(msg.getId());
//v2.addElement(message2);
}
catch (IdUnusedException e)
@@ -4552,6 +4725,37 @@ public void doReorderUpdate(RunData rundata, Context context)
addAlert(sstate, rb.getString("java.alert.youdelann") + messageReferences2[i]);
}
}
+ if(allMessages.size() > messageReferences2.length){
+ //need to update the message order of the remaining messages (only sorts the top 10)
+
+ //order by message order:
+ SortedIterator messagesSorted = new SortedIterator(allMessages.iterator(), new AnnouncementComparator(SORT_MESSAGE_ORDER, true));
+ //start at last message and increment up
+ int messageOrder = 1;
+ while(messagesSorted.hasNext()){
+ Message message = (Message) messagesSorted.next();
+ if(!updatedMessageIds.contains(message.getId())){
+ //since this list is ordered, we can assign the message order in order:
+ AnnouncementChannel channel2 = AnnouncementService.getAnnouncementChannel(this
+ .getChannelIdFromReference(message.getReference()));
+ // get the message object through service
+ AnnouncementMessage message2 = channel2.getAnnouncementMessage(this
+ .getMessageIDFromReference(message.getReference()));
+ AnnouncementMessageEdit msg =(AnnouncementMessageEdit)message2;
+ AnnouncementMessageHeaderEdit header2 = msg.getAnnouncementHeaderEdit();
+ header2.setMessage_order(messageOrder);
+ channel2.commitMessage_order(msg);
+ messageOrder++;
+ }
+ }
+ }
+ } catch (PermissionException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ } catch (IdUnusedException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
}
}
@@ -4751,8 +4955,7 @@ protected List readResourcesPage(SessionState state, int first, int last)
if ((sortedBy == null) || sortedBy.equals(""))
{
- //sortedBy = "message order";
- sortedBy="message_order";
+ sortedBy= getCurrentOrder();
asc = false;
}
SortedIterator rvSorted = new SortedIterator(rv.iterator(), new AnnouncementComparator(sortedBy, asc));
View
3 ...cement-tool/tool/src/java/org/sakaiproject/announcement/tool/AnnouncementActionState.java
@@ -43,6 +43,7 @@
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.util.ParameterParser;
import org.sakaiproject.util.ResourceLoader;
+import org.sakaiproject.component.cover.ServerConfigurationService;
/**
* <p>
@@ -626,7 +627,7 @@ protected void init()
private String m_currentSortedBy = "message_order";
// the current sort sequence: ture - acscending/false - descending
- private boolean m_currentSortAsc = true;
+ private boolean m_currentSortAsc = false;
// ********* for sorting *********
View
29 announcement-tool/tool/src/webapp/vm/announcement/chef_announcements-metadata.vm
@@ -49,9 +49,34 @@
<th>$tlang.getString("gen.from")</th>
<td>$validator.escapeHtml($message.Header.From.DisplayName)</td>
</tr>
+
<tr>
- <th>$tlang.getString("gen.date")</th>
- <td>$message.Header.Date.toStringLocalFull()</td>
+ <th>$tlang.getString("gen.mod")</th>
+ <td>
+ #if ($modDate)
+ $modDate.toStringLocalFull()
+ #else
+ $message.Header.Date.toStringLocalFull()
+ #end
+ </td>
+ </tr>
+
+ <tr>
+ <th>$tlang.getString("gen.releasedate")</th>
+ #if($releaseDate)
+ <td>$releaseDate.toStringLocalFull()</td>
+ #else
+ <td></td>
+ #end
+ </tr>
+
+ <tr>
+ <th>$tlang.getString("gen.retractdate")</th>
+ #if($retractDate)
+ <td>$retractDate.toStringLocalFull()</td>
+ #else
+ <td></td>
+ #end
</tr>
#if ($!range)
View
8 announcement-tool/tool/src/webapp/vm/announcement/chef_announcements.vm
@@ -616,8 +616,12 @@
<td headers="author">
$validator.escapeHtml($ann_item.Header.From.DisplayName)
</td>
- <td headers="date">
- $ann_item.Header.Date.toStringLocalFull()
+ <td headers="date">
+ #if (!$ann_item_props.isEmpty() && $ann_item_props.getProperty("modDate"))
+ $ann_item_props.getTimeProperty("modDate").toStringLocalFull()
+ #else
+ $ann_item.Header.Date.toStringLocalFull()
+ #end
</td>
#if ($EnableItemCheckBoxes)
#if ($SiteColumnFlag > 0)

0 comments on commit 893531d

Please sign in to comment.