- Added Edit and Delete actions for AVM files and Delete action for AVM folders
   - Available on the Modified Items list for a user and also in the website sandbox browse screens
   - Edit is working using the inline editors for plain text and HTML files - XML form content editing to be integrated shortly!
   - Edit for non-inline editable files is working (i.e. download file), but no "Update" action available at present for saving updates
   - Delete will delete files/folders structures from the current sandbox, deleted files in a layer are shown in My Modified Files (see below)
 - User sandbox My Modified Files now shows deleted files as differences (as ghosted out rows)
 - Refactoring of the modified Create Content Wizard into a new wizard Create Web Content Wizard
   - responsible for creating content in the AVM store rather than usual SpacesStore
   - removed XML specific handling from Create Content Wizard (now only present in Create Web Content Wizard)
 - Create Content action added to sandbox view - NOTE: does not yet create content in the AVM world!
 - Added "jsp" filetype as plain text format mimetype (to allow inline-edit for JSP files as website content)
 - Open/closed state of My Modified Files panel is remembered between screen refreshes

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3864 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2006-09-20 14:33:42 +00:00
parent 0ee6dbcfc8
commit 9fe7ccf523
27 changed files with 1923 additions and 501 deletions

View File

@@ -944,10 +944,10 @@ public class CheckinCheckoutBean
private static Log logger = LogFactory.getLog(CheckinCheckoutBean.class);
/** I18N messages */
private static final String MSG_ERROR_CHECKIN = "error_checkin";
private static final String MSG_ERROR_CANCELCHECKOUT = "error_cancel_checkout";
private static final String MSG_ERROR_UPDATE = "error_update";
private static final String MSG_ERROR_CHECKOUT = "error_checkout";
public static final String MSG_ERROR_CHECKIN = "error_checkin";
public static final String MSG_ERROR_CANCELCHECKOUT = "error_cancel_checkout";
public static final String MSG_ERROR_UPDATE = "error_update";
public static final String MSG_ERROR_CHECKOUT = "error_checkout";
/** constants for copy location selection */
private static final String COPYLOCATION_CURRENT = "current";

View File

@@ -381,7 +381,7 @@ public abstract class BaseContentWizard extends BaseWizardBean
}
else
{
writer.putContent(strContent == null ? "" : strContent);
writer.putContent(strContent == null ? "" : strContent);
}
// remember the created node now

View File

@@ -17,7 +17,6 @@
package org.alfresco.web.bean.content;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
@@ -35,17 +34,9 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.data.QuickSort;
import org.alfresco.web.templating.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.ContentWriter;
import java.io.OutputStreamWriter;
import org.alfresco.web.app.servlet.FacesHelper;
/**
* Bean implementation for the "Create Content Wizard" dialog
*
@@ -54,11 +45,9 @@ import org.alfresco.web.app.servlet.FacesHelper;
public class CreateContentWizard extends BaseContentWizard
{
protected String content = null;
protected String templateTypeName;
protected List<SelectItem> createMimeTypes;
private static final Log LOGGER =
LogFactory.getLog(CreateContentWizard.class);
private static Log logger = LogFactory.getLog(CreateContentWizard.class);
// ------------------------------------------------------------------------------
@@ -68,25 +57,7 @@ public class CreateContentWizard extends BaseContentWizard
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
LOGGER.debug("saving file content to " + this.fileName);
saveContent(null, this.content);
if (this.templateTypeName != null)
{
LOGGER.debug("generating template output for " + this.templateTypeName);
this.nodeService.setProperty(this.createdNode,
TemplatingService.TT_QNAME,
this.templateTypeName);
TemplatingService ts = TemplatingService.getInstance();
TemplateType tt = this.getTemplateType();
OutputUtil.generate(this.createdNode,
ts.parseXML(this.content),
tt,
this.fileName,
this.getContainerNodeRef(),
this.fileFolderService,
this.contentService,
this.nodeService);
}
// return the default outcome
return outcome;
@@ -99,7 +70,6 @@ public class CreateContentWizard extends BaseContentWizard
this.content = null;
this.inlineEdit = true;
this.templateTypeName = null;
this.mimeType = MimetypeMap.MIMETYPE_HTML;
}
@@ -163,20 +133,6 @@ public class CreateContentWizard extends BaseContentWizard
this.content = content;
}
public List<SelectItem> getCreateTemplateTypes()
{
Collection<TemplateType> ttl = TemplatingService.getInstance().getTemplateTypes();
List<SelectItem> sil = new ArrayList<SelectItem>(ttl.size());
for (TemplateType tt : ttl)
{
sil.add(new SelectItem(tt.getName(), tt.getName()));
}
QuickSort sorter = new QuickSort(sil, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
sorter.sort();
return sil;
}
/**
* @return Returns a list of mime types to allow the user to select from
*/
@@ -213,12 +169,12 @@ public class CreateContentWizard extends BaseContentWizard
}
else
{
LOGGER.warn("Could not find 'create-mime-types' configuration element");
logger.warn("Could not find 'create-mime-types' configuration element");
}
}
else
{
LOGGER.warn("Could not find 'Content Wizards' configuration section");
logger.warn("Could not find 'Content Wizards' configuration section");
}
}
@@ -226,25 +182,6 @@ public class CreateContentWizard extends BaseContentWizard
return this.createMimeTypes;
}
public String getTemplateTypeName()
{
return this.templateTypeName;
}
public TemplateType getTemplateType()
{
final TemplatingService ts = TemplatingService.getInstance();
return ts.getTemplateType(this.getTemplateTypeName());
}
/**
* @param templateType Sets the currently selected template type
*/
public void setTemplateTypeName(final String templateTypeName)
{
this.templateTypeName = templateTypeName;
}
/**
* @return Returns the summary data for the wizard.
*/
@@ -261,6 +198,7 @@ public class CreateContentWizard extends BaseContentWizard
getSummaryMimeType(this.mimeType)});
}
// ------------------------------------------------------------------------------
// Action event handlers
@@ -272,12 +210,4 @@ public class CreateContentWizard extends BaseContentWizard
// clear the content as HTML is not compatible with the plain text box etc.
this.content = null;
}
// ------------------------------------------------------------------------------
// Service Injection
// ------------------------------------------------------------------------------
// Helper methods
}

View File

@@ -51,6 +51,7 @@ import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.ui.common.component.UIBreadcrumb;
import org.alfresco.web.ui.common.component.data.UIRichList;
import org.alfresco.web.ui.wcm.WebResources;
import org.alfresco.web.ui.wcm.component.UIUserSandboxes;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -74,12 +75,19 @@ public class AVMBrowseBean implements IContextListener
private String sandboxTitle = null;
private String currentPath = null;
/* component references */
private UIRichList foldersRichList;
private UIRichList filesRichList;
private UIUserSandboxes userSandboxes;
/* transient lists of files/folders for a directory */
private List<Map> files = null;
private List<Map> folders = null;
/** Current AVM Node context*/
private AVMNode avmNode = null;
/** breadcrumb location */
private List<IBreadcrumbHandler> location = null;
/** The NodeService to be used by the bean */
@@ -131,6 +139,11 @@ public class AVMBrowseBean implements IContextListener
{
this.nodeService = nodeService;
}
public NodeService getNodeService()
{
return this.nodeService;
}
/**
* @param dictionaryService The DictionaryService to set.
@@ -239,7 +252,23 @@ public class AVMBrowseBean implements IContextListener
{
this.filesRichList = filesRichList;
}
/**
* @return Returns the userSandboxes.
*/
public UIUserSandboxes getUserSandboxes()
{
return this.userSandboxes;
}
/**
* @param userSandboxes The userSandboxes to set.
*/
public void setUserSandboxes(UIUserSandboxes userSandboxes)
{
this.userSandboxes = userSandboxes;
}
/**
* @return Returns the sandbox.
*/
@@ -316,6 +345,53 @@ public class AVMBrowseBean implements IContextListener
return this.navigator.getCurrentNode();
}
/**
* @return Returns the current AVM node context.
*/
public AVMNode getAvmNode()
{
return this.avmNode;
}
/**
* @param avmNode The AVM node context to set.
*/
public void setAvmNode(AVMNode avmNode)
{
this.avmNode = avmNode;
}
/**
* @param avmRef The AVMNodeDescriptor context to set.
*/
public void setAVMNodeDescriptor(AVMNodeDescriptor avmRef)
{
this.avmNode = new AVMNode(avmRef);
}
/**
* @return Breadcrumb location list
*/
public List<IBreadcrumbHandler> getLocation()
{
if (this.location == null)
{
List<IBreadcrumbHandler> loc = new ArrayList<IBreadcrumbHandler>(8);
loc.add(new AVMBreadcrumbHandler(getCurrentPath()));
this.location = loc;
}
return this.location;
}
/**
* @param location Breadcrumb location list
*/
public void setLocation(List<IBreadcrumbHandler> location)
{
this.location = location;
}
/**
* @return Map of avm node objects representing the folders with the current website space
*/
@@ -390,6 +466,10 @@ public class AVMBrowseBean implements IContextListener
}
}
// ------------------------------------------------------------------------------
// Action event handlers
/**
* Update the UI after a folder click action in the website browsing screens
*/
@@ -434,27 +514,33 @@ public class AVMBrowseBean implements IContextListener
}
/**
* @return Breadcrumb location list
* Action event called by all actions that need to setup a Content node context on the
* before an action page/wizard is called. The context will be an AVMNodeDescriptor in
* setAVMNode() which can be retrieved on action pages via getAVMNode().
*
* @param event ActionEvent
*/
public List<IBreadcrumbHandler> getLocation()
public void setupContentAction(ActionEvent event)
{
if (this.location == null)
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String path = params.get("id");
if (path != null && path.length() != 0)
{
List<IBreadcrumbHandler> loc = new ArrayList<IBreadcrumbHandler>(8);
loc.add(new AVMBreadcrumbHandler(getCurrentPath()));
this.location = loc;
setAVMNodeDescriptor(avmService.lookup(-1, path));
}
return this.location;
else
{
setAVMNodeDescriptor(null);
}
// update UI state ready for return after dialog close
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
/**
* @param location Breadcrumb location list
*/
public void setLocation(List<IBreadcrumbHandler> location)
{
this.location = location;
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* @return the internal AVM path to the current folder for browsing

View File

@@ -16,21 +16,24 @@
*/
package org.alfresco.web.bean.wcm;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.CheckinCheckoutBean;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils;
/**
* Bean backing the edit pages for a AVM node content.
@@ -38,10 +41,7 @@ import org.alfresco.web.ui.common.component.UIActionLink;
* @author Kevin Roast
*/
public class AVMEditBean
{
/** Current AVM Node context*/
private AVMNodeDescriptor avmNode = null;
{
private String documentContent = null;
private String editorOutput = null;
@@ -49,6 +49,9 @@ public class AVMEditBean
/** AVM service bean reference */
protected AVMService avmService;
/** AVM Browse Bean reference */
protected AVMBrowseBean avmBrowseBean;
/** The ContentService bean reference */
protected ContentService contentService;
@@ -57,13 +60,21 @@ public class AVMEditBean
// Bean property getters and setters
/**
* @param avmService The AVMService to set.
* @param avmService The AVMService to set.
*/
public void setAvmService(AVMService avmService)
{
this.avmService = avmService;
}
/**
* @param avmBrowseBean The AVMBrowseBean to set.
*/
public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean)
{
this.avmBrowseBean = avmBrowseBean;
}
/**
* @param contentService The ContentService to set.
*/
@@ -75,17 +86,33 @@ public class AVMEditBean
/**
* @return Returns the current AVM node context.
*/
public AVMNodeDescriptor getAVMNode()
public AVMNode getAvmNode()
{
return this.avmNode;
return this.avmBrowseBean.getAvmNode();
}
/**
* @param avmNode The AVM node context to set.
* @return Large file icon for current AVM node
*/
public void setAVMNode(AVMNodeDescriptor avmNode)
public String getFileType32()
{
this.avmNode = avmNode;
return Utils.getFileTypeImage(getAvmNode().getName(), false);
}
/**
* @return Small file icon for current AVM node
*/
public String getFileType16()
{
return Utils.getFileTypeImage(getAvmNode().getName(), true);
}
/**
* @return Content URL for current AVM node
*/
public String getUrl()
{
return DownloadContentServlet.generateDownloadURL(AVMNodeConverter.ToNodeRef(-1, getAvmNode().getPath()), getAvmNode().getName());
}
/**
@@ -124,38 +151,16 @@ public class AVMEditBean
// ------------------------------------------------------------------------------
// Action event handlers
/**
* Action event called by all actions that need to setup a Content node context on the
* before an action page/wizard is called. The context will be an AVMNodeDescriptor in
* setAVMNode() which can be retrieved on action pages via getAVMNode().
*
* @param event ActionEvent
*/
public void setupContentAction(ActionEvent event)
{
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String path = params.get("id");
if (path != null && path.length() != 0)
{
setAVMNode(avmService.lookup(-1, path));
}
else
{
setAVMNode(null);
}
}
/**
* Action handler called to calculate which editing screen to display based on the mimetype
* of a document. If appropriate, the in-line editing screen will be shown.
*/
public void setupEditAction(ActionEvent event)
{
setupContentAction(event);
this.avmBrowseBean.setupContentAction(event);
// retrieve the content reader for this node
NodeRef avmRef = AVMNodeConverter.ToNodeRef(-1, getAVMNode().getPath());
NodeRef avmRef = AVMNodeConverter.ToNodeRef(-1, getAvmNode().getPath());
ContentReader reader = contentService.getReader(avmRef, ContentModel.PROP_CONTENT);
if (reader != null)
{
@@ -201,4 +206,81 @@ public class AVMEditBean
}
}
}
/**
* Action called upon completion of the Edit File download page
*/
public String editFileOK()
{
String outcome = null;
AVMNode node = getAvmNode();
if (node != null)
{
resetState();
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
return outcome;
}
/**
* Action handler called to set the content of a node from an inline editing page.
*/
public String editInlineOK()
{
String outcome = null;
UserTransaction tx = null;
AVMNode avmNode = getAvmNode();
if (avmNode != null)
{
NodeRef avmRef = AVMNodeConverter.ToNodeRef(-1, getAvmNode().getPath());
try
{
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
// get an updating writer that we can use to modify the content on the current node
ContentWriter writer = this.contentService.getWriter(avmRef, ContentModel.PROP_CONTENT, true);
writer.putContent(this.editorOutput);
// commit the transaction
tx.commit();
// TODO: generate template content
/*if (nodeService.getProperty(node.getNodeRef(),
TemplatingService.TT_QNAME) != null)
{
OutputUtil.regenerate(node.getNodeRef(),
this.contentService,
this.nodeService);
}*/
resetState();
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
catch (Throwable err)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
Utils.addErrorMessage(Application.getMessage(
FacesContext.getCurrentInstance(), CheckinCheckoutBean.MSG_ERROR_UPDATE) + err.getMessage());
}
}
return outcome;
}
private void resetState()
{
// clean up and clear action context
//clearUpload();
this.avmBrowseBean.setAvmNode(null);
setDocumentContent(null);
setEditorOutput(null);
}
}

View File

@@ -16,21 +16,19 @@
*/
package org.alfresco.web.bean.wcm;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import javax.faces.context.FacesContext;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNameMap;
import org.alfresco.web.bean.repository.NodePropertyResolver;
import org.alfresco.web.bean.repository.QNameNodeMap;
import org.alfresco.web.bean.repository.Repository;
/**
@@ -66,6 +64,16 @@ public class AVMNode implements Map<String, Object>
{
return this.version;
}
public String getName()
{
return this.avmRef.getName();
}
public NodeRef getNodeRef()
{
return AVMNodeConverter.ToNodeRef(this.version, this.path);
}
/**
* @return All the properties known about this node.
@@ -156,22 +164,7 @@ public class AVMNode implements Map<String, Object>
*/
public Object get(Object key)
{
Object obj = null;
// there are some things that aren't available as properties
// but from method calls, so for these handle them individually
Map<String, Object> props = getProperties();
/*if (propsInitialised == false)
{
// well known properties required as publically accessable map attributes
props.put("id", this.getId());
props.put("name", this.getName()); // TODO: perf test pulling back single prop here instead of all!
props.put("nodeRef", this.getNodeRef());
propsInitialised = true;
}*/
return props.get(key);
return getProperties().get(key);
}
/**

View File

@@ -0,0 +1,269 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.bean.wcm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import org.alfresco.config.Config;
import org.alfresco.config.ConfigElement;
import org.alfresco.config.ConfigService;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.content.BaseContentWizard;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.data.QuickSort;
import org.alfresco.web.templating.OutputUtil;
import org.alfresco.web.templating.TemplateType;
import org.alfresco.web.templating.TemplatingService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Bean implementation for the "Create Web Content Wizard" dialog
*/
public class CreateWebContentWizard extends BaseContentWizard
{
protected String content = null;
protected String templateTypeName;
protected List<SelectItem> createMimeTypes;
private static final Log logger = LogFactory.getLog(CreateWebContentWizard.class);
// ------------------------------------------------------------------------------
// Wizard implementation
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
logger.debug("saving file content to " + this.fileName);
saveContent(null, this.content);
if (this.templateTypeName != null)
{
logger.debug("generating template output for " + this.templateTypeName);
this.nodeService.setProperty(this.createdNode,
TemplatingService.TT_QNAME,
this.templateTypeName);
TemplatingService ts = TemplatingService.getInstance();
TemplateType tt = this.getTemplateType();
OutputUtil.generate(this.createdNode,
ts.parseXML(this.content),
tt,
this.fileName,
this.getContainerNodeRef(),
this.fileFolderService,
this.contentService,
this.nodeService);
}
// return the default outcome
return outcome;
}
@Override
public void init(Map<String, String> parameters)
{
super.init(parameters);
this.content = null;
this.inlineEdit = true;
this.templateTypeName = null;
this.mimeType = MimetypeMap.MIMETYPE_XML;
}
@Override
public boolean getNextButtonDisabled()
{
// TODO: Allow the next button state to be configured so that
// wizard implementations don't have to worry about
// checking step numbers
boolean disabled = false;
int step = Application.getWizardManager().getCurrentStep();
switch(step)
{
case 1:
{
disabled = (this.fileName == null || this.fileName.length() == 0);
break;
}
}
return disabled;
}
@Override
protected String doPostCommitProcessing(FacesContext context, String outcome)
{
// as we were successful, go to the set properties dialog if asked
// to otherwise just return
if (this.showOtherProperties)
{
// we are going to immediately edit the properties so we need
// to setup the BrowseBean context appropriately
this.browseBean.setDocument(new Node(this.createdNode));
return getDefaultFinishOutcome() + AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
"dialog:setContentProperties";
}
else
{
return outcome;
}
}
// ------------------------------------------------------------------------------
// Bean Getters and Setters
/**
* @return Returns the content from the edited form.
*/
public String getContent()
{
return this.content;
}
/**
* @param content The content to edit (should be clear initially)
*/
public void setContent(String content)
{
this.content = content;
}
public List<SelectItem> getCreateTemplateTypes()
{
Collection<TemplateType> ttl = TemplatingService.getInstance().getTemplateTypes();
List<SelectItem> sil = new ArrayList<SelectItem>(ttl.size());
for (TemplateType tt : ttl)
{
sil.add(new SelectItem(tt.getName(), tt.getName()));
}
QuickSort sorter = new QuickSort(sil, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
sorter.sort();
return sil;
}
/**
* @return Returns a list of mime types to allow the user to select from
*/
public List<SelectItem> getCreateMimeTypes()
{
if (this.createMimeTypes == null)
{
FacesContext context = FacesContext.getCurrentInstance();
// add the well known object type to start with
this.createMimeTypes = new ArrayList<SelectItem>(5);
// add the configured create mime types to the list
ConfigService svc = Application.getConfigService(context);
Config wizardCfg = svc.getConfig("Content Wizards");
if (wizardCfg != null)
{
ConfigElement typesCfg = wizardCfg.getConfigElement("create-mime-types");
if (typesCfg != null)
{
for (ConfigElement child : typesCfg.getChildren())
{
String currentMimeType = child.getAttribute("name");
if (currentMimeType != null)
{
String label = getSummaryMimeType(currentMimeType);
this.createMimeTypes.add(new SelectItem(currentMimeType, label));
}
}
// make sure the list is sorted by the label
QuickSort sorter = new QuickSort(this.objectTypes, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
sorter.sort();
}
else
{
logger.warn("Could not find 'create-mime-types' configuration element");
}
}
else
{
logger.warn("Could not find 'Content Wizards' configuration section");
}
}
return this.createMimeTypes;
}
public String getTemplateTypeName()
{
return this.templateTypeName;
}
public TemplateType getTemplateType()
{
final TemplatingService ts = TemplatingService.getInstance();
return ts.getTemplateType(this.getTemplateTypeName());
}
/**
* @param templateType Sets the currently selected template type
*/
public void setTemplateTypeName(final String templateTypeName)
{
this.templateTypeName = templateTypeName;
}
/**
* @return Returns the summary data for the wizard.
*/
public String getSummary()
{
ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
// TODO: show first few lines of content here?
return buildSummary(
new String[] {bundle.getString("file_name"),
bundle.getString("type"),
bundle.getString("content_type")},
new String[] {this.fileName, getSummaryObjectType(),
getSummaryMimeType(this.mimeType)});
}
// ------------------------------------------------------------------------------
// Action event handlers
/**
* Create content type value changed by the user
*/
public void createContentChanged(ValueChangeEvent event)
{
// clear the content as HTML is not compatible with the plain text box etc.
this.content = null;
}
}

View File

@@ -102,7 +102,7 @@ public class CreateWebsiteWizard extends BaseWizardBean
// create the AVM stores (layers) to represent the newly created location website
createStagingSandbox(this.name);
// create a sandbox for each user (TODO: based on role?)
// create a sandbox for each user - TODO: based on role?
List<String> invitedUsers = getInvitedUsernames();
invitedUsers.add(Application.getCurrentUser(context).getUserName());
for (String username : invitedUsers)
@@ -113,8 +113,6 @@ public class CreateWebsiteWizard extends BaseWizardBean
// save the list of invited users against the store
this.nodeService.setProperty(nodeRef, ContentModel.PROP_USERSANDBOXES, (Serializable)invitedUsers);
// TODO: import the ZIP structure into the AVM staging store
// set the property on the node to reference the AVM store
this.nodeService.setProperty(nodeRef, ContentModel.PROP_AVMSTORE, this.name);

View File

@@ -0,0 +1,110 @@
package org.alfresco.web.bean.wcm;
import java.text.MessageFormat;
import javax.faces.context.FacesContext;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.repository.Node;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Bean implementation for the AVM "Delete File" dialog
*
* @author kevinr
*/
public class DeleteFileDialog extends BaseDialogBean
{
private static final Log logger = LogFactory.getLog(DeleteFileDialog.class);
protected AVMService avmService;
protected AVMBrowseBean avmBrowseBean;
/**
* @param avmBrowseBean The avmBrowseBean to set.
*/
public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean)
{
this.avmBrowseBean = avmBrowseBean;
}
/**
* @param avmService The avmService to set.
*/
public void setAvmService(AVMService avmService)
{
this.avmService = avmService;
}
// ------------------------------------------------------------------------------
// Dialog implementation
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
// get the content to delete
AVMNode node = this.avmBrowseBean.getAvmNode();
if (node != null)
{
if (logger.isDebugEnabled())
logger.debug("Trying to delete AVM node: " + node.getPath());
// delete the node
this.avmService.removeNode(
node.getPath().substring(0, node.getPath().lastIndexOf('/')),
node.getPath().substring(node.getPath().lastIndexOf('/') + 1));
}
else
{
logger.warn("WARNING: delete called without a current AVM Node!");
}
return outcome;
}
@Override
protected String doPostCommitProcessing(FacesContext context, String outcome)
{
// clear action context
this.avmBrowseBean.setAvmNode(null);
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
@Override
protected String getErrorMessageId()
{
return "error_delete_file";
}
@Override
public boolean getFinishButtonDisabled()
{
return false;
}
// ------------------------------------------------------------------------------
// Bean Getters and Setters
/**
* Returns the confirmation to display to the user before deleting the content.
*
* @return The formatted message to display
*/
public String getConfirmMessage()
{
String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_avm_file_confirm");
return MessageFormat.format(fileConfirmMsg,
new Object[] {this.avmBrowseBean.getAvmNode().getName()});
}
}

View File

@@ -0,0 +1,110 @@
package org.alfresco.web.bean.wcm;
import java.text.MessageFormat;
import javax.faces.context.FacesContext;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.repository.Node;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Bean implementation for the AVM "Delete Folder" dialog
*
* @author kevinr
*/
public class DeleteFolderDialog extends BaseDialogBean
{
private static final Log logger = LogFactory.getLog(DeleteFolderDialog.class);
protected AVMService avmService;
protected AVMBrowseBean avmBrowseBean;
/**
* @param avmBrowseBean The avmBrowseBean to set.
*/
public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean)
{
this.avmBrowseBean = avmBrowseBean;
}
/**
* @param avmService The avmService to set.
*/
public void setAvmService(AVMService avmService)
{
this.avmService = avmService;
}
// ------------------------------------------------------------------------------
// Dialog implementation
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
// get the content to delete
AVMNode node = this.avmBrowseBean.getAvmNode();
if (node != null)
{
if (logger.isDebugEnabled())
logger.debug("Trying to delete AVM node: " + node.getPath());
// delete the node
this.avmService.removeNode(
node.getPath().substring(0, node.getPath().lastIndexOf('/')),
node.getPath().substring(node.getPath().lastIndexOf('/') + 1));
}
else
{
logger.warn("WARNING: delete called without a current AVM Node!");
}
return outcome;
}
@Override
protected String doPostCommitProcessing(FacesContext context, String outcome)
{
// clear action context
this.avmBrowseBean.setAvmNode(null);
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
@Override
protected String getErrorMessageId()
{
return "error_delete_folder";
}
@Override
public boolean getFinishButtonDisabled()
{
return false;
}
// ------------------------------------------------------------------------------
// Bean Getters and Setters
/**
* Returns the confirmation to display to the user before deleting the content.
*
* @return The formatted message to display
*/
public String getConfirmMessage()
{
String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(),
"delete_avm_folder_confirm");
return MessageFormat.format(fileConfirmMsg,
new Object[] {this.avmBrowseBean.getAvmNode().getName()});
}
}

View File

@@ -42,205 +42,205 @@ import org.w3c.dom.Document;
*/
public class OutputUtil
{
private static final Log LOGGER = LogFactory.getLog(OutputUtil.class);
private static final String PARENT_AVM_PATH =
"repo-1:/repo-1/alice/appBase/avm_webapps/ROOT";
private static String stripExtension(String s)
{
return s.replaceAll("(.+)\\..*", "$1");
}
private static String getAVMParentPath(NodeRef nodeRef,
NodeService nodeService)
throws Exception
{
ChildAssociationRef caf = nodeService.getPrimaryParent(nodeRef);
final String parentName = (String)
nodeService.getProperty(caf.getParentRef(), ContentModel.PROP_NAME);
LOGGER.debug("computed avm path " + PARENT_AVM_PATH + "/" + parentName);
final String result = PARENT_AVM_PATH + "/" + parentName;
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
if (avmService.lookup(-1, result) != null)
{
return result;
}
else
{
// avmService.createDirectory(PARENT_AVM_PATH, parentName);
return PARENT_AVM_PATH;
}
}
public static void generate(NodeRef createdNode,
Document xml,
TemplateType tt,
String fileName,
NodeRef containerNodeRef,
FileFolderService fileFolderService,
ContentService contentService,
NodeService nodeService)
throws Exception
{
try
{
// get the node ref of the node that will contain the content
String generatedFileName = stripExtension(fileName) + ".shtml";
FileInfo fileInfo =
fileFolderService.create(containerNodeRef,
generatedFileName,
ContentModel.TYPE_CONTENT);
NodeRef fileNodeRef = fileInfo.getNodeRef();
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " +
generatedFileName);
// get a writer for the content and put the file
ContentWriter writer = contentService.getWriter(fileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/html");
writer.setEncoding("UTF-8");
TemplateOutputMethod tom = tt.getOutputMethods().get(0);
OutputStreamWriter out =
new OutputStreamWriter(writer.getContentOutputStream());
tom.generate(xml, tt, out);
out.close();
nodeService.setProperty(fileNodeRef,
TemplatingService.TT_QNAME,
tt.getName());
LOGGER.debug("generated " + generatedFileName + " using " + tom);
if (createdNode != null)
{
nodeService.setProperty(createdNode,
TemplatingService.TT_GENERATED_OUTPUT_QNAME,
fileNodeRef.toString());
}
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
final String parentAVMPath = getAVMParentPath(createdNode, nodeService);
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, fileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + fileName));
}
LOGGER.debug("writing xml " + fileName + " to avm");
final TemplatingService ts = TemplatingService.getInstance();
ts.writeXML(xml, out);
out.close();
}
catch (Exception e)
{
LOGGER.error(e);
e.printStackTrace();
throw e;
}
}
public static void regenerate(final NodeRef nodeRef,
final ContentService contentService,
final NodeService nodeService)
throws Exception
{
try
{
final TemplatingService ts = TemplatingService.getInstance();
final String templateTypeName = (String)
nodeService.getProperty(nodeRef, TemplatingService.TT_QNAME);
final TemplateType tt = ts.getTemplateType(templateTypeName);
final ContentReader reader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
final Document xml = ts.parseXML(reader.getContentInputStream());
String fileName = (String)
nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
NodeRef generatedNodeRef =
new NodeRef((String)
nodeService.getProperty(nodeRef,
TemplatingService.TT_GENERATED_OUTPUT_QNAME));
String generatedFileName = (String)
nodeService.getProperty(generatedNodeRef,
ContentModel.PROP_NAME);
if (LOGGER.isDebugEnabled())
LOGGER.debug("regenerating file node for : " + fileName + " (" +
nodeRef.toString() + ") to " + generatedNodeRef.toString());
// get a writer for the content and put the file
ContentWriter writer = contentService.getWriter(generatedNodeRef,
ContentModel.PROP_CONTENT,
true);
// set the mimetype and encoding
writer.setMimetype("text/html");
writer.setEncoding("UTF-8");
// put a loop to generate all output methods
TemplateOutputMethod tom = tt.getOutputMethods().get(0);
OutputStreamWriter out =
new OutputStreamWriter(writer.getContentOutputStream());
tom.generate(xml, tt, out);
out.close();
LOGGER.debug("generated " + fileName + " using " + tom);
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
final String parentAVMPath = getAVMParentPath(nodeRef, nodeService);
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, fileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + fileName));
}
LOGGER.debug("writing xml " + fileName + " to avm");
ts.writeXML(xml, out);
out.close();
}
catch (Exception e)
{
LOGGER.error(e);
e.printStackTrace();
throw e;
}
}
private static final Log LOGGER = LogFactory.getLog(OutputUtil.class);
private static final String PARENT_AVM_PATH =
"repo-1:/repo-1/alice/appBase/avm_webapps/ROOT";
private static String stripExtension(String s)
{
return s.replaceAll("(.+)\\..*", "$1");
}
private static String getAVMParentPath(NodeRef nodeRef,
NodeService nodeService)
throws Exception
{
ChildAssociationRef caf = nodeService.getPrimaryParent(nodeRef);
final String parentName = (String)
nodeService.getProperty(caf.getParentRef(), ContentModel.PROP_NAME);
LOGGER.debug("computed avm path " + PARENT_AVM_PATH + "/" + parentName);
final String result = PARENT_AVM_PATH + "/" + parentName;
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
if (avmService.lookup(-1, result) != null)
{
return result;
}
else
{
// avmService.createDirectory(PARENT_AVM_PATH, parentName);
return PARENT_AVM_PATH;
}
}
public static void generate(NodeRef createdNode,
Document xml,
TemplateType tt,
String fileName,
NodeRef containerNodeRef,
FileFolderService fileFolderService,
ContentService contentService,
NodeService nodeService)
throws Exception
{
try
{
// get the node ref of the node that will contain the content
String generatedFileName = stripExtension(fileName) + ".shtml";
FileInfo fileInfo =
fileFolderService.create(containerNodeRef,
generatedFileName,
ContentModel.TYPE_CONTENT);
NodeRef fileNodeRef = fileInfo.getNodeRef();
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " +
generatedFileName);
// get a writer for the content and put the file
ContentWriter writer = contentService.getWriter(fileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/html");
writer.setEncoding("UTF-8");
TemplateOutputMethod tom = tt.getOutputMethods().get(0);
OutputStreamWriter out =
new OutputStreamWriter(writer.getContentOutputStream());
tom.generate(xml, tt, out);
out.close();
nodeService.setProperty(fileNodeRef,
TemplatingService.TT_QNAME,
tt.getName());
LOGGER.debug("generated " + generatedFileName + " using " + tom);
if (createdNode != null)
{
nodeService.setProperty(createdNode,
TemplatingService.TT_GENERATED_OUTPUT_QNAME,
fileNodeRef.toString());
}
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
final String parentAVMPath = getAVMParentPath(createdNode, nodeService);
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, fileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + fileName));
}
LOGGER.debug("writing xml " + fileName + " to avm");
final TemplatingService ts = TemplatingService.getInstance();
ts.writeXML(xml, out);
out.close();
}
catch (Exception e)
{
LOGGER.error(e);
e.printStackTrace();
throw e;
}
}
public static void regenerate(final NodeRef nodeRef,
final ContentService contentService,
final NodeService nodeService)
throws Exception
{
try
{
final TemplatingService ts = TemplatingService.getInstance();
final String templateTypeName = (String)
nodeService.getProperty(nodeRef, TemplatingService.TT_QNAME);
final TemplateType tt = ts.getTemplateType(templateTypeName);
final ContentReader reader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
final Document xml = ts.parseXML(reader.getContentInputStream());
String fileName = (String)
nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
NodeRef generatedNodeRef =
new NodeRef((String)
nodeService.getProperty(nodeRef,
TemplatingService.TT_GENERATED_OUTPUT_QNAME));
String generatedFileName = (String)
nodeService.getProperty(generatedNodeRef,
ContentModel.PROP_NAME);
if (LOGGER.isDebugEnabled())
LOGGER.debug("regenerating file node for : " + fileName + " (" +
nodeRef.toString() + ") to " + generatedNodeRef.toString());
// get a writer for the content and put the file
ContentWriter writer = contentService.getWriter(generatedNodeRef,
ContentModel.PROP_CONTENT,
true);
// set the mimetype and encoding
writer.setMimetype("text/html");
writer.setEncoding("UTF-8");
// put a loop to generate all output methods
TemplateOutputMethod tom = tt.getOutputMethods().get(0);
OutputStreamWriter out =
new OutputStreamWriter(writer.getContentOutputStream());
tom.generate(xml, tt, out);
out.close();
LOGGER.debug("generated " + fileName + " using " + tom);
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
final String parentAVMPath = getAVMParentPath(nodeRef, nodeService);
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, fileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + fileName));
}
LOGGER.debug("writing xml " + fileName + " to avm");
ts.writeXML(xml, out);
out.close();
}
catch (Exception e)
{
LOGGER.error(e);
e.printStackTrace();
throw e;
}
}
}

View File

@@ -63,6 +63,7 @@ import org.springframework.web.jsf.FacesContextUtils;
public class UIUserSandboxes extends SelfRenderingComponent
{
private static final String ACTIONS_FILE = "avm_file_modified";
private static final String ACTIONS_FOLDER = "avm_folder_modified";
private static final String COMPONENT_ACTIONS = "org.alfresco.faces.Actions";
@@ -74,6 +75,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
private static final String MSG_DESCRIPTION = "description";
private static final String MSG_MODIFIED = "modified_date";
private static final String MSG_ACTIONS = "actions";
private static final String MSG_DELETED_ITEM = "avm_node_deleted";
private static final String SPACE_ICON = "/images/icons/" + BrowseBean.SPACE_SMALL_DEFAULT + ".gif";
@@ -207,10 +209,10 @@ public class UIUserSandboxes extends SelfRenderingComponent
// components for the current username, preview, browse and modified items inner list
out.write("<table cellspacing=2 cellpadding=2 border=0 width=100%><tr><td>");
// show the icon for the sandbox as a clickable browse link image
// this is currently identical to the sandbox_browse action as below
Utils.encodeRecursive(context, aquireAction(
context, mainStore, username, "sandbox_icon", WebResources.IMAGE_USERSANDBOX_32,
"#{AVMBrowseBean.setupSandboxAction}", "browseSandbox"));
//out.write(Utils.buildImageTag(context, WebResources.IMAGE_USERSANDBOX_32, 32, 32, ""));
out.write("</td><td width=100%>");
out.write("<b>");
out.write(bundle.getString(MSG_USERNAME));
@@ -222,12 +224,12 @@ public class UIUserSandboxes extends SelfRenderingComponent
Utils.encodeRecursive(context, aquireAction(
context, mainStore, username, "sandbox_preview", "/images/icons/preview_website.gif",
null, null));
out.write("&nbsp;&nbsp;");
out.write("&nbsp;");
Utils.encodeRecursive(context, aquireAction(
context, mainStore, username, "sandbox_create", "/images/icons/new_content.gif",
null, null));
out.write("&nbsp;&nbsp;");
"#{AVMBrowseBean.setupSandboxAction}", "wizard:createWebContent"));
out.write("&nbsp;");
Utils.encodeRecursive(context, aquireAction(
context, mainStore, username, "sandbox_browse", "/images/icons/space_small.gif",
@@ -249,26 +251,9 @@ public class UIUserSandboxes extends SelfRenderingComponent
if (this.expandedPanels.contains(username))
{
out.write("<div style='padding:2px'></div>");
out.write("<table class='modifiedItemsList' cellspacing=2 cellpadding=2 border=0 width=100%>");
// header row
out.write("<tr align=left><th width=16></th><th>");
out.write(bundle.getString(MSG_NAME));
out.write("</th><th>");
out.write(bundle.getString(MSG_CREATED));
out.write("</th><th>");
out.write(bundle.getString(MSG_MODIFIED));
out.write("</th><th>");
out.write(bundle.getString(MSG_SIZE));
out.write("</th><th>");
out.write(bundle.getString(MSG_ACTIONS));
out.write("</th></tr>");
// row per modified doc item for this sandbox user
// list the modified docs for this sandbox user
renderUserFiles(context, out, username, storeRoot);
// end table
out.write("</table>");
}
out.write("</td></tr></table>");
@@ -309,7 +294,9 @@ public class UIUserSandboxes extends SelfRenderingComponent
{
AVMSyncService avmSyncService = getAVMSyncService(fc);
AVMService avmService = getAVMService(fc);
DateFormat df = Utils.getDateTimeFormat(fc);
ResourceBundle bundle = Application.getBundle(fc);
// build the paths to the stores to compare
String userStore = AVMConstants.buildAVMUserMainStoreName(storeRoot, username) + ":/";
@@ -317,13 +304,32 @@ public class UIUserSandboxes extends SelfRenderingComponent
// get the UIActions component responsible for rendering context related user actions
UIActions uiFileActions = aquireUIActions(ACTIONS_FILE);
UIActions uiFolderActions = aquireUIActions(ACTIONS_FOLDER);
// use the sync service to get the list of diffs between the stores
List<AVMDifference> diffs = avmSyncService.compare(-1, userStore, -1, stagingStore);
for (AVMDifference diff : diffs)
if (diffs.size() != 0)
{
//if (diff.getDifferenceCode() == AVMDifference.NEWER)
//{
// output the table of modified items
out.write("<table class='modifiedItemsList' cellspacing=2 cellpadding=2 border=0 width=100%>");
// header row
out.write("<tr align=left><th width=16></th><th>");
out.write(bundle.getString(MSG_NAME));
out.write("</th><th>");
out.write(bundle.getString(MSG_CREATED));
out.write("</th><th>");
out.write(bundle.getString(MSG_MODIFIED));
out.write("</th><th>");
out.write(bundle.getString(MSG_SIZE));
out.write("</th><th>");
out.write(bundle.getString(MSG_ACTIONS));
out.write("</th></tr>");
// output each of the modified files as a row in the table
for (AVMDifference diff : diffs)
{
// TODO: display cases for diff.getDifferenceCode()?
String sourcePath = diff.getSourcePath();
AVMNodeDescriptor node = avmService.lookup(-1, sourcePath);
if (node != null)
@@ -352,24 +358,87 @@ public class UIUserSandboxes extends SelfRenderingComponent
out.write(name);
}
out.write("</td><td>");
// created date
out.write(df.format(new Date(node.getCreateDate())));
out.write("</td><td>");
// modified date
out.write(df.format(new Date(node.getModDate())));
out.write("</td><td>");
// size of files
if (node.isFile())
{
// size of files
out.write(getSizeConverter().getAsString(fc, this, node.getLength()));
out.write("</td><td>");
// add UI actions for this item
uiFileActions.setContext(new AVMNode(node));
Utils.encodeRecursive(fc, uiFileActions);
}
else
{
out.write("</td><td>");
// add UI actions for this item
uiFolderActions.setContext(new AVMNode(node));
Utils.encodeRecursive(fc, uiFolderActions);
}
out.write("</td><td>");
// add UI actions for this item
uiFileActions.setContext(new AVMNode(node));
Utils.encodeRecursive(fc, uiFileActions);
out.write("</td></tr>");
}
//}
else
{
// must have been deleted from this sandbox - show ghosted
AVMNodeDescriptor ghost = avmService.lookup(-1, diff.getDestinationPath());
if (ghost != null)
{
// icon and name of the file/folder - files are clickable to see the content
String name = ghost.getName();
out.write("<tr><td width=16>");
if (ghost.isFile())
{
out.write(Utils.buildImageTag(fc, Utils.getFileTypeImage(fc, name, true), ""));
out.write("</td><td style='color:#aaaaaa'>");
out.write(name);
out.write("</a>");
}
else
{
out.write(Utils.buildImageTag(fc, SPACE_ICON, 16, 16, ""));
out.write("</td><td style='color:#aaaaaa'>");
out.write(name);
}
out.write("</td><td style='color:#aaaaaa'>");
// created date
out.write(df.format(new Date(ghost.getCreateDate())));
out.write("</td><td style='color:#aaaaaa'>");
// modified date
out.write(df.format(new Date(ghost.getModDate())));
out.write("</td><td style='color:#aaaaaa'>");
// size of files
if (ghost.isFile())
{
out.write(getSizeConverter().getAsString(fc, this, ghost.getLength()));
}
out.write("</td><td style='color:#aaaaaa'>");
// no UI actions for this item
out.write('[' + bundle.getString(MSG_DELETED_ITEM) + ']');
out.write("</td></tr>");
}
}
}
// end table
out.write("</table>");
}
else
{
// TODO: output "no modified files found" message
}
}
@@ -385,6 +454,14 @@ public class UIUserSandboxes extends SelfRenderingComponent
return this.sizeConverter;
}
/**
* Aquire the UIActions component for the specified action group ID.
* Search for the component in the child list or create as needed.
*
* @param id ActionGroup id of the UIActions component
*
* @return UIActions component
*/
private UIActions aquireUIActions(String id)
{
UIActions uiActions = null;
@@ -401,6 +478,7 @@ public class UIUserSandboxes extends SelfRenderingComponent
javax.faces.application.Application facesApp = FacesContext.getCurrentInstance().getApplication();
uiActions = (UIActions)facesApp.createComponent(COMPONENT_ACTIONS);
uiActions.setShowLink(false);
uiActions.getAttributes().put("styleClass", "inlineAction");
uiActions.setId(id);
uiActions.setParent(this);
uiActions.setValue(id);