Index: C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/java/org/apache/maven/continuum/web/tool/RssFormatterTool.java
===================================================================
--- C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/java/org/apache/maven/continuum/web/tool/RssFormatterTool.java (revision 0)
+++ C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/java/org/apache/maven/continuum/web/tool/RssFormatterTool.java (revision 0)
@@ -0,0 +1,134 @@
+package org.apache.maven.continuum.web.tool;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.
+ */
+
+import org.apache.maven.continuum.project.ContinuumProjectState;
+import java.util.Date;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+/**
+ * @author John Didion
+ * @version $Id: $
+ */
+public class RssFormatterTool {
+ private static final String formatString = "E, dd MMM yyyy HH:mm:ss z";
+ private static final DateFormat format;
+
+ static {
+ format = new SimpleDateFormat(formatString);
+ }
+
+ // TODO: Add i18n
+ public String formatProjectState( int state )
+ {
+ if ( state == ContinuumProjectState.NEW )
+ {
+ return "New";
+ }
+ else if ( state == ContinuumProjectState.OK )
+ {
+ return "Ok";
+ }
+ else if ( state == ContinuumProjectState.FAILED )
+ {
+ return "Failed";
+ }
+ else if ( state == ContinuumProjectState.ERROR )
+ {
+ return "Error";
+ }
+ else if ( state == ContinuumProjectState.BUILDING )
+ {
+ return "Building";
+ }
+ else
+ {
+ return "Unknown project state '" + state + "'";
+ }
+ }
+
+ public String formatTrigger( int trigger )
+ {
+ if ( trigger == ContinuumProjectState.TRIGGER_UNKNOWN )
+ {
+ // TODO: fix this
+ return "Schedule";
+ }
+ else if ( trigger == ContinuumProjectState.TRIGGER_FORCED )
+ {
+ return "Forced";
+ }
+ else
+ {
+ return "Unknown build trigger: '" + trigger + "'";
+ }
+ }
+
+ public String formatTimestamp( long timestamp )
+ {
+ return format.format( new Date( timestamp ) );
+ }
+
+ public String formatInterval( long start, long end )
+ {
+ long diff = end - start;
+
+ long interval = diff / 1000L;
+
+ long hours = interval / 3600L;
+
+ interval -= hours * 3600;
+
+ long minutes = interval / 60;
+
+ interval -= minutes * 60;
+
+ long seconds = interval;
+
+ if ( hours > 0 )
+ {
+ return Long.toString( hours ) + "h " + Long.toString( minutes ) + "m " + Long.toString( seconds ) + "s";
+ }
+
+ if ( minutes > 0 )
+ {
+ return Long.toString( minutes ) + "m " + Long.toString( seconds ) + "s";
+ }
+
+ return Long.toString( seconds ) + "s";
+ }
+
+ public String formatStateImage(int state) {
+ String icon = null;
+
+ if ( state == ContinuumProjectState.OK )
+ {
+ icon = "icon_success_sml.gif";
+ }
+ else if ( state == ContinuumProjectState.FAILED )
+ {
+ icon = "icon_warning_sml.gif";
+ }
+ else if ( state == ContinuumProjectState.ERROR )
+ {
+ icon = "icon_error_sml.gif";
+ }
+
+ return icon;
+ }
+}
\ No newline at end of file
Index: C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/java/org/apache/maven/continuum/web/tool/XmlLinkTool.java
===================================================================
--- C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/java/org/apache/maven/continuum/web/tool/XmlLinkTool.java (revision 0)
+++ C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/java/org/apache/maven/continuum/web/tool/XmlLinkTool.java (revision 0)
@@ -0,0 +1,115 @@
+package org.apache.maven.continuum.web.tool;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.
+ */
+
+import org.codehaus.plexus.summit.pull.tools.TemplateLink;
+
+/**
+ * @author John Didion
+ * @version $Id: $
+ */
+public class XmlLinkTool extends TemplateLink {
+ private String image;
+
+ public XmlLinkTool setImage(String image) {
+ this.image = image;
+ return this;
+ }
+
+ public String toString() {
+ String s = toStringImpl();
+ refresh();
+ return s;
+ }
+
+ public String getURI() {
+ return toStringImpl();
+ }
+
+ /* (non-Javadoc)
+ * @see org.codehaus.plexus.summit.util.UriBuilder#refresh()
+ */
+ public void refresh() {
+ super.refresh();
+ this.image = null;
+ }
+
+ private String toStringImpl() {
+ StringBuffer output = new StringBuffer();
+ if ( !isRelative() )
+ {
+ output.append( data.getServerScheme() );
+ output.append( "://" );
+ output.append( data.getServerName() );
+ if ( ( data.getServerScheme().equals( HTTP ) &&
+ data.getServerPort() != 80 ) ||
+ ( data.getServerScheme().equals( HTTPS ) &&
+ data.getServerPort() != 443 ) )
+ {
+ output.append( ':' );
+ output.append( data.getServerPort() );
+ }
+ }
+
+ output.append( data.getContextPath() );
+
+ if (null != this.image) {
+ output.append("/images/").append(this.image);
+ } else {
+ output.append( data.getScriptName() );
+
+ if ( this.hasPathInfo() )
+ {
+ output.append( '/' );
+ renderPathInfo( this.pathInfo, output );
+ }
+ if ( this.hasQueryData() )
+ {
+ output.append( '?' );
+ renderQueryString( this.queryData, output );
+ }
+ }
+
+ // There seems to be a bug in Apache JServ 1.0 where the
+ // session id is not appended to the end of the url when a
+ // cookie has not been set.
+ String url = null;
+ if ( this.res != null && isEncodeUrl() )
+ {
+ if ( this.redirect )
+ {
+ url = res.encodeRedirectURL( output.toString() );
+ }
+ else
+ {
+ url = res.encodeURL( output.toString() );
+ }
+ }
+ else
+ {
+ url = output.toString();
+ }
+ return escape(url);
+ }
+
+ private String escape(String s) {
+ if (null == s) {
+ return null;
+ }
+ return s.replaceAll("&", "&");
+ }
+}
\ No newline at end of file
Index: C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/META-INF/plexus/components.xml
===================================================================
--- C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/META-INF/plexus/components.xml (revision 379571)
+++ C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/META-INF/plexus/components.xml (working copy)
@@ -96,6 +96,11 @@
global
+ rssFormatter
+ rssFormatterTool
+ global
+
+
trigger
org.codehaus.plexus.formica.web.ContentGenerator
continuum-trigger
@@ -121,11 +126,22 @@
org.apache.maven.continuum.web.tool.StringTool
global
+
+ xmlLink
+ xmlLinkTool
+ request
+
+ xmlLinkTool
+ org.apache.maven.continuum.web.tool.XmlLinkTool
+ per-lookup
+
+
+
datetool
org.apache.maven.continuum.web.tool.DateTool
@@ -139,6 +155,12 @@
+ rssFormatterTool
+ org.apache.maven.continuum.web.tool.RssFormatterTool
+
+
+
+
org.apache.maven.continuum.web.tool.FormDataTool
org.apache.maven.continuum.web.tool.FormDataTool
@@ -207,6 +229,24 @@
+
+ RSS
+
+
+ project
+ getProject(#id)
+
+
+ builds
+ getBuildResultsForProject(#id)
+
+
+
+
Index: C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/layouts/RSS.vm
===================================================================
--- C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/layouts/RSS.vm (revision 0)
+++ C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/layouts/RSS.vm (revision 0)
@@ -0,0 +1,2 @@
+$data.response.setContentType("text/xml")
+$screenViewContent
\ No newline at end of file
Index: C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/screens/RSS.vm
===================================================================
--- C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/screens/RSS.vm (revision 0)
+++ C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/screens/RSS.vm (revision 0)
@@ -0,0 +1,87 @@
+### TODO: is it possible to specify the ttl element using schedule information?
+#set($channelTitle="${project.name} Builds")
+#set($channelLink=$xmlLink.setPage('ProjectBuilds.vm').addPathInfo('view', "ProjectBuilds").addPathInfo('id', $project.id).toString())
+
+
+ ${channelTitle}
+ ${channelLink}
+ Continuum build server results for ${project.name}.
+ Continuum
+ ${i18n.defaultLanguage}
+#if(!$builds.isEmpty())
+#set($last=$builds.get(0))
+ ${rssFormatter.formatTimestamp($last.endTime)}
+ ${rssFormatter.formatTimestamp($last.endTime)}
+#end
+### TODO: it would be cool to support this, though I'm not exactly sure where
+### the cloud config would reside. One possibility is to make continuum itself
+### a cloud server, adding the register procedure to the XML api. Then we could
+### add a RssCloudNotifier, and here we could just loop through a project's
+### notifiers to see if one of them is a RssCloudNotifier, and, if so, use its
+### config to fill in the attributes.
+###if()
+##
+###end
+#set($imageFile=$rssFormatter.formatStateImage($project.state))
+#if($imageFile)
+
+ ${xmlLink.setImage($imageFile)}
+ ${channelTitle}
+ ${channelLink}
+
+#end
+
+ ${project.name}
+ $!{project.description}
+ ${project.groupId}
+ ${project.version}
+ ${project.executorId}
+ $!{project.url}
+ ${project.state}
+ ${rssFormatter.formatProjectState($project.state)}
+ #if($imageFile)${xmlLink.setImage($imageFile)}#end
+ ${project.buildNumber}
+
+#foreach($build in $builds)
+#set($imageFile=$rssFormatter.formatStateImage($build.state))
+ -
+ ${rssFormatter.formatTimestamp($build.startTime)} ($rssFormatter.formatProjectState($build.state))
+ ${xmlLink.setPage('ProjectBuild.vm').addQueryData('view','ProjectBuild').addQueryData('buildId',$build.id).addQueryData('id',$project.id)}
+ Results for build started at ${rssFormatter.formatTimestamp($build.startTime)}.
+ ${rssFormatter.formatTimestamp($build.endTime)}
+
+ #if($build.state == 2)${build.buildNumber}#end
+ ${rssFormatter.formatTimestamp($build.startTime)}
+ ${rssFormatter.formatTimestamp($build.endTime)}
+ ${rssFormatter.formatInterval($build.startTime,$build.endTime)}
+ ${build.state}
+ ${rssFormatter.formatProjectState($build.state)}
+ #if($imageFile)${xmlLink.setImage($imageFile)}#end
+ ${build.trigger}
+ ${rssFormatter.formatTrigger($build.trigger)}
+ #if($build.error)#end
+
+### TODO: The following does not work because the scm result is not detached
+### when the build result is attached. There are two possible solutions:
+### 1. write a pull tool that can be used to detach objects (least invasive)
+### 2. modify modello to add fetch-depth=0 attributes to the appropriate fields (cleanest)
+##
+###foreach($changeSet in $build.scmResult.changes)
+##
+## ${changeSet.author}
+## ${changeSet.comment}
+## ${rssFormatter.formatTimestamp($changeSet.date)}
+###foreach($change in $changeSet.files)
+##
+## ${change.name}
+## ${change.revision}
+##
+###end
+##
+###end
+##
+
+
+#end
+
+
\ No newline at end of file
Index: C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/screens/Summary.vm
===================================================================
--- C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/screens/Summary.vm (revision 379571)
+++ C:/dev/maven-continuum/continuum-1.0.2/continuum-web/src/main/resources/templates/screens/Summary.vm (working copy)
@@ -103,6 +103,12 @@
Working Copy |
#end
+ #if ( $item.state == 1 || $item.state == 2 || $item.state == 3 || $item.state == 4 || $item.state == 6 )
+ RSS Feed |
+ #else
+ RSS Feed |
+ #end
+
#if ( $continuum.security.isAuthorized( $c1user, "deleteProject" ) )
#if ( $item.state == 1 || $item.state == 2 || $item.state == 3 || $item.state == 4 )
Delete |