Merged V2.0 to HEAD

5456: (From WCM_DEPLOY)

There were many pure conflicts on license headers, one conflict due to CR-LF and
some other smaller issues to resolve:
-----------------------------------------
Resolved (line endings not cr-lf):
   root\projects\repository\config\alfresco\public-services-context.xml

Reverted:
   root\projects\web-client\source\web\images\icons\ajax_anim.gif

Reverted or Resolved (License text conflicts):
   svn revert root\projects\jndi-client\source\java\org\alfresco\jndi\JndiTest.java
   svn resolved root\projects\jndi-client\source\java\org\alfresco\jndi\AVMFileDirContext.java
   svn revert root\projects\jndi-client\source\java\org\alfresco\jndi\AVMBulkLoader.java
   svn revert root\projects\jndi-client\source\java\org\alfresco\filter\CacheControlFilter.java
   svn revert root\projects\jndi-client\source\java\org\alfresco\filter\CacheControlFilterInfoBean.java
   svn revert -R root\projects\catalina-virtual\source\java\org\alfresco\mbeans
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\context\AVMStandardContext.java
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\loader\AVMWebappClassLoader.java
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\loader\AVMWebappLoader.java
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\host\AVMResourceBinding.java
   svn resolved root\projects\catalina-virtual\source\java\org\alfresco\catalina\host\AVMHostConfig.java
      - why the change in method naming convention?
   svn resolved root\projects\catalina-virtual\source\java\org\alfresco\catalina\host\AVMHost.java
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\host\DefaultAVMResourceBinding.java
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\valve\AVMUrlValveTest.java
   svn resolved root\projects\catalina-virtual\source\java\org\alfresco\catalina\valve\AVMUrlValve.java
   svn revert root\projects\catalina-virtual\source\java\org\alfresco\catalina\host\AVMHostMatch.java

Modified:
   root\projects\web-client\source\java\org\alfresco\web\ui\wcm\component\UIDeployWebsite.java (Kevin to check line 330)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5484 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-04-12 01:41:14 +00:00
parent 1e854c1087
commit 69694b7ac0
86 changed files with 5283 additions and 1422 deletions

View File

@@ -112,6 +112,7 @@ public final class Utils
*
* @param string the String to convert
*/
//XXXarielb perhaps use org.springframework.web.util.HtmlUtils instead?
public static String encode(String string)
{
if (string == null)

View File

@@ -57,7 +57,7 @@ public class MultiValueConverter implements Converter
StringTokenizer tokenizer = new StringTokenizer(value, ",");
while (tokenizer.hasMoreTokens())
{
items.add(tokenizer.nextToken());
items.add(tokenizer.nextToken().trim());
}
return items;

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.web.ui.common.tag;
import javax.faces.convert.Converter;
import javax.faces.webapp.ConverterTag;
import javax.servlet.jsp.JspException;
import org.alfresco.web.ui.common.converter.MultiValueConverter;
/**
* Allows the MultiValueConverter component to be used on JSP pages
*
* @author gavinc
*/
public class MultiValueConverterTag extends ConverterTag
{
/**
* Default Constructor
*/
public MultiValueConverterTag()
{
setConverterId(MultiValueConverter.CONVERTER_ID);
}
/**
* @see javax.faces.webapp.ConverterTag#createConverter()
*/
protected Converter createConverter() throws JspException
{
return (MultiValueConverter)super.createConverter();
}
}

View File

@@ -0,0 +1,494 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.web.ui.wcm.component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.transaction.UserTransaction;
import org.alfresco.model.WCMAppModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.wcm.AVMConstants;
import org.alfresco.web.bean.wcm.DeploymentMonitor;
import org.alfresco.web.ui.common.Utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* JSF component that allows a user to select which servers to deploy a
* website to and provides monitoring of the deployments selected
*
* @author gavinc
*/
public class UIDeployWebsite extends UIInput
{
protected NodeRef webProjectRef;
protected Integer snapshotVersion = -1;
protected Boolean monitorDeployment;
protected List<String> monitorIds;
private static Log logger = LogFactory.getLog(UIDeployWebsite.class);
// ------------------------------------------------------------------------------
// Component implementation
/**
* Default constructor
*/
public UIDeployWebsite()
{
setRendererType(null);
}
@Override
public String getFamily()
{
return "org.alfresco.faces.DeployWebsite";
}
@Override
public void decode(FacesContext context)
{
super.decode(context);
Map valuesMap = context.getExternalContext().getRequestParameterValuesMap();
String[] values = (String[])valuesMap.get(this.getClientId(context));
setSubmittedValue(values);
}
@SuppressWarnings("unchecked")
@Override
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.webProjectRef = (NodeRef)values[1];
this.monitorDeployment = (Boolean)values[2];
this.monitorIds = (List<String>)values[3];
this.snapshotVersion = (Integer)values[4];
}
@Override
public Object saveState(FacesContext context)
{
Object values[] = new Object[5];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.webProjectRef;
values[2] = this.monitorDeployment;
values[3] = this.monitorIds;
values[4] = this.snapshotVersion;
return values;
}
@SuppressWarnings("unchecked")
@Override
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
tx.begin();
NodeRef webProject = this.getWebsite();
if (webProject == null)
{
throw new IllegalArgumentException("The web project must be specified.");
}
// add some before the panels
out.write("\n<div style='padding-top:4px;'></div>\n");
if (this.getMonitor())
{
// get the ids of the deployment monitor objects
List<String> deployMonitorIds = this.getMonitorIds();
if (logger.isDebugEnabled())
{
logger.debug("Monitoring deployment of: " + deployMonitorIds);
}
// TODO: Add support for 'sniffing' the session for deployment monitors
// this could be useful when the monitor ids are not known
// render the supporting script required for monitoring
renderScript(context, out, deployMonitorIds);
// render each server being deployed with an animated icon, the subsequent
// AJAX callback will update the progress.
for (String id : deployMonitorIds)
{
// try and find the monitor object in the session, if it's not there
// it has probably completed and been removed
DeploymentMonitor monitor = (DeploymentMonitor)context.getExternalContext().
getSessionMap().get(id);
if (monitor != null)
{
if (logger.isDebugEnabled())
logger.debug("Found deployment monitor: " + monitor);
renderServer(context, out, monitor.getTargetServer(), false, true, id);
}
}
}
else
{
// get a list of the servers that have been successfully deployed to
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
int deployingVersion = this.getSnapshotVersion();
List<String> serversAlreadyDeployed = new ArrayList<String>();
List<ChildAssociationRef> deployReportRefs = nodeService.getChildAssocs(
webProjectRef, WCMAppModel.ASSOC_DEPLOYMENTREPORT, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref : deployReportRefs)
{
NodeRef report = ref.getChildRef();
Boolean success = (Boolean)nodeService.getProperty(report,
WCMAppModel.PROP_DEPLOYSUCCESSFUL);
int deployedVersion = (Integer)nodeService.getProperty(report,
WCMAppModel.PROP_DEPLOYVERSION);
if (success.booleanValue() && (deployingVersion == deployedVersion))
{
serversAlreadyDeployed.add((String)nodeService.getProperty(report,
WCMAppModel.PROP_DEPLOYSERVER));
}
}
// get the list of servers for the user to select from
List<String> servers = (List<String>)nodeService.getProperty(webProject,
WCMAppModel.PROP_DEPLOYTO);
if (logger.isDebugEnabled())
logger.debug("Servers available: " + servers + ", servers already deployed: " +
serversAlreadyDeployed);
// render the list of servers, only pre-select those that have not been
// deployed successfully
for (String server : servers)
{
boolean preSelected = !serversAlreadyDeployed.contains(server);
renderServer(context, out, server, preSelected, false, null);
}
}
tx.commit();
}
catch (Throwable err)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
throw new RuntimeException(err);
}
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @return The NodeRef representation of the web project to show the deployment reports for
*/
public NodeRef getWebsite()
{
ValueBinding vb = getValueBinding("website");
if (vb != null)
{
this.webProjectRef = (NodeRef)vb.getValue(getFacesContext());
}
return this.webProjectRef;
}
/**
* @param value The NodeRef representation of the web project to show the deployment reports for
*/
public void setWebsite(NodeRef value)
{
this.webProjectRef = value;
}
/**
* @return true if the component should monitor a deployment
*/
public boolean getMonitor()
{
ValueBinding vb = getValueBinding("monitor");
if (vb != null)
{
this.monitorDeployment = (Boolean)vb.getValue(getFacesContext());
}
if (this.monitorDeployment == null)
{
this.monitorDeployment = Boolean.FALSE;
}
return this.monitorDeployment.booleanValue();
}
/**
* @param monitor Determines whether a deployment should be monitored
*/
public void setMonitor(boolean monitor)
{
this.monitorDeployment = new Boolean(monitor);
}
/**
* @return The list of deployment monitor IDs
*/
@SuppressWarnings("unchecked")
public List<String> getMonitorIds()
{
ValueBinding vb = getValueBinding("monitorIds");
if (vb != null)
{
this.monitorIds = (List<String>)vb.getValue(getFacesContext());
}
return this.monitorIds;
}
/**
* @param monitorIds List of monitor IDs to look for
*/
public void setMonitorIds(List<String> monitorIds)
{
this.monitorIds = monitorIds;
}
/**
* @return The version of the snapshot being deployed
*/
public int getSnapshotVersion()
{
ValueBinding vb = getValueBinding("snapshotVersion");
if (vb != null)
{
this.snapshotVersion = (Integer)vb.getValue(getFacesContext());
}
return this.snapshotVersion;
}
/**
* @param snapshotVersion The version of the snapshot being deployed
*/
public void setSnapshotVersion(int snapshotVersion)
{
this.snapshotVersion = snapshotVersion;
}
// ------------------------------------------------------------------------------
// Helpers
private void renderScript(FacesContext context, ResponseWriter out,
List<String> monitorIds) throws IOException
{
// // render supporting Yahoo scripts
// Utils.writeYahooScripts(context, out, null);
// create comma separated list of deplyment ids
StringBuilder ids = new StringBuilder();
for (int x = 0; x < monitorIds.size(); x++)
{
if (x > 0)
{
ids.append(",");
}
String id = monitorIds.get(x);
ids.append(id);
}
// determine the polling frequency value
int pollFreq = AVMConstants.getRemoteDeploymentPollingFrequency() * 1000;
// render the script to handle the progress monitoring
out.write("<script type='text/javascript'>\n");
out.write("Alfresco.DeploymentMonitor = function(ids) {\n");
out.write(" this.ids = ids;\n");
out.write(" this.url = '");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/ajax/invoke/DeploymentProgressBean.getStatus?ids=' + this.ids;\n");
out.write(" this.failedMsg = '");
out.write(Application.getMessage(context, "deploy_failed"));
out.write("';\n");
out.write(" this.successMsg = '");
out.write(Application.getMessage(context, "deploy_successful"));
out.write("';\n");
out.write("}\n");
out.write("Alfresco.DeploymentMonitor.prototype = {\n");
out.write(" ids: null,\n");
out.write(" url: null,\n");
out.write(" failedMsg: null,\n");
out.write(" successMsg: null,\n");
out.write(" retrieveDeploymentStatus: function() {\n");
out.write(" YAHOO.util.Connect.asyncRequest('GET', this.url,\n");
out.write(" {\n");
out.write(" success: this.processResults,\n");
out.write(" failure: this.handleError,\n");
out.write(" scope: this\n");
out.write(" },\n");
out.write(" null);\n");
out.write(" },\n");
out.write(" processResults: function(ajaxResponse) {\n");
out.write(" var xml = ajaxResponse.responseXML.documentElement;\n");
out.write(" var statuses = xml.getElementsByTagName('target-server');\n");
out.write(" var noInProgress = statuses.length;\n");
out.write(" if (noInProgress > 0) {\n");
out.write(" for (var x = 0; x < noInProgress; x++) {\n");
out.write(" var target = statuses[x];\n");
out.write(" var id = target.getAttribute('id');\n");
out.write(" var finished = target.getAttribute('finished');\n");
out.write(" if (finished == 'true') {\n");
out.write(" var successful = target.getAttribute('successful');\n");
out.write(" var icon = document.getElementById(id + '_icon');\n");
out.write(" if (icon != null) {\n");
out.write(" var image = (successful == 'true') ? 'successful' : 'failed';\n");
out.write(" icon.src = '/alfresco/images/icons/deploy_' + image + '.gif';\n");
out.write(" }\n");
out.write(" var text = document.getElementById(id + '_text');\n");
out.write(" if (text != null) {\n");
out.write(" var msg = (successful == 'true') ? this.successMsg : this.failedMsg;\n");
out.write(" text.innerHTML = msg;\n");
out.write(" }\n");
out.write(" }\n");
out.write(" }\n");
out.write(" // there are still outstanding deployments, refresh in a few seconds\n");
out.write(" setTimeout('Alfresco.monitor.retrieveDeploymentStatus()', ");
out.write(Integer.toString(pollFreq));
out.write(");\n");
out.write(" }\n");
out.write(" },\n");
out.write(" handleError: function(ajaxResponse) {\n");
out.write(" handleErrorYahoo(ajaxResponse.status + ' ' + ajaxResponse.statusText);\n");
out.write(" }\n");
out.write("}\n");
out.write("Alfresco.initDeploymentMonitor = function() {\n");
out.write(" Alfresco.monitor = new Alfresco.DeploymentMonitor('");
out.write(ids.toString());
out.write("');\n");
out.write(" Alfresco.monitor.retrieveDeploymentStatus();\n");
out.write("}\n");
out.write("Alfresco.monitor = null;\n");
out.write("window.onload = Alfresco.initDeploymentMonitor;\n");
out.write("</script>\n");
}
private void renderServer(FacesContext context, ResponseWriter out, String server,
boolean selected, boolean monitoring, String monitorId) throws IOException
{
String contextPath = context.getExternalContext().getRequestContextPath();
out.write("<table cellspacing='0' cellpadding='0' border='0' width='100%'>");
out.write("<tr><td width='10'><img src='");
out.write(contextPath);
out.write("/images/parts/deploy_panel_start.gif' /></td>");
out.write("<td style='background-image: url(");
out.write(contextPath);
out.write("/images/parts/deploy_panel_bg.gif); background-repeat: repeat-x;'>");
if (monitoring)
{
out.write("<div class='deployPanelStatusIcon'>");
out.write("<img id='");
out.write(monitorId);
out.write("_icon' src='");
out.write(contextPath);
out.write("/images/icons/ajax_anim.gif' />");
}
else
{
out.write("<div class='deployPanelCheckbox'>");
out.write("<input type='checkbox' name='");
out.write(this.getClientId(context));
out.write("' value='");
out.write(server);
out.write("'");
if (selected)
{
out.write("checked='checked'");
}
out.write(" />");
}
out.write("</div></td><td width='2'><img src='");
out.write(contextPath);
out.write("/images/parts/deploy_panel_separator.gif' /></td>");
out.write("<td style='background-image: url(");
out.write(contextPath);
out.write("/images/parts/deploy_panel_bg.gif); background-repeat: repeat-x;'>");
out.write("<div class='deployPanelIcon'>");
out.write("<img src='");
out.write(contextPath);
out.write("/images/icons/deploy_server_large.gif' /></div></td>");
out.write("<td style='background-image: url(");
out.write(contextPath);
out.write("/images/parts/deploy_panel_bg.gif); background-repeat: repeat-x; width: 100%;'>");
out.write("<div class='deployPanelServerName'>");
out.write(server);
out.write("</div>");
if (monitoring)
{
out.write("<div class='deployPanelServerStatus' id='");
out.write(monitorId);
out.write("_text'>");
out.write(Application.getMessage(context, "deploying"));
out.write("</div>");
}
else if (selected == false)
{
out.write("<div class='deployPanelServerStatus'><img src='");
out.write(contextPath);
out.write("/images/icons/info_icon.gif' style='vertical-align: -5px;' />&nbsp;");
out.write(Application.getMessage(context, "deploy_server_not_selected"));
out.write("</div>");
}
out.write("</td><td width='10'><img src='");
out.write(contextPath);
out.write("/images/parts/deploy_panel_end.gif' /></td></tr></table>");
// add some padding under each panel
out.write("\n<div style='padding-top:8px;'></div>\n");
}
}

View File

@@ -0,0 +1,311 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.web.ui.wcm.component;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.PanelGenerator;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
/**
* JSF component that displays the latest deployment reports for a web project.
*
* @author gavinc
*/
public class UIDeploymentReports extends SelfRenderingComponent
{
protected NodeRef webProjectRef;
private static Log logger = LogFactory.getLog(UIDeploymentReports.class);
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.DeploymentReports";
}
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.webProjectRef = (NodeRef)values[1];
}
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.webProjectRef;
return values;
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
@SuppressWarnings("unchecked")
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
tx.begin();
NodeRef webProject = getValue();
if (webProject == null)
{
throw new IllegalArgumentException("The web project must be specified.");
}
if (logger.isDebugEnabled())
logger.debug("Rendering deployment reports for: " + webProject.toString());
// render the supporting JavaScript
renderScript(context, out);
// iterate through each deployment report
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
ContentService contentService = Repository.getServiceRegistry(context).getContentService();
List<ChildAssociationRef> deployReportRefs = nodeService.getChildAssocs(
this.webProjectRef, WCMAppModel.ASSOC_DEPLOYMENTREPORT, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref : deployReportRefs)
{
// render each report
renderReport(context, out, ref.getChildRef(), nodeService, contentService);
}
// add some padding after the panels
out.write("\n<div style='padding-top:8px;'></div>\n");
tx.commit();
}
catch (Throwable err)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
throw new RuntimeException(err);
}
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @return The NodeRef representation of the web project to show the deployment reports for
*/
public NodeRef getValue()
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.webProjectRef = (NodeRef)vb.getValue(getFacesContext());
}
return this.webProjectRef;
}
/**
* @param value The NodeRef representation of the web project to show the deployment reports for
*/
public void setValue(NodeRef value)
{
this.webProjectRef = value;
}
// ------------------------------------------------------------------------------
// Helpers
private void renderScript(FacesContext context, ResponseWriter out)
throws IOException
{
out.write("<script type='text/javascript'>\n");
out.write("function toggleDeploymentDetails(icon, server) {\n");
out.write(" var currentState = icon.className;\n");
out.write(" var detailsDiv = document.getElementById(server + '-deployment-details');\n");
out.write(" if (currentState == 'collapsed') {\n");
out.write(" icon.src = '");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/images/icons/expanded.gif';\n");
out.write(" icon.className = 'expanded';\n");
out.write(" if (detailsDiv != null) { detailsDiv.style.display = 'block'; }\n");
out.write(" } else {\n");
out.write(" icon.src = '");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/images/icons/collapsed.gif';\n");
out.write(" icon.className = 'collapsed';\n");
out.write(" if (detailsDiv != null) { detailsDiv.style.display = 'none'; }\n");
out.write(" }\n}</script>\n");
}
private void renderReport(FacesContext context, ResponseWriter out, NodeRef deploymentReport,
NodeService nodeService, ContentService contentService)
throws IOException
{
if (logger.isDebugEnabled())
logger.debug("Rendering report: " + deploymentReport);
// add some padding before the panel
out.write("\n<div style='padding-top:8px;'></div>\n");
// start the surrounding panel
PanelGenerator.generatePanelStart(out,
context.getExternalContext().getRequestContextPath(), "innerwhite", "white");
// extract the information we need to display
String server = (String)nodeService.getProperty(deploymentReport, WCMAppModel.PROP_DEPLOYSERVER);
Integer snapshot = (Integer)nodeService.getProperty(deploymentReport, WCMAppModel.PROP_DEPLOYVERSION);
String creator = (String)nodeService.getProperty(deploymentReport, ContentModel.PROP_CREATOR);
Date startTime = (Date)nodeService.getProperty(deploymentReport, WCMAppModel.PROP_DEPLOYSTARTTIME);
Date endTime = (Date)nodeService.getProperty(deploymentReport, WCMAppModel.PROP_DEPLOYENDTIME);
String started = Utils.getDateTimeFormat(context).format(startTime);
String finished = Utils.getDateTimeFormat(context).format(endTime);
Boolean success = (Boolean)nodeService.getProperty(deploymentReport, WCMAppModel.PROP_DEPLOYSUCCESSFUL);
String failReason = (String)nodeService.getProperty(deploymentReport, WCMAppModel.PROP_DEPLOYFAILEDREASON);
String content = "";
ContentReader reader = contentService.getReader(deploymentReport, ContentModel.PROP_CONTENT);
if (reader != null)
{
content = reader.getContentString();
if (content != null)
{
content = StringUtils.replace(content, "\r\n", "<br/>");
}
else
{
content = "";
}
}
out.write("<table cellspacing='0' cellpadding='2' border='0' width='100%'>");
out.write("<tr><td width='40' valign='top'><img src='");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/images/icons/deploy_server_large.gif' /></td><td>");
out.write("<div class='mainHeading'>");
out.write(server);
out.write("</div><div style='margin-top: 3px;'><img src='");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/images/icons/deploy_");
if (success.booleanValue())
{
out.write("successful");
}
else
{
out.write("failed");
}
out.write(".gif' style='vertical-align: -4px;' />&nbsp;&nbsp;");
if (success.booleanValue())
{
out.write(Application.getMessage(context, "deploy_successful"));
}
else
{
out.write(Application.getMessage(context, "deploy_failed"));
}
out.write("</div>");
out.write("<div style='margin-top: 6px;'>");
out.write(Application.getMessage(context, "snapshot"));
out.write(":&nbsp;");
out.write(snapshot.toString());
out.write("</div>");
out.write("<div style='margin-top: 3px;'>");
out.write(Application.getMessage(context, "deploy_started"));
out.write(":&nbsp;");
out.write(started);
out.write("</div>");
out.write("<div style='margin-top: 3px;'>");
out.write(Application.getMessage(context, "deploy_finished"));
out.write(":&nbsp;");
out.write(finished);
out.write("</div>");
out.write("<div style='margin-top: 3px;'>");
out.write(Application.getMessage(context, "deployed_by"));
out.write(":&nbsp;");
out.write(creator);
out.write("</div>");
if (success.booleanValue() == false && failReason != null && failReason.length() > 0)
{
out.write("<div style='margin-top: 3px;'>");
out.write(Application.getMessage(context, "reason"));
out.write(":&nbsp;");
out.write(failReason);
out.write("</div>");
}
if (content.length() > 0)
{
out.write("<div style='margin-top: 6px;'><img src='");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/images/icons/collapsed.gif' style='vertical-align: -1px; cursor: pointer;' class='collapsed' onclick=\"toggleDeploymentDetails(this, '");
out.write(server.replace(':', '_'));
out.write("');\" />&nbsp;");
out.write(Application.getMessage(context, "details"));
out.write("</div>\n");
out.write("<div id='");
out.write(server.replace(':', '_'));
out.write("-deployment-details' style='display: none; border: 1px dotted #eee; margin-left: 14px; margin-top: 4px; padding:3px;'>");
out.write(content);
out.write("</div>");
}
out.write("\n<div style='padding-top:6px;'></div>\n");
out.write("</td></tr></table>");
// finish the surrounding panel
PanelGenerator.generatePanelEnd(out,
context.getExternalContext().getRequestContextPath(), "innerwhite");
}
}

View File

@@ -26,6 +26,7 @@ package org.alfresco.web.ui.wcm.component;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
@@ -40,10 +41,16 @@ import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.transaction.UserTransaction;
import org.alfresco.model.WCMAppModel;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.VersionDescriptor;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.wcm.AVMConstants;
import org.alfresco.web.ui.common.ComponentConstants;
import org.alfresco.web.ui.common.ConstantMethodBinding;
import org.alfresco.web.ui.common.Utils;
@@ -61,6 +68,7 @@ public class UISandboxSnapshots extends SelfRenderingComponent
{
private static final String ACT_SNAPSHOT_PREVIEW = "snapshot_preview";
private static final String ACT_SNAPSHOT_REVERT = "snapshot_revert";
private static final String ACT_SNAPSHOT_DEPLOY = "snapshot_deploy";
private static final String REQUEST_SNAPVERSION = "_snapVer";
@@ -72,14 +80,14 @@ public class UISandboxSnapshots extends SelfRenderingComponent
public static final String FILTER_DATE_WEEK = "week";
public static final String FILTER_DATE_MONTH = "month";
private static final String COMPONENT_ACTIONS = "org.alfresco.faces.Actions";
private static final String MSG_LABEL = "name";
private static final String MSG_DESCRIPTION = "description";
private static final String MSG_DATE = "date";
private static final String MSG_USERNAME = "username";
private static final String MSG_VERSION = "version";
private static final String MSG_STATUS = "status";
private static final String MSG_ACTIONS = "actions";
private static final String MSG_LIVE = "live";
/** sandbox to show snapshots for */
private String value;
@@ -87,6 +95,9 @@ public class UISandboxSnapshots extends SelfRenderingComponent
/** date filter to use when listing snapshots */
private String dateFilter;
/** The snapshot version deployed and the state of that deployment */
private int deployAttemptVersion = -1;
private String deployStatus;
// ------------------------------------------------------------------------------
// Component implementation
@@ -174,6 +185,8 @@ public class UISandboxSnapshots extends SelfRenderingComponent
out.write("</th><th>");
out.write(bundle.getString(MSG_VERSION));
out.write("</th><th>");
out.write(bundle.getString(MSG_STATUS));
out.write("</th><th>");
out.write(bundle.getString(MSG_ACTIONS));
out.write("</th></tr>");
@@ -211,6 +224,10 @@ public class UISandboxSnapshots extends SelfRenderingComponent
}
versions = avmService.getStoreVersions(sandbox, fromDate, toDate);
}
// determine the deployment status for the website
determineDeploymentStatus(context, sandbox);
Map requestMap = context.getExternalContext().getRequestMap();
for (int i=versions.size() - 1; i >= 0; i--) // reverse order
{
@@ -219,6 +236,8 @@ public class UISandboxSnapshots extends SelfRenderingComponent
// only display snapshots with a valid tag - others are system generated snapshots
if (item.getTag() != null && item.getVersionID() != 0)
{
int version = item.getVersionID();
out.write("<tr><td>");
out.write(item.getTag());
out.write("</td><td>");
@@ -228,20 +247,45 @@ public class UISandboxSnapshots extends SelfRenderingComponent
out.write("</td><td>");
out.write(item.getCreator());
out.write("</td><td>");
out.write(Integer.toString(item.getVersionID()));
out.write(Integer.toString(version));
out.write("</td><td>");
if (version == this.deployAttemptVersion && this.deployStatus != null)
{
out.write(this.deployStatus);
}
else
{
out.write("&nbsp;");
}
out.write("</td><td><nobr>");
// actions for the item
// create actions for the item
// revert action
UIActionLink action = findAction(ACT_SNAPSHOT_REVERT, sandbox);
if (action == null)
{
Map<String, String> params = new HashMap<String, String>(2, 1.0f);
params.put("sandbox", sandbox);
params.put("version", "#{" + REQUEST_SNAPVERSION + "}");
action = createAction(context, sandbox, ACT_SNAPSHOT_REVERT, null,
action = createAction(context, sandbox, ACT_SNAPSHOT_REVERT, "/images/icons/revert.gif",
"#{AVMBrowseBean.revertSnapshot}", null, null, params);
}
requestMap.put(REQUEST_SNAPVERSION, Integer.toString(item.getVersionID()));
Utils.encodeRecursive(context, action);
out.write("&nbsp;&nbsp;");
// deploy action
action = findAction(ACT_SNAPSHOT_DEPLOY, sandbox);
if (action == null)
{
Map<String, String> params = new HashMap<String, String>(2, 1.0f);
params.put("version", "#{" + REQUEST_SNAPVERSION + "}");
action = createAction(context, sandbox, ACT_SNAPSHOT_DEPLOY, "/images/icons/deploy.gif",
"#{DialogManager.setupParameters}", "dialog:deploySnapshot", null, params);
}
Utils.encodeRecursive(context, action);
requestMap.remove(REQUEST_SNAPVERSION);
//out.write("&nbsp;");
@@ -419,6 +463,91 @@ public class UISandboxSnapshots extends SelfRenderingComponent
return control;
}
private void determineDeploymentStatus(FacesContext context, String sandbox)
{
// work out what status to show against which snapshot
NodeRef webProjectRef = AVMConstants.getWebProjectNodeFromStore(sandbox);
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
List<String> selectedServers = (List<String>)nodeService.getProperty(webProjectRef,
WCMAppModel.PROP_SELECTEDDEPLOYTO);
Integer ver = (Integer)nodeService.getProperty(webProjectRef,
WCMAppModel.PROP_SELECTEDDEPLOYVERSION);
if (ver != null)
{
this.deployAttemptVersion = ver.intValue();
}
if (selectedServers != null && selectedServers.size() > 0)
{
// if the 'selecteddeployto' property is set a deployment has been attempted
List<ChildAssociationRef> deployReportRefs = nodeService.getChildAssocs(
webProjectRef, WCMAppModel.ASSOC_DEPLOYMENTREPORT, RegexQNamePattern.MATCH_ALL);
List<String> deployedServers = new ArrayList<String>();
boolean oneOrMoreFailed = false;
boolean allFailed = true;
for (ChildAssociationRef ref : deployReportRefs)
{
NodeRef report = ref.getChildRef();
// get the name of the server and the deploy outcome
String serverName = (String)nodeService.getProperty(report,
WCMAppModel.PROP_DEPLOYSERVER);
Boolean successful = (Boolean)nodeService.getProperty(report,
WCMAppModel.PROP_DEPLOYSUCCESSFUL);
deployedServers.add(serverName);
if (successful != null)
{
if (successful.booleanValue())
{
allFailed = false;
}
else
{
oneOrMoreFailed = true;
}
}
}
// now we have a list of servers that were deployed see if all
// the selected servers have a report, if not it means a deployment
// is in progress. If all servers reports are present then
// determine the status by the outcomes of from all the reports.
boolean allPresent = true;
for (String selectedServer : selectedServers)
{
if (deployedServers.contains(selectedServer) == false)
{
allPresent = false;
break;
}
}
if (allPresent)
{
// get the right status string
if (allFailed)
{
this.deployStatus = Application.getMessage(context, "deploy_status_failed");
}
else if (oneOrMoreFailed)
{
this.deployStatus = Application.getMessage(context, "deploy_status_partial");
}
else
{
this.deployStatus = Application.getMessage(context, "deploy_status_live");
}
}
else
{
this.deployStatus = Application.getMessage(context, "deploy_status_in_progress");
}
}
}
private AVMService getAVMService(FacesContext fc)
{
return (AVMService)FacesContextUtils.getRequiredWebApplicationContext(fc).getBean("AVMService");

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.web.ui.wcm.tag;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* Tag class that allows the DeployWebsite component to be used on a JSP page.
*
* @author gavinc
*/
public class DeployWebsiteTag extends BaseComponentTag
{
private String value;
private String website;
private String monitor;
private String monitorIds;
private String snapshotVersion;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.DeployWebsite";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "value", this.value);
setStringProperty(component, "website", this.website);
setBooleanProperty(component, "monitor", this.monitor);
setStringProperty(component, "monitorIds", this.monitorIds);
setIntProperty(component, "snapshotVersion", this.snapshotVersion);
}
/**
* @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release()
*/
public void release()
{
super.release();
this.value = null;
this.website = null;
this.monitor = null;
this.monitorIds = null;
this.snapshotVersion = null;
}
/**
* @param value the value (the list of servers to deploy to)
*/
public void setValue(String value)
{
this.value = value;
}
/**
* @param monitor Flag to indicate whether to select servers or show deployment progress
*/
public void setMonitor(String monitor)
{
this.monitor = monitor;
}
/**
* @param monitorIds List of deployment monitor IDs to look for
*/
public void setMonitorIds(String monitorIds)
{
this.monitorIds = monitorIds;
}
/**
* @param website NodeRef of the web project being deployed
*/
public void setWebsite(String website)
{
this.website = website;
}
/**
* @param snapshotVersion The version of the snapshot to deploy to
*/
public void setSnapshotVersion(String snapshotVersion)
{
this.snapshotVersion = snapshotVersion;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.web.ui.wcm.tag;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* Tag class that allows the DeploymentReports component to be used on a JSP page.
*
* @author gavinc
*/
public class DeploymentReportsTag extends BaseComponentTag
{
private String value;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.DeploymentReports";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "value", this.value);
}
/**
* @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release()
*/
public void release()
{
super.release();
this.value = null;
}
/**
* Set the value (NodeRef of the web project)
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
}