diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-events-query.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-events-query.post.json.ftl
new file mode 100644
index 0000000000..ab6b289ccd
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-events-query.post.json.ftl
@@ -0,0 +1,6 @@
+<#-- List Channels -->
+<#import "publishing.lib.ftl" as publishLib />
+{
+ "data":
+ <@publishLib.eventsJSON events=data />
+}
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-queue.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-queue.post.desc.xml
index 75591cb40e..17cc3376c4 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-queue.post.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing-queue.post.desc.xml
@@ -25,7 +25,7 @@
{
"channelName": string,
"comment": string,
- "schedule":
+ "scheduledTime":
{
"dateTime": string,
"format": string,
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing.lib.ftl
index 8d0e64aa7b..9ed996f173 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing.lib.ftl
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/publishing.lib.ftl
@@ -1,3 +1,62 @@
+<#-- Renders a List of Publishing Events -->
+<#macro eventsJSON events>
+<#escape x as jsonUtils.encodeJSONString(x)>
+[
+ <#if events??>
+ <#list events as event>
+ <@eventJSON event=event />
+ <#if event_has_next>,#if>
+ #list>
+ #if>
+]
+#escape>
+#macro>
+
+
+<#-- Renders a Publishing Event. -->
+<#macro eventJSON event>
+{
+ "id": "${event.id}",
+ "url": "${event.url}",
+ "status": "${event.status}",
+ <#if event.comment?? >"comment": "${event.comment}",#if>
+ <#if event.scheduledTime?? >
+ "scheduledTime":
+ <@calendarJSON calendar=event.scheduledTime />,
+ #if>
+ "creator": "${event.creator}",
+ "createdTime":
+ <@dateJSON date=event.createdTime/>,
+ "publishNodes":
+ <@publishNodesJSON nodes=event.publishNodes/>,
+ "unpublishNodes":
+ <@publishNodesJSON nodes=event.unpublishNodes/>,
+ "channel":
+ <@channelJSON channel=event.channel/>
+}
+#macro>
+
+<#-- Renders a List of Nodes to be published/unpublished. -->
+<#macro publishNodesJSON nodes>
+[
+ <#if nodes??>
+ <#list nodes as node>
+ <@publishNodeJSON node=node/>
+ <#if node_has_next>,#if>
+ #list>
+ #if>
+]
+#macro>
+
+<#-- Renders a Published/Unpublished Node. -->
+<#macro publishNodeJSON node>
+{
+ <#if node.name?? >"name": "${node.name}",#if>
+ <#if node.version?? >"version": "${node.version}",#if>
+ "nodeRef": "${node.nodeRef}"
+}
+#macro>
+
<#-- Renders a List of Channel.s -->
<#macro channelsJSON channels>
<#escape x as jsonUtils.encodeJSONString(x)>
@@ -55,3 +114,20 @@
[]
#if>
#macro>
+
+<#-- Renders a date. -->
+<#macro dateJSON date>
+{
+ "dateTime": "${date.dateTime}",
+ "format": "${date.format}"
+}
+#macro>
+
+<#-- Renders a calendar. -->
+<#macro calendarJSON calendar>
+{
+ "dateTime": "${calendar.dateTime}",
+ "format": "${calendar.format}",
+ "timeZone": "${calendar.timeZone}"
+}
+#macro>
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index 80e788a2a4..0bcddaafd8 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -1114,6 +1114,16 @@
class="org.alfresco.repo.web.scripts.publishing.PublishingQueuePost"
parent="webscript">
+
+
+
+
+
+
+
+
@@ -1449,4 +1459,4 @@
parent="abstractCalendarWebScript">
-
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/web/scripts/WebScriptUtil.java b/source/java/org/alfresco/repo/web/scripts/WebScriptUtil.java
new file mode 100644
index 0000000000..45a7ac7c0d
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/WebScriptUtil.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.web.scripts;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.util.ISO8601DateFormat;
+import org.json.JSONObject;
+import org.springframework.extensions.surf.util.Content;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * @author Nick Smith
+ * @since 4.0
+ *
+ */
+public class WebScriptUtil
+{
+ // General Keys
+ public static final String DATA_KEY = "data";
+
+ // NodeRef Keys
+ public static final String STORE_PROTOCOL = "store_protocol";
+ public static final String STORE_ID = "store_id";
+ public static final String NODE_ID = "node_id";
+
+ //Date/Calendar Keys
+ public static final String DATE_TIME= "dateTime";
+ public static final String FORMAT= "format";
+ public static final String TIME_ZONE= "timeZone";
+ public static final String ISO8601 = "ISO8601";
+
+ public static String getContent(WebScriptRequest request) throws IOException
+ {
+ Content content = request.getContent();
+ return content.getContent();
+ }
+
+ public static Map buildCalendarModel(Calendar calendar)
+ {
+ Map model = buildDateModel(calendar.getTime());
+ model.put(TIME_ZONE, calendar.getTimeZone().getID());
+ return model;
+ }
+
+ public static Map buildDateModel(Date dateTime)
+ {
+ String dateStr = ISO8601DateFormat.format(dateTime);
+ Map model = new HashMap();
+ model.put(DATE_TIME, dateStr);
+ model.put(FORMAT, ISO8601);
+ return model;
+ }
+
+ public static Calendar getCalendar(JSONObject json) throws ParseException
+ {
+ Date date = getDate(json);
+ if(date == null)
+ {
+ return null;
+ }
+ Calendar calendar = Calendar.getInstance();
+ String timeZone = json.optString(TIME_ZONE);
+ if(timeZone != null)
+ {
+ TimeZone zone = TimeZone.getTimeZone(timeZone);
+ calendar.setTimeZone(zone);
+ }
+ calendar.setTime(date);
+ return calendar;
+ }
+
+ public static Date getDate(JSONObject json) throws ParseException
+ {
+ if(json == null)
+ {
+ return null;
+ }
+ String dateTime = json.optString(DATE_TIME);
+ if(dateTime == null)
+ {
+ return null;
+ }
+ String format = json.optString(FORMAT);
+ if(format!= null && ISO8601.equals(format) == false)
+ {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+ return dateFormat.parse(dateTime);
+ }
+ return ISO8601DateFormat.parse(dateTime);
+ }
+
+
+ public static Map createBaseModel(Map result)
+ {
+ Map model = new HashMap();
+ model.put(DATA_KEY, result);
+ return model;
+ }
+
+ public static Map createBaseModel(List