- adding aspect to webapp nodes to differentiate them from ordinary folders in the avm_webapps directory

- refactoring of generate and regenerate calls to take a FormInstanceData object
- adding in support for overriding step title and description properties in wizards so as to be able to format them with parameters
- making the step descriptions in create form wizard reiterate the form name so as to give the user better context
- displaying avm task resources in the manage task screen.  still need to get actions working and clean this up a bit.
- making output path patterns sandbox relative
- refactored utility method for combining avm paths sensitive to webapp vs sandbox relative paths.
- adding a default description for generated renditions

todo:
- cleanup some usage of AVMNode from ManageTaskBean
- get actions to appear in manage task screen
- add a multi value property to the web project for all its webapps
- properly use overridden values for forms from the web project settings

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4687 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-12-21 20:34:00 +00:00
parent ef3b4f793c
commit 2190c4f29d
26 changed files with 544 additions and 267 deletions

View File

@@ -64,14 +64,16 @@ public interface Form
* configured output path pattern.
*
* @param parentAVMPath the parent avm path
* @param webappname the current webapp name
* @param formInstanceDataFileName the file name provided by the user.
* @param formInstanceData the parsed xml content
*
* @return the path to use for writing the form instance data.
*/
public String getOutputPathForFormInstanceData(final String parentAVMPath,
public String getOutputPathForFormInstanceData(final Document formInstanceData,
final String formInstanceDataFileName,
final Document formInstanceData);
final String parentAVMPath,
final String webappName);
//XXXarielb not used currently and not sure if it's necessary...
// public void addInputMethod(final TemplateInputMethod in);

View File

@@ -108,13 +108,15 @@ class FormImpl
: null);
}
public String getOutputPathForFormInstanceData(final String parentAVMPath,
public String getOutputPathForFormInstanceData(final Document formInstanceData,
final String formInstanceDataName,
final Document formInstanceData)
final String parentAVMPath,
final String webappName)
{
final String outputPathPattern = this.getOutputPathPattern();
final Map<String, Object> root = new HashMap<String, Object>();
root.put("webapp", webappName);
root.put("xml", NodeModel.wrap(formInstanceData));
root.put("name", formInstanceDataName);
root.put("date", new SimpleDate(new Date(), SimpleDate.DATETIME));
@@ -124,7 +126,9 @@ class FormImpl
String result = templateService.processTemplateString(null,
outputPathPattern,
new SimpleHash(root));
result = AVMConstants.buildAbsoluteAVMPath(parentAVMPath, result);
result = AVMConstants.buildAVMPath(parentAVMPath,
result,
AVMConstants.PathRelation.SANDBOX_RELATIVE);
LOGGER.debug("processed pattern " + outputPathPattern + " as " + result);
return result;
}

View File

@@ -38,6 +38,12 @@ public interface FormInstanceData
/** the path relative to the containing webapp */
public String getWebappRelativePath();
/** the path relative to the sandbox */
public String getSandboxRelativePath();
/** the path to the contents of this form instance data */
public String getPath();
/** the url to the asset */
public String getUrl();

View File

@@ -18,8 +18,6 @@ package org.alfresco.web.forms;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel;
@@ -66,15 +64,19 @@ public class FormInstanceDataImpl
nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME);
}
/** the path relative to the containing webapp */
public String getWebappRelativePath()
{
final String path = AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond();
final String p = ("[^:]+:/" + AVMConstants.DIR_APPBASE +
"/" + AVMConstants.DIR_WEBAPPS +
"/[^/]+(.*)/" + this.getName());
final Matcher m = Pattern.compile(p).matcher(path);
return m.matches() && m.group(1).length() != 0 ? m.group(1) : "/";
return AVMConstants.getWebappRelativePath(this.getPath());
}
public String getSandboxRelativePath()
{
return AVMConstants.getSandboxRelativePath(this.getPath());
}
public String getPath()
{
return AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond();
}
public Form getForm()
@@ -94,7 +96,7 @@ public class FormInstanceDataImpl
public String getUrl()
{
return AVMConstants.buildAVMAssetUrl(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond());
return AVMConstants.buildAVMAssetUrl(this.getPath());
}
public List<Rendition> getRenditions()
@@ -103,8 +105,7 @@ public class FormInstanceDataImpl
final List<Rendition> result = new LinkedList<Rendition>();
for (RenderingEngineTemplate ret : this.getForm().getRenderingEngineTemplates())
{
final String renditionAvmPath =
FormsService.getOutputAvmPathForRendition(ret, this.getNodeRef());
final String renditionAvmPath = ret.getOutputPathForRendition(this);
if (avmService.lookup(-1, renditionAvmPath) == null)
{
LOGGER.warn("unable to locate rendition " + renditionAvmPath +

View File

@@ -26,11 +26,13 @@ import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Stack;
import javax.faces.context.FacesContext;
@@ -266,28 +268,24 @@ public final class FormsService
*
* @param formInstanceDataNodeRef the noderef containing the form instance data
*/
public List<Rendition> generateRenditions(final NodeRef formInstanceDataNodeRef)
public List<Rendition> generateRenditions(final FormInstanceData formInstanceData)
throws IOException,
SAXException,
RenderingEngine.RenderingException
{
final Form form =
this.getForm((NodeRef)this.nodeService.getProperty(formInstanceDataNodeRef,
WCMAppModel.PROP_PARENT_FORM));
final Document formInstanceData = this.parseXML(formInstanceDataNodeRef);
final Form form = formInstanceData.getForm();
final String formInstanceDataFileName = (String)
this.nodeService.getProperty(formInstanceDataNodeRef, ContentModel.PROP_NAME);
final String formInstanceDataAvmPath =
AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
final Document formInstanceDataDocument = this.parseXML(formInstanceData.getNodeRef());
final String formInstanceDataFileName = formInstanceData.getName();
final String formInstanceDataAvmPath = formInstanceData.getPath();
LOGGER.debug("generating renditions for " + formInstanceDataAvmPath);
final List<Rendition> result = new LinkedList<Rendition>();
for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{
// get the node ref of the node that will contain the content
final String renditionAvmPath =
this.getOutputAvmPathForRendition(ret, formInstanceDataNodeRef);
final String renditionAvmPath = ret.getOutputPathForRendition(formInstanceData);
final String parentAVMPath = AVMNodeConverter.SplitBase(renditionAvmPath)[0];
this.makeAllDirectories(parentAVMPath);
final OutputStream out = this.avmService.createFile(parentAVMPath,
@@ -299,18 +297,24 @@ public final class FormsService
final HashMap<String, String> parameters =
this.getRenderingEngineParameters(formInstanceDataAvmPath,
renditionAvmPath);
ret.getRenderingEngine().render(formInstanceData, ret, parameters, out);
ret.getRenderingEngine().render(formInstanceDataDocument, ret, parameters, out);
out.close();
final NodeRef renditionNodeRef =
AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
final NodeRef renditionNodeRef = AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
final Rendition rendition = new RenditionImpl(renditionNodeRef);
form.registerFormInstanceData(renditionNodeRef);
ret.registerRendition(renditionNodeRef, formInstanceDataNodeRef);
ret.registerRendition(rendition, formInstanceData);
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f);
props.put(ContentModel.PROP_TITLE, AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
props.put(ContentModel.PROP_DESCRIPTION,
MessageFormat.format(bundle.getString("default_rendition_description"),
ret.getTitle(),
AVMConstants.getSandboxRelativePath(renditionAvmPath)));
nodeService.addAspect(renditionNodeRef, ContentModel.ASPECT_TITLED, props);
result.add(new RenditionImpl(renditionNodeRef));
result.add(rendition);
if (LOGGER.isDebugEnabled())
LOGGER.debug("generated " + renditionAvmPath + " using " + ret);
}
@@ -322,33 +326,27 @@ public final class FormsService
*
* @param formInstanceDataNodeRef the node ref containing the form instance data.
*/
public List<Rendition> regenerateRenditions(final NodeRef formInstanceDataNodeRef)
public List<Rendition> regenerateRenditions(final FormInstanceData formInstanceData)
throws IOException,
SAXException,
RenderingEngine.RenderingException
{
final NodeRef formNodeRef = (NodeRef)
nodeService.getProperty(formInstanceDataNodeRef, WCMAppModel.PROP_PARENT_FORM);
final Form form = this.getForm(formNodeRef);
final Form form = formInstanceData.getForm();
final ContentReader reader = contentService.getReader(formInstanceDataNodeRef, ContentModel.PROP_CONTENT);
final Document formInstanceData = this.parseXML(reader.getContentInputStream());
final String formInstanceDataFileName = (String)
nodeService.getProperty(formInstanceDataNodeRef, ContentModel.PROP_NAME);
final Document formInstanceDataDocument = this.parseXML(formInstanceData.getNodeRef());
final String formInstanceDataFileName = formInstanceData.getName();
// other parameter values passed to rendering engine
final String formInstanceDataAvmPath = AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
final String formInstanceDataAvmPath = formInstanceData.getPath();
LOGGER.debug("regenerating renditions for " + formInstanceDataAvmPath);
final List<Rendition> result = new LinkedList<Rendition>();
for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{
final String renditionAvmPath =
this.getOutputAvmPathForRendition(ret, formInstanceDataNodeRef);
final String renditionAvmPath = ret.getOutputPathForRendition(formInstanceData);
if (LOGGER.isDebugEnabled())
LOGGER.debug("regenerating file node for : " + formInstanceDataFileName +
" (" + formInstanceDataNodeRef.toString() +
" (" + formInstanceData.toString() +
") to " + renditionAvmPath);
// get a writer for the content and put the file
@@ -365,11 +363,10 @@ public final class FormsService
final HashMap<String, String> parameters =
this.getRenderingEngineParameters(formInstanceDataAvmPath, renditionAvmPath);
ret.getRenderingEngine().render(formInstanceData, ret, parameters, out);
ret.getRenderingEngine().render(formInstanceDataDocument, ret, parameters, out);
out.close();
final NodeRef renditionNodeRef =
AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
final NodeRef renditionNodeRef = AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
result.add(new RenditionImpl(renditionNodeRef));
if (LOGGER.isDebugEnabled())
LOGGER.debug("regenerated " + renditionAvmPath + " using " + ret);
@@ -377,21 +374,6 @@ public final class FormsService
return result;
}
public static String getOutputAvmPathForRendition(final RenderingEngineTemplate ret,
final NodeRef formInstanceDataNodeRef)
{
// final String formInstanceDataAvmPath =
// AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
// String formInstanceDataFileName = AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[1];
// formInstanceDataFileName = FormsService.stripExtension(formInstanceDataFileName);
String result = ret.getOutputPathForRendition(formInstanceDataNodeRef);
// if (result != null && result.charAt(0) == '/')
// {
//
// }
return result;
}
private static HashMap<String, String> getRenderingEngineParameters(final String formInstanceDataAvmPath,
final String renditionAvmPath)
{

View File

@@ -98,8 +98,10 @@ public class FreeMarkerRenderingEngine
try
{
final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions();
final String path = AVMConstants.buildAbsoluteAVMPath(parameters.get("parent_path"),
(String)args.get(0));
final String path =
AVMConstants.buildAVMPath(parameters.get("parent_path"),
(String)args.get(0),
AVMConstants.PathRelation.WEBAPP_RELATIVE);
final Document d = ef.parseXMLDocument(path);
return d != null ? d.getDocumentElement() : null;
}
@@ -119,8 +121,9 @@ public class FreeMarkerRenderingEngine
{
final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions();
final String path =
AVMConstants.buildAbsoluteAVMPath(parameters.get("parent_path"),
args.size() == 1 ? "" : (String)args.get(1));
AVMConstants.buildAVMPath(parameters.get("parent_path"),
args.size() == 1 ? "" : (String)args.get(1),
AVMConstants.PathRelation.WEBAPP_RELATIVE);
final Map<String, Document> resultMap = ef.parseXMLDocuments((String)args.get(0), path);
LOGGER.debug("received " + resultMap.size() + " documents in " + path);
@@ -165,8 +168,9 @@ public class FreeMarkerRenderingEngine
{
try
{
return AVMConstants.buildAbsoluteAVMPath(parameters.get("parent_path"),
(String)args.get(0));
return AVMConstants.buildAVMPath(parameters.get("parent_path"),
(String)args.get(0),
AVMConstants.PathRelation.WEBAPP_RELATIVE);
}
catch (Exception e)
{

View File

@@ -71,7 +71,7 @@ public interface RenderingEngineTemplate
*
* @return the output path for the rendition.
*/
public String getOutputPathForRendition(final NodeRef formInstanceDataNodeRef);
public String getOutputPathForRendition(final FormInstanceData formInstanceData);
/**
* Returns the mimetype to use when generating content for this
@@ -82,5 +82,6 @@ public interface RenderingEngineTemplate
*/
public String getMimetypeForRendition();
public void registerRendition(final NodeRef rendition, final NodeRef primaryFormInstanceData);
public void registerRendition(final Rendition rendition,
final FormInstanceData primaryFormInstanceData);
}

View File

@@ -34,6 +34,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.ServiceRegistry;
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.MimetypeService;
@@ -132,36 +133,43 @@ public class RenderingEngineTemplateImpl
*
* @return the output path to use for renditions.
*/
public String getOutputPathForRendition(final NodeRef formInstanceDataNodeRef)
public String getOutputPathForRendition(final FormInstanceData formInstanceData)
{
final ServiceRegistry sr = this.getServiceRegistry();
final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeService nodeService = sr.getNodeService();
final AVMService avmService = sr.getAVMService();
final String outputPathPattern = (String)
nodeService.getProperty(this.renditionPropertiesNodeRef,
WCMAppModel.PROP_OUTPUT_PATH_PATTERN_RENDITION);
final String formInstanceDataAVMPath =
AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
final String formInstanceDataAVMPath = formInstanceData.getPath();
final Map<String, Object> root = new HashMap<String, Object>();
final String formInstanceDataName = (String)
sr.getNodeService().getProperty(formInstanceDataNodeRef, ContentModel.PROP_NAME);
root.put("name",
formInstanceDataName.replaceAll("(.+)\\..*", "$1"));
final String webappName =
(avmService.hasAspect(-1,
AVMConstants.getWebappPath(formInstanceDataAVMPath),
WCMAppModel.ASPECT_WEBAPP)
? AVMConstants.getWebapp(formInstanceDataAVMPath)
: null);
root.put("webapp", webappName);
final String formInstanceDataName = formInstanceData.getName();
root.put("name", formInstanceDataName.replaceAll("(.+)\\..*", "$1"));
root.put("extension",
sr.getMimetypeService().getExtension(this.getMimetypeForRendition()));
try
{
final FormsService fs = FormsService.getInstance();
root.put("xml", NodeModel.wrap(fs.parseXML(formInstanceDataNodeRef)));
root.put("xml", NodeModel.wrap(fs.parseXML(formInstanceData.getNodeRef())));
}
catch (Exception e)
{
LOGGER.error(e);
}
root.put("node", new TemplateNode(formInstanceDataNodeRef, sr, null));
root.put("node", new TemplateNode(formInstanceData.getNodeRef(), sr, null));
root.put("date", new SimpleDate(new Date(), SimpleDate.DATETIME));
final TemplateService templateService = sr.getTemplateService();
@@ -169,7 +177,9 @@ public class RenderingEngineTemplateImpl
outputPathPattern,
new SimpleHash(root));
final String parentAVMPath = AVMNodeConverter.SplitBase(formInstanceDataAVMPath)[0];
result = AVMConstants.buildAbsoluteAVMPath(parentAVMPath, result);
result = AVMConstants.buildAVMPath(parentAVMPath,
result,
AVMConstants.PathRelation.SANDBOX_RELATIVE);
LOGGER.debug("processed pattern " + outputPathPattern + " as " + result);
return result;
}
@@ -186,19 +196,19 @@ public class RenderingEngineTemplateImpl
WCMAppModel.PROP_MIMETYPE_FOR_RENDITION);
}
public void registerRendition(final NodeRef renditionNodeRef,
final NodeRef primaryFormInstanceDataNodeRef)
public void registerRendition(final Rendition rendition,
final FormInstanceData primaryFormInstanceData)
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
final Map<QName, Serializable> props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE, this.nodeRef);
// extract a store relative path for the primary form instance data
String path = AVMNodeConverter.ToAVMVersionPath(primaryFormInstanceDataNodeRef).getSecond();
String path = primaryFormInstanceData.getPath();
path = path.substring(path.indexOf(':') + 1);
props.put(WCMAppModel.PROP_PRIMARY_FORM_INSTANCE_DATA, path);
nodeService.addAspect(renditionNodeRef, WCMAppModel.ASPECT_RENDITION, props);
nodeService.addAspect(rendition.getNodeRef(), WCMAppModel.ASPECT_RENDITION, props);
}
private ServiceRegistry getServiceRegistry()

View File

@@ -27,12 +27,18 @@ import java.io.Serializable;
public interface Rendition
extends Serializable
{
/** the name of this instance data */
/** the name of this rendition */
public String getName();
/** the description of this rendition */
public String getDescription();
/** the path relative to the containing webapp */
public String getWebappRelativePath();
/** the path relative to the sandbox */
public String getSandboxRelativePath();
/** the primary form instance data used to generate this rendition */
public FormInstanceData getPrimaryFormInstanceData();

View File

@@ -16,8 +16,6 @@
*/
package org.alfresco.web.forms;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel;
@@ -64,15 +62,22 @@ public class RenditionImpl
nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME);
}
/** the path relative to the containing webapp */
/** the description of this rendition */
public String getDescription()
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
return (String)
nodeService.getProperty(this.nodeRef, ContentModel.PROP_DESCRIPTION);
}
public String getWebappRelativePath()
{
final String path = AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond();
final String p = ("[^:]+:/" + AVMConstants.DIR_APPBASE +
"/" + AVMConstants.DIR_WEBAPPS +
"/[^/]+(.*)/" + this.getName());
final Matcher m = Pattern.compile(p).matcher(path);
return m.matches() && m.group(1).length() != 0 ? m.group(1) : "/";
return AVMConstants.getWebappRelativePath(this.getPath());
}
public String getSandboxRelativePath()
{
return AVMConstants.getSandboxRelativePath(this.getPath());
}
public FormInstanceData getPrimaryFormInstanceData()
@@ -115,7 +120,7 @@ public class RenditionImpl
public String getUrl()
{
return AVMConstants.buildAVMAssetUrl(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond());
return AVMConstants.buildAVMAssetUrl(this.getPath());
}
public String getFileTypeImage()

View File

@@ -79,7 +79,9 @@ public class XSLTRenderingEngine
throws TransformerException
{
final XObject o = ec.getVariableOrParam(new QName(ALFRESCO_NS, ALFRESCO_NS_PREFIX, "parent_path"));
return o == null ? null : AVMConstants.buildAbsoluteAVMPath(o.toString(), path);
return o == null ? null : AVMConstants.buildAVMPath(o.toString(),
path,
AVMConstants.PathRelation.WEBAPP_RELATIVE);
}
/**

View File

@@ -434,8 +434,9 @@ public class XFormsBean
final String previewStorePath =
this.avmBrowseBean.getCurrentPath().replaceFirst(AVMConstants.STORE_MAIN,
AVMConstants.STORE_PREVIEW);
currentPath = AVMConstants.buildAbsoluteAVMPath(previewStorePath,
currentPath);
currentPath = AVMConstants.buildAVMPath(previewStorePath,
currentPath,
AVMConstants.PathRelation.WEBAPP_RELATIVE);
}
LOGGER.debug(this + ".getFilePickerData(" + currentPath + ")");
@@ -519,8 +520,9 @@ public class XFormsBean
final String previewStorePath =
this.avmBrowseBean.getCurrentPath().replaceFirst(AVMConstants.STORE_MAIN,
AVMConstants.STORE_PREVIEW);
currentPath = AVMConstants.buildAbsoluteAVMPath(previewStorePath,
item.getString());
currentPath = AVMConstants.buildAVMPath(previewStorePath,
item.getString(),
AVMConstants.PathRelation.WEBAPP_RELATIVE);
LOGGER.debug("currentPath is " + currentPath);
}
else