diff --git a/config/alfresco/web-client-application-context.xml b/config/alfresco/web-client-application-context.xml
index 1a3c05c9b8..f43f7ea6d2 100644
--- a/config/alfresco/web-client-application-context.xml
+++ b/config/alfresco/web-client-application-context.xml
@@ -57,6 +57,9 @@
+
+
+
diff --git a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java
index 22f49c72dd..6ffc782764 100644
--- a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java
+++ b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java
@@ -18,6 +18,8 @@ package org.alfresco.web.bean.wcm;
import java.text.MessageFormat;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.faces.context.FacesContext;
@@ -122,6 +124,44 @@ public final class AVMConstants
return dns;
}
+
+ /**
+ * Converts the provided path to an absolute path within the avm.
+ *
+ * @param parentAVMPath used as the parent path if the provided path
+ * is relative, otherwise used to extract the parent path portion up until
+ * the webapp directory.
+ * @param path a path relative to the parentAVMPath path, or if it is
+ * absolute, it is relative to the webapp used in the parentAVMPath.
+ *
+ * @return an absolute path within the avm using the paths provided.
+ */
+ public static String buildAbsoluteAVMPath(final String parentAVMPath, final String path)
+ {
+ String parent = parentAVMPath;
+ if (path == null || path.length() == 0 ||
+ ".".equals(path) || "./".equals(path))
+ {
+ return parent;
+ }
+
+ if (path.charAt(0) == '/')
+ {
+ final Pattern p = Pattern.compile("([^:]+:/" + AVMConstants.DIR_APPBASE +
+ "/[^/]+/[^/]+).*");
+ final Matcher m = p.matcher(parent);
+ if (m.matches())
+ {
+ parent = m.group(1);
+ }
+ }
+ else if (parent.charAt(parent.length() - 1) != '/')
+ {
+ parent = parent + '/';
+ }
+
+ return parent + path;
+ }
// names of the stores representing the layers for an AVM website
public final static String STORE_STAGING = "-staging";
diff --git a/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java
index b9d596c1a1..d2555fe07d 100644
--- a/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java
+++ b/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java
@@ -27,13 +27,16 @@ import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
+import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
+import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.model.FileInfo;
+import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
@@ -57,7 +60,8 @@ import org.w3c.dom.Document;
*
* @author arielb
*/
-public class CreateFormWizard extends BaseWizardBean
+public class CreateFormWizard
+ extends BaseWizardBean
{
/////////////////////////////////////////////////////////////////////////////
@@ -65,35 +69,35 @@ public class CreateFormWizard extends BaseWizardBean
/**
* Simple wrapper class to represent a form data renderer
*/
- public class RenderingEngineData
+ public class RenderingEngineTemplateData
{
private final String fileName;
private final File file;
- private final String fileExtension;
- private final String mimetype;
- private final Class renderingEngineType;
+ private final String mimetypeForRendition;
+ private final String outputPathPatternForRendition;
+ private final RenderingEngine renderingEngine;
- public RenderingEngineData(final String fileName,
- final File file,
- final String fileExtension,
- final String mimetype,
- final Class renderingEngineType)
+ public RenderingEngineTemplateData(final String fileName,
+ final File file,
+ final String outputPathPatternForRendition,
+ final String mimetypeForRendition,
+ final RenderingEngine renderingEngine)
{
this.fileName = fileName;
this.file = file;
- this.fileExtension = fileExtension;
- this.mimetype = mimetype;
- this.renderingEngineType = renderingEngineType;
+ this.outputPathPatternForRendition = outputPathPatternForRendition;
+ this.mimetypeForRendition = mimetypeForRendition;
+ this.renderingEngine = renderingEngine;
}
- public String getFileExtension()
+ public String getOutputPathPatternForRendition()
{
- return this.fileExtension;
+ return this.outputPathPatternForRendition;
}
- public String getMimetype()
+ public String getMimetypeForRendition()
{
- return this.mimetype;
+ return this.mimetypeForRendition;
}
public String getFileName()
@@ -106,20 +110,26 @@ public class CreateFormWizard extends BaseWizardBean
return this.file;
}
- public Class getRenderingEngineType()
+ public RenderingEngine getRenderingEngine()
{
- return this.renderingEngineType;
+ return this.renderingEngine;
}
-
- public String getRenderingEngineTypeName()
+
+ public String toString()
{
- return CreateFormWizard.this.getRenderingEngineTypeName(this.getRenderingEngineType());
+ return (this.getClass().getName() + "{" +
+ "fileName: " + this.getFileName() + "," +
+ "mimetypeForRendition: " + this.getMimetypeForRendition() + "," +
+ "outputPathPatternForRendition: " + this.getOutputPathPatternForRendition() + "," +
+ "renderingEngine: " + this.getRenderingEngine().getName() +
+ "}");
}
}
/////////////////////////////////////////////////////////////////////////////
- public static final String FILE_RENDERING_ENGINE = "rendering-engine";
+ public static final String FILE_RENDERING_ENGINE_TEMPLATE =
+ "rendering-engine-template";
public static final String FILE_SCHEMA = "schema";
@@ -129,22 +139,25 @@ public class CreateFormWizard extends BaseWizardBean
private String formName;
private String formTitle;
private String formDescription;
- private Class renderingEngineType = null;
+ private RenderingEngine renderingEngine = null;
protected ContentService contentService;
protected MimetypeService mimetypeService;
- private DataModel renderingEnginesDataModel;
- private List renderingEngines = null;
- private String fileExtension = null;
- private String mimetype = null;
+ private DataModel renderingEngineTemplatesDataModel;
+ private List renderingEngineTemplates = null;
+ private String outputPathPatternForFormInstanceData = null;
+ private String outputPathPatternForRendition = null;
+ private String mimetypeForRendition = null;
private List mimetypeChoices = null;
// ------------------------------------------------------------------------------
// Wizard implementation
@Override
- protected String finishImpl(FacesContext context, String outcome)
+ protected String finishImpl(final FacesContext context, final String outcome)
throws Exception
{
+ LOGGER.debug("creating form " + this.getFormName());
+
final FormsService ts = FormsService.getInstance();
// get the node ref of the node that will contain the content
final NodeRef contentFormsNodeRef = ts.getContentFormsNodeRef();
@@ -157,18 +170,12 @@ public class CreateFormWizard extends BaseWizardBean
this.fileFolderService.create(folderInfo.getNodeRef(),
this.getSchemaFileName(),
ContentModel.TYPE_CONTENT);
- final NodeRef schemaNodeRef = fileInfo.getNodeRef();
-
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Created file node for file: " +
- this.getSchemaFileName());
-
// get a writer for the content and put the file
- ContentWriter writer = this.contentService.getWriter(schemaNodeRef,
+ ContentWriter writer = this.contentService.getWriter(fileInfo.getNodeRef(),
ContentModel.PROP_CONTENT,
true);
// set the mimetype and encoding
- writer.setMimetype("text/xml");
+ writer.setMimetype(MimetypeMap.MIMETYPE_XML);
writer.setEncoding("UTF-8");
writer.putContent(this.getSchemaFile());
@@ -176,46 +183,74 @@ public class CreateFormWizard extends BaseWizardBean
Map props = new HashMap(2, 1.0f);
props.put(ContentModel.PROP_TITLE, this.getFormTitle());
props.put(ContentModel.PROP_DESCRIPTION, this.getFormDescription());
- this.nodeService.addAspect(schemaNodeRef, ContentModel.ASPECT_TITLED, props);
+ this.nodeService.addAspect(folderInfo.getNodeRef(), ContentModel.ASPECT_TITLED, props);
- props = new HashMap(1, 1.0f);
- props.put(WCMModel.PROP_SCHEMA_ROOT_ELEMENT_NAME, this.getSchemaRootElementName());
- this.nodeService.addAspect(schemaNodeRef, WCMModel.ASPECT_FORM, props);
+ props = new HashMap(3, 1.0f);
+ props.put(WCMModel.PROP_XML_SCHEMA, fileInfo.getNodeRef());
+ props.put(WCMModel.PROP_XML_SCHEMA_ROOT_ELEMENT_NAME,
+ this.getSchemaRootElementName());
+ props.put(WCMModel.PROP_OUTPUT_PATH_PATTERN_FOR_FORM_INSTANCE_DATA,
+ this.getOutputPathPatternForFormInstanceData());
+ this.nodeService.addAspect(folderInfo.getNodeRef(), WCMModel.ASPECT_FORM, props);
- for (RenderingEngineData tomd : this.renderingEngines)
+ for (RenderingEngineTemplateData retd : this.renderingEngineTemplates)
{
- fileInfo = this.fileFolderService.create(folderInfo.getNodeRef(),
- tomd.getFileName(),
- ContentModel.TYPE_CONTENT);
- final NodeRef renderingEngineNodeRef = fileInfo.getNodeRef();
-
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Created file node for file: " + tomd.getFileName());
-
- // get a writer for the content and put the file
- writer = this.contentService.getWriter(renderingEngineNodeRef,
- ContentModel.PROP_CONTENT,
- true);
- // set the mimetype and encoding
- writer.setMimetype("text/xml");
- writer.setEncoding("UTF-8");
- writer.putContent(tomd.getFile());
+ LOGGER.debug("adding rendering engine template " + retd +
+ " to form " + this.getFormName());
- this.nodeService.createAssociation(schemaNodeRef,
- renderingEngineNodeRef,
- WCMModel.ASSOC_RENDERING_ENGINES);
-
- props = new HashMap(3, 1.0f);
- props.put(WCMModel.PROP_RENDERING_ENGINE_TYPE,
- tomd.getRenderingEngineType().getName());
- props.put(WCMModel.PROP_FORM_SOURCE, schemaNodeRef);
- props.put(WCMModel.PROP_FILE_EXTENSION_FOR_RENDITION,
- tomd.getFileExtension());
+ NodeRef renderingEngineTemplateNodeRef =
+ this.fileFolderService.searchSimple(folderInfo.getNodeRef(), retd.getFileName());
+ if (renderingEngineTemplateNodeRef == null)
+ {
+ try
+ {
+ fileInfo = this.fileFolderService.create(folderInfo.getNodeRef(),
+ retd.getFileName(),
+ ContentModel.TYPE_CONTENT);
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Created file node for file: " + retd.getFileName());
+ renderingEngineTemplateNodeRef = fileInfo.getNodeRef();
+ }
+ catch (final FileExistsException fee)
+ {
+ LOGGER.error(fee.getName() + " already exists in " +
+ fee.getParentNodeRef());
+ throw fee;
+ }
+
+ // get a writer for the content and put the file
+ writer = this.contentService.getWriter(renderingEngineTemplateNodeRef,
+ ContentModel.PROP_CONTENT,
+ true);
+ // set the mimetype and encoding
+ // XXXarielb mime type of template isn't known
+ // writer.setMimetype("text/xml");
+ writer.setEncoding("UTF-8");
+ writer.putContent(retd.getFile());
+
+ this.nodeService.createAssociation(folderInfo.getNodeRef(),
+ renderingEngineTemplateNodeRef,
+ WCMModel.ASSOC_RENDERING_ENGINE_TEMPLATES);
+ props = new HashMap(2, 1.0f);
+ props.put(WCMModel.PROP_PARENT_RENDERING_ENGINE_NAME,
+ retd.getRenderingEngine().getName());
+ props.put(WCMModel.PROP_FORM_SOURCE, folderInfo.getNodeRef());
+ this.nodeService.addAspect(renderingEngineTemplateNodeRef,
+ WCMModel.ASPECT_RENDERING_ENGINE_TEMPLATE,
+ props);
+ }
+
+ LOGGER.debug("adding rendition properties to " + renderingEngineTemplateNodeRef);
+ props = new HashMap(2, 1.0f);
+ props.put(WCMModel.PROP_OUTPUT_PATH_PATTERN_FOR_RENDITION,
+ retd.getOutputPathPatternForRendition());
props.put(WCMModel.PROP_MIMETYPE_FOR_RENDITION,
- tomd.getMimetype());
- this.nodeService.addAspect(renderingEngineNodeRef,
- WCMModel.ASPECT_RENDERING_ENGINE,
- props);
+ retd.getMimetypeForRendition());
+ this.nodeService.createNode(renderingEngineTemplateNodeRef,
+ WCMModel.ASSOC_RENDITION_PROPERTIES,
+ WCMModel.ASSOC_RENDITION_PROPERTIES,
+ WCMModel.TYPE_RENDITION_PROPERTIES,
+ props);
}
// return the default outcome
return outcome;
@@ -227,22 +262,23 @@ public class CreateFormWizard extends BaseWizardBean
super.init(parameters);
this.removeUploadedSchemaFile();
- this.removeUploadedRenderingEngineFile();
+ this.removeUploadedRenderingEngineTemplateFile();
this.schemaRootElementName = null;
this.formName = null;
this.formTitle = null;
this.formDescription = null;
- this.renderingEngineType = null;
- this.renderingEngines = new ArrayList();
- this.fileExtension = null;
- this.mimetype = null;
+ this.renderingEngine = null;
+ this.renderingEngineTemplates = new ArrayList();
+ this.outputPathPatternForFormInstanceData = null;
+ this.outputPathPatternForRendition = null;
+ this.mimetypeForRendition = null;
}
@Override
public String cancel()
{
this.removeUploadedSchemaFile();
- this.removeUploadedRenderingEngineFile();
+ this.removeUploadedRenderingEngineTemplateFile();
return super.cancel();
}
@@ -274,89 +310,101 @@ public class CreateFormWizard extends BaseWizardBean
*/
public boolean getAddToListDisabled()
{
- return getRenderingEngineFileName() == null;
+ return this.getRenderingEngineTemplateFileName() == null;
}
/**
- * @return Returns the fileExtension.
+ * @return Returns the output path for the rendition.
*/
- public String getFileExtension()
+ public String getOutputPathPatternForRendition()
{
- if (this.fileExtension == null && this.mimetype != null)
+ if (this.outputPathPatternForRendition == null && this.mimetypeForRendition != null)
{
- this.fileExtension = this.mimetypeService.getExtension(this.mimetype);
+ this.outputPathPatternForRendition =
+ ("${formInstanceData.name}." +
+ this.mimetypeService.getExtension(this.mimetypeForRendition));
}
- return this.fileExtension;
+ return this.outputPathPatternForRendition;
}
/**
- * @param fileExtension The fileExtension to set.
+ * @param outputPathPatternForRendition The output path for the rendition.
*/
- public void setFileExtension(String fileExtension)
+ public void setOutputPathPatternForRendition(final String outputPathPatternForRendition)
{
- this.fileExtension = fileExtension;
+ this.outputPathPatternForRendition = outputPathPatternForRendition;
}
/**
* @return Returns the mimetype.
*/
- public String getMimetype()
+ public String getMimetypeForRendition()
{
- if (this.mimetype == null && this.fileExtension != null)
+ if (this.mimetypeForRendition == null && this.outputPathPatternForRendition != null)
{
- this.mimetype = this.mimetypeService.guessMimetype(this.fileExtension);
+ this.mimetypeForRendition =
+ this.mimetypeService.guessMimetype(this.outputPathPatternForRendition);
}
- return this.mimetype;
+ return this.mimetypeForRendition;
}
/**
* @param mimetype The mimetype to set.
*/
- public void setMimetype(String mimetype)
+ public void setMimetypeForRendition(final String mimetypeForRendition)
{
- this.mimetype = mimetype;
+ this.mimetypeForRendition = mimetypeForRendition;
}
/**
* Add the selected rendering engine to the list
*/
- public void addSelectedRenderingEngine(ActionEvent event)
+ public void addSelectedRenderingEngineTemplate(final ActionEvent event)
{
- for (RenderingEngineData tomd : this.renderingEngines)
+ for (RenderingEngineTemplateData retd : this.renderingEngineTemplates)
{
- if (tomd.getFileExtension().equals(this.fileExtension))
+ if (retd.getOutputPathPatternForRendition().equals(this.outputPathPatternForRendition))
{
- throw new AlfrescoRuntimeException("rendering engine with extension " + this.fileExtension +
+ throw new AlfrescoRuntimeException("rendering engine template with output path " + this.outputPathPatternForRendition +
" already exists");
}
}
- final RenderingEngineData data =
- this.new RenderingEngineData(this.getRenderingEngineFileName(),
- this.getRenderingEngineFile(),
- this.getFileExtension(),
- this.getMimetype(),
- this.renderingEngineType);
- this.renderingEngines.add(data);
- this.removeUploadedRenderingEngineFile();
- this.renderingEngineType = null;
- this.fileExtension = null;
- this.mimetype = null;
+ final RenderingEngineTemplateData data =
+ this.new RenderingEngineTemplateData(this.getRenderingEngineTemplateFileName(),
+ this.getRenderingEngineTemplateFile(),
+ this.getOutputPathPatternForRendition(),
+ this.getMimetypeForRendition(),
+ this.renderingEngine);
+ this.renderingEngineTemplates.add(data);
+ this.removeUploadedRenderingEngineTemplateFile();
+ this.renderingEngine = null;
+ this.outputPathPatternForRendition = null;
+ this.mimetypeForRendition = null;
}
/**
* Action handler called when the Remove button is pressed to remove a
* rendering engine
*/
- public void removeSelectedRenderingEngine(ActionEvent event)
+ public void removeSelectedRenderingEngineTemplate(final ActionEvent event)
{
- final RenderingEngineData wrapper = (RenderingEngineData)
- this.renderingEnginesDataModel.getRowData();
+ final RenderingEngineTemplateData wrapper = (RenderingEngineTemplateData)
+ this.renderingEngineTemplatesDataModel.getRowData();
if (wrapper != null)
{
- this.renderingEngines.remove(wrapper);
+ this.renderingEngineTemplates.remove(wrapper);
}
}
+
+ /**
+ * Action handler called when the user changes the selected mimetype
+ */
+ public String mimetypeForRenditionChanged(final ValueChangeEvent vce)
+ {
+ // refresh the current page
+ return null;
+ }
/**
* Action handler called when the user wishes to remove an uploaded file
@@ -372,9 +420,9 @@ public class CreateFormWizard extends BaseWizardBean
/**
* Action handler called when the user wishes to remove an uploaded file
*/
- public String removeUploadedRenderingEngineFile()
+ public String removeUploadedRenderingEngineTemplateFile()
{
- clearUpload(FILE_RENDERING_ENGINE);
+ clearUpload(FILE_RENDERING_ENGINE_TEMPLATE);
// refresh the current page
return null;
@@ -389,65 +437,58 @@ public class CreateFormWizard extends BaseWizardBean
*
* @return JSF DataModel representing the current configured output methods
*/
- public DataModel getRenderingEnginesDataModel()
+ public DataModel getRenderingEngineTemplatesDataModel()
{
- if (this.renderingEnginesDataModel == null)
+ if (this.renderingEngineTemplatesDataModel == null)
{
- this.renderingEnginesDataModel = new ListDataModel();
+ this.renderingEngineTemplatesDataModel = new ListDataModel();
}
- this.renderingEnginesDataModel.setWrappedData(this.renderingEngines);
+ this.renderingEngineTemplatesDataModel.setWrappedData(this.renderingEngineTemplates);
- return this.renderingEnginesDataModel;
+ return this.renderingEngineTemplatesDataModel;
}
/**
* @return Returns the mime type currenty selected
*/
- public String getRenderingEngineType()
+ public String getRenderingEngineName()
{
- if (this.renderingEngineType == null &&
- this.getRenderingEngineFileName() != null)
+ if (this.renderingEngine == null &&
+ this.getRenderingEngineTemplateFileName() != null)
{
- this.renderingEngineType =
- (this.getRenderingEngineFileName().endsWith(".xsl")
- ? XSLTRenderingEngine.class
- : (this.getRenderingEngineFileName().endsWith(".ftl")
- ? FreeMarkerRenderingEngine.class
- : (this.getRenderingEngineFileName().endsWith(".fo")
- ? XSLFORenderingEngine.class
- : null)));
+ final FormsService fs = FormsService.getInstance();
+ this.renderingEngine =
+ fs.guessRenderingEngine(this.getRenderingEngineTemplateFileName());
}
- return (this.renderingEngineType == null
+ return (this.renderingEngine == null
? null
- : this.renderingEngineType.getName());
+ : this.renderingEngine.getName());
}
/**
- * @param renderingEngineType Sets the currently selected mime type
+ * @param renderingEngineName Sets the currently selected rendering engine name
*/
- public void setRenderingEngineType(final String renderingEngineType)
- throws ClassNotFoundException
+ public void setRenderingEngineName(final String renderingEngineName)
{
- this.renderingEngineType = (renderingEngineType == null
- ? null
- : Class.forName(renderingEngineType));
+ final FormsService fs = FormsService.getInstance();
+ this.renderingEngine = (renderingEngineName == null
+ ? null
+ : fs.getRenderingEngine(renderingEngineName));
}
/**
* @return Returns a list of mime types to allow the user to select from
*/
- public List getRenderingEngineTypeChoices()
+ public List getRenderingEngineChoices()
{
- return (List)Arrays.asList(new SelectItem[]
+ final FormsService fs = FormsService.getInstance();
+ final List result = new LinkedList();
+ for (RenderingEngine re : fs.getRenderingEngines())
{
- new SelectItem(FreeMarkerRenderingEngine.class.getName(),
- getRenderingEngineTypeName(FreeMarkerRenderingEngine.class)),
- new SelectItem(XSLTRenderingEngine.class.getName(),
- getRenderingEngineTypeName(XSLTRenderingEngine.class)),
- new SelectItem(XSLFORenderingEngine.class.getName(),
- getRenderingEngineTypeName(XSLFORenderingEngine.class))
- });
+ result.add(new SelectItem(re.getName(), re.getName()));
+ }
+ return result;
}
/**
@@ -479,17 +520,6 @@ public class CreateFormWizard extends BaseWizardBean
return this.mimetypeChoices;
}
- private String getRenderingEngineTypeName(Class type)
- {
- return (FreeMarkerRenderingEngine.class.equals(type)
- ? "FreeMarker"
- : (XSLTRenderingEngine.class.equals(type)
- ? "XSLT"
- : (XSLFORenderingEngine.class.equals(type)
- ? "XSL-FO"
- : null)));
- }
-
private FileUploadBean getFileUploadBean(final String id)
{
final FacesContext ctx = FacesContext.getCurrentInstance();
@@ -540,17 +570,17 @@ public class CreateFormWizard extends BaseWizardBean
/**
* @return Returns the schema file or null
*/
- public String getRenderingEngineFileName()
+ public String getRenderingEngineTemplateFileName()
{
- return this.getFileName(FILE_RENDERING_ENGINE);
+ return this.getFileName(FILE_RENDERING_ENGINE_TEMPLATE);
}
/**
* @return Returns the rendering engine file or null
*/
- public File getRenderingEngineFile()
+ public File getRenderingEngineTemplateFile()
{
- return this.getFile(FILE_RENDERING_ENGINE);
+ return this.getFile(FILE_RENDERING_ENGINE_TEMPLATE);
}
/**
@@ -618,6 +648,25 @@ public class CreateFormWizard extends BaseWizardBean
? this.getSchemaFileName().replaceAll("(.+)\\..*", "$1")
: this.formName);
}
+ /**
+ * @return Returns the output path for form instance data.
+ */
+ public String getOutputPathPatternForFormInstanceData()
+ {
+ if (this.outputPathPatternForFormInstanceData == null)
+ {
+ this.outputPathPatternForFormInstanceData = "${formInstanceData.name}.xml";
+ }
+ return this.outputPathPatternForFormInstanceData;
+ }
+
+ /**
+ * @param outputPathPatternForFormInstanceData the output path for form instance data
+ */
+ public void setOutputPathPatternForFormInstanceData(final String outputPathPatternForFormInstanceData)
+ {
+ this.outputPathPatternForFormInstanceData = outputPathPatternForFormInstanceData;
+ }
/**
* Sets the title for this form.
@@ -659,16 +708,16 @@ public class CreateFormWizard extends BaseWizardBean
public String getSummary()
{
final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
- final String[] labels = new String[1 + this.renderingEngines.size()];
- final String[] values = new String[1 + this.renderingEngines.size()];
+ final String[] labels = new String[1 + this.renderingEngineTemplates.size()];
+ final String[] values = new String[1 + this.renderingEngineTemplates.size()];
labels[0] = "Schema File";
values[0] = this.getSchemaFileName();
- for (int i = 0; i < this.renderingEngines.size(); i++)
+ for (int i = 0; i < this.renderingEngineTemplates.size(); i++)
{
- final RenderingEngineData tomd = this.renderingEngines.get(i);
- labels[1 + i] = ("RenderingEngine for " + tomd.getFileExtension() +
- " mimetype " + tomd.getMimetype());
- values[1 + i] = tomd.getFileName();
+ final RenderingEngineTemplateData retd = this.renderingEngineTemplates.get(i);
+ labels[1 + i] = ("RenderingEngine for " + retd.getOutputPathPatternForRendition() +
+ " mimetype " + retd.getMimetypeForRendition());
+ values[1 + i] = retd.getFileName();
}
return this.buildSummary(labels, values);
@@ -681,7 +730,7 @@ public class CreateFormWizard extends BaseWizardBean
/**
* @param contentService The contentService to set.
*/
- public void setContentService(ContentService contentService)
+ public void setContentService(final ContentService contentService)
{
this.contentService = contentService;
}
@@ -689,7 +738,7 @@ public class CreateFormWizard extends BaseWizardBean
/**
* @param mimetypeService The mimetypeService to set.
*/
- public void setMimetypeService(MimetypeService mimetypeService)
+ public void setMimetypeService(final MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java
index d6641e09ca..88f07c9785 100644
--- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java
+++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java
@@ -102,22 +102,12 @@ public class CreateWebContentWizard extends BaseContentWizard
if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null)
{
- if (logger.isDebugEnabled())
- logger.debug("generating form data renderer output for " + this.formName);
final Form form = this.getForm();
- final FormsService fs = FormsService.getInstance();
final NodeRef formInstanceDataNodeRef =
AVMNodeConverter.ToNodeRef(-1, this.createdPath);
- final Map props = new HashMap(1, 1.0f);
- props.put(WCMModel.PROP_PARENT_FORM, form.getNodeRef());
- props.put(WCMModel.PROP_PARENT_FORM_NAME, form.getName());
- this.nodeService.addAspect(formInstanceDataNodeRef,
- WCMModel.ASPECT_FORM_INSTANCE_DATA,
- props);
- fs.generateRenditions(formInstanceDataNodeRef,
- fs.parseXML(this.content),
- form);
+ form.registerFormInstanceData(formInstanceDataNodeRef);
+ FormsService.getInstance().generateRenditions(formInstanceDataNodeRef);
}
// return the default outcome
@@ -137,7 +127,23 @@ public class CreateWebContentWizard extends BaseContentWizard
{
// get the parent path of the location to save the content
String path = this.avmBrowseBean.getCurrentPath();
-
+ if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null)
+ {
+ final FormsService fs = FormsService.getInstance();
+ final Document formInstanceData = (fileContent != null
+ ? fs.parseXML(fileContent)
+ : fs.parseXML(strContent));
+
+ path = this.getForm().getOutputPathForFormInstanceData(path, this.fileName, formInstanceData);
+ final String[] sb = AVMNodeConverter.SplitBase(path);
+ path = sb[0];
+ this.fileName = sb[1];
+ fs.makeAllDirectories(path);
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("creating file " + this.fileName + " in " + path);
+
// put the content of the file into the AVM store
if (fileContent != null)
{
@@ -193,16 +199,6 @@ public class CreateWebContentWizard extends BaseContentWizard
// ------------------------------------------------------------------------------
// Bean Getters and Setters
-
- /**
- * @param fileName The name of the file
- */
- public void setFileName(String fileName)
- {
- super.setFileName(fileName != null && fileName.indexOf('.') == -1
- ? fileName + ".xml"
- : fileName);
- }
/**
* @return Returns the content from the edited form.
@@ -219,7 +215,7 @@ public class CreateWebContentWizard extends BaseContentWizard
{
this.content = content;
}
-
+
/**
* @return the available forms that can be created.
*/
diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java
index 22f3301d10..690cb33c9d 100644
--- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java
+++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java
@@ -60,7 +60,7 @@ import org.alfresco.web.bean.wizard.BaseWizardBean;
import org.alfresco.web.bean.wizard.InviteUsersWizard.UserGroupRole;
import org.alfresco.web.forms.Form;
import org.alfresco.web.forms.FormsService;
-import org.alfresco.web.forms.RenderingEngine;
+import org.alfresco.web.forms.RenderingEngineTemplate;
import org.alfresco.web.ui.common.component.UIListItem;
import org.alfresco.web.ui.common.component.UISelectList;
import org.alfresco.web.ui.wcm.WebResources;
@@ -293,7 +293,7 @@ public class CreateWebsiteWizard extends BaseWizardBean
for (PresentationTemplate template : form.getTemplates())
{
props.clear();
- props.put(ContentModel.PROP_ENGINE, template.getRenderingEngine().getNodeRef());
+ props.put(ContentModel.PROP_ENGINE, template.getRenderingEngineTemplate().getNodeRef());
NodeRef templateRef = this.nodeService.createNode(formRef,
ContentModel.ASSOC_WEBFORMTEMPLATE,
ContentModel.ASSOC_WEBFORMTEMPLATE,
@@ -533,8 +533,7 @@ public class CreateWebsiteWizard extends BaseWizardBean
UIListItem item = new UIListItem();
item.setValue(form);
item.setLabel(form.getName());
- item.setDescription((String)this.nodeService.getProperty(
- form.getNodeRef(), ContentModel.PROP_DESCRIPTION));
+ item.setDescription(form.getDescription());
item.setImage(WebResources.IMAGE_WEBFORM_32);
items.add(item);
}
@@ -1083,29 +1082,27 @@ public class CreateWebsiteWizard extends BaseWizardBean
*/
public static class PresentationTemplate
{
- private RenderingEngine engine;
+ private RenderingEngineTemplate ret;
private String title;
private String description;
private String filenamePattern;
- public PresentationTemplate(RenderingEngine engine, String filenamePattern)
+ public PresentationTemplate(RenderingEngineTemplate ret, String filenamePattern)
{
- this.engine = engine;
+ this.ret = ret;
this.filenamePattern = filenamePattern;
}
- public RenderingEngine getRenderingEngine()
+ public RenderingEngineTemplate getRenderingEngineTemplate()
{
- return this.engine;
+ return this.ret;
}
public String getTitle()
{
if (this.title == null)
{
- this.title = (String)Repository.getServiceRegistry(
- FacesContext.getCurrentInstance()).getNodeService().getProperty(
- engine.getNodeRef(), ContentModel.PROP_NAME);
+ this.title = ret.getName();
}
return this.title;
}
@@ -1114,9 +1111,7 @@ public class CreateWebsiteWizard extends BaseWizardBean
{
if (this.description == null)
{
- this.description = (String)Repository.getServiceRegistry(
- FacesContext.getCurrentInstance()).getNodeService().getProperty(
- engine.getNodeRef(), ContentModel.PROP_DESCRIPTION);
+ this.description = ret.getDescription();
}
return this.description;
}
diff --git a/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java b/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java
index 9474eaaa11..90a28e9d64 100644
--- a/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java
+++ b/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java
@@ -30,7 +30,7 @@ import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.wcm.CreateWebsiteWizard.FormWrapper;
import org.alfresco.web.bean.wcm.CreateWebsiteWizard.PresentationTemplate;
import org.alfresco.web.forms.Form;
-import org.alfresco.web.forms.RenderingEngine;
+import org.alfresco.web.forms.RenderingEngineTemplate;
import org.alfresco.web.ui.common.component.UIListItem;
import org.alfresco.web.ui.common.component.UISelectList;
import org.alfresco.web.ui.wcm.WebResources;
@@ -126,9 +126,9 @@ public class FormTemplatesDialog extends BaseDialogBean
public List getTemplatesList()
{
Form form = getActionForm().getForm();
- List engines = form.getRenderingEngines();
+ List engines = form.getRenderingEngineTemplates();
List items = new ArrayList(engines.size());
- for (RenderingEngine engine : engines)
+ for (RenderingEngineTemplate engine : engines)
{
PresentationTemplate wrapper = new PresentationTemplate(engine, null);
UIListItem item = new UIListItem();
@@ -153,7 +153,7 @@ public class FormTemplatesDialog extends BaseDialogBean
{
PresentationTemplate template = (PresentationTemplate)this.templateList.get(index).getValue();
// clone the PresentationTemplate into one the user can modify
- this.templates.add(new PresentationTemplate(template.getRenderingEngine(), template.getFilenamePattern()));
+ this.templates.add(new PresentationTemplate(template.getRenderingEngineTemplate(), template.getFilenamePattern()));
}
}
diff --git a/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java b/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java
index 8afa6a6452..d521049616 100644
--- a/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java
+++ b/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java
@@ -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.WCMModel;
import org.alfresco.repo.avm.AVMRemote;
@@ -41,51 +39,8 @@ public abstract class AbstractRenderingEngine
protected static final String ALFRESCO_NS = "http://www.alfresco.org/alfresco";
protected static final String ALFRESCO_NS_PREFIX = "alfresco";
- private final NodeRef nodeRef;
- protected final NodeService nodeService;
- protected final ContentService contentService;
-
- protected AbstractRenderingEngine(final NodeRef nodeRef,
- final NodeService nodeService,
- final ContentService contentService)
+ protected AbstractRenderingEngine()
{
- this.nodeRef = nodeRef;
- this.nodeService = nodeService;
- this.contentService = contentService;
- }
-
- /**
- * Returns the node ref for the rendering engine template.
- *
- * @return the node ref for the rendering engine template.
- */
- public NodeRef getNodeRef()
- {
- return this.nodeRef;
- }
-
- /**
- * Returns the file extension to use for generated assets.
- *
- * @return the file extension to use for generated assets.
- */
- public String getFileExtensionForRendition()
- {
- return (String)
- this.nodeService.getProperty(this.nodeRef,
- WCMModel.PROP_FILE_EXTENSION_FOR_RENDITION);
- }
-
- /**
- * Returns the file extension to use for generated assets.
- *
- * @return the file extension to use for generated assets.
- */
- public String getMimetypeForRendition()
- {
- return (String)
- this.nodeService.getProperty(this.nodeRef,
- WCMModel.PROP_MIMETYPE_FOR_RENDITION);
}
protected static AVMRemote getAVMRemote()
@@ -101,48 +56,4 @@ public abstract class AbstractRenderingEngine
{
return new FormDataFunctions(AbstractRenderingEngine.getAVMRemote());
}
-
- /**
- * Converts the provided path to an absolute path within the avm.
- *
- * @param parentAVMPath used as the parent path if the provided path
- * is relative, otherwise used to extract the parent path portion up until
- * the webapp directory.
- * @param path a path relative to the parentAVMPath path, or if it is
- * absolute, it is relative to the webapp used in the parentAVMPath.
- *
- * @return an absolute path within the avm using the paths provided.
- */
- protected static String toAVMPath(final String parentAVMPath, final String path)
- {
- String parent = parentAVMPath;
- if (path == null ||
- path.length() == 0 ||
- ".".equals(path) ||
- "./".equals(path))
- {
- return parentAVMPath;
- }
-
- if (path.charAt(0) == '/')
- {
- final Pattern p = Pattern.compile("([^:]+:/" + AVMConstants.DIR_APPBASE +
- "/[^/]+/[^/]+).*");
- final Matcher m = p.matcher(parentAVMPath);
- if (m.matches())
- {
- parent = m.group(1);
- }
- }
- else if (parentAVMPath.charAt(parentAVMPath.length() - 1) != '/')
- {
- parent = parent + '/';
- }
-
- final String result = parent + path;
- LOGGER.debug("built full avmPath " + result +
- " for parent " + parentAVMPath +
- " and request path " + path);
- return result;
- }
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/web/forms/Form.java b/source/java/org/alfresco/web/forms/Form.java
index 7f111a3d66..d2605b1c90 100644
--- a/source/java/org/alfresco/web/forms/Form.java
+++ b/source/java/org/alfresco/web/forms/Form.java
@@ -18,6 +18,8 @@ package org.alfresco.web.forms;
import org.alfresco.service.cmr.repository.NodeRef;
import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.util.List;
@@ -31,16 +33,32 @@ public interface Form
extends Serializable
{
- /** the name of the template, which must be unique within the FormsService */
+ /** the name of the form, which must be unique within the FormsService */
public String getName();
+ /** the description of the form */
+ public String getDescription();
+
/** the root tag to use within the schema */
- public String getRootTagName();
+ public String getSchemaRootElementName();
/** the xml schema for this template type */
- public Document getSchema();
+ public Document getSchema()
+ throws IOException, SAXException;
- public NodeRef getNodeRef();
+ /**
+ * provides the output path for the form instance data based on the
+ * configured output path pattern.
+ *
+ * @param parentAVMPath the parent avm path
+ * @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,
+ final String formInstanceDataFileName,
+ final Document formInstanceData);
//XXXarielb not used currently and not sure if it's necessary...
// public void addInputMethod(final TemplateInputMethod in);
@@ -53,10 +71,17 @@ public interface Form
/**
* adds an output method to this template type.
*/
- public void addRenderingEngine(RenderingEngine output);
+ public void addRenderingEngineTemplate(RenderingEngineTemplate output);
/**
* Provides the set of output methods for this template.
*/
- public List getRenderingEngines();
+ public List getRenderingEngineTemplates();
+
+
+ /**
+ * Associates properties with the form instance data registering it as
+ * generated by this form.
+ */
+ public void registerFormInstanceData(final NodeRef formInstanceDataNodeRef);
}
diff --git a/source/java/org/alfresco/web/forms/FormDataFunctions.java b/source/java/org/alfresco/web/forms/FormDataFunctions.java
index 915275debc..6ee11bb196 100644
--- a/source/java/org/alfresco/web/forms/FormDataFunctions.java
+++ b/source/java/org/alfresco/web/forms/FormDataFunctions.java
@@ -113,11 +113,11 @@ public class FormDataFunctions
pv = this.avmRemote.getNodeProperty(-1,
avmPath + '/' + entryName,
- WCMModel.PROP_PARENT_RENDERING_ENGINE);
+ WCMModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE);
if (pv != null)
{
- // it's generated by a transformer (not the xml file)
+ // it's generated by a rendering engine (it's not the xml file)
continue;
}
diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java
index 1b6f79a439..2b0037040c 100644
--- a/source/java/org/alfresco/web/forms/FormImpl.java
+++ b/source/java/org/alfresco/web/forms/FormImpl.java
@@ -16,11 +16,28 @@
*/
package org.alfresco.web.forms;
+import freemarker.ext.dom.NodeModel;
+import freemarker.template.SimpleDate;
+import freemarker.template.SimpleHash;
+import freemarker.template.SimpleScalar;
+import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
import java.io.*;
import java.net.URI;
+import java.io.Serializable;
import java.util.*;
import org.alfresco.model.ContentModel;
+import org.alfresco.model.WCMModel;
+import org.alfresco.service.cmr.repository.AssociationRef;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+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.cmr.repository.TemplateService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.web.bean.wcm.AVMConstants;
import org.alfresco.web.forms.xforms.XFormsProcessor;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.apache.commons.logging.Log;
@@ -33,60 +50,116 @@ public class FormImpl
{
private static final Log LOGGER = LogFactory.getLog(FormImpl.class);
- private transient Document schema;
- private final NodeRef schemaNodeRef;
- private final String name;
- private final String rootTagName;
- private final LinkedList renderingEngines =
- new LinkedList();
+ private final NodeRef folderNodeRef;
+ private final NodeService nodeService;
+ private final ContentService contentService;
+ private final TemplateService templateService;
+
private final static LinkedList PROCESSORS =
new LinkedList();
-
static
{
- PROCESSORS.add(new XFormsProcessor());
+ FormImpl.PROCESSORS.add(new XFormsProcessor());
}
- public FormImpl(final String name,
- final NodeRef schemaNodeRef,
- final String rootTagName)
+ public FormImpl(final NodeRef folderNodeRef,
+ final NodeService nodeService,
+ final ContentService contentService,
+ final TemplateService templateService)
{
- this.name = name;
- this.schemaNodeRef = schemaNodeRef;
- this.rootTagName = rootTagName;
- }
-
- public String getName()
- {
- return this.name;
+ this.folderNodeRef = folderNodeRef;
+ this.nodeService = nodeService;
+ this.contentService = contentService;
+ this.templateService = templateService;
}
- public String getRootTagName()
+ public String getName()
{
- return this.rootTagName;
+ return (String)
+ this.nodeService.getProperty(this.folderNodeRef,
+ ContentModel.PROP_TITLE);
+ }
+
+ public String getDescription()
+ {
+ return (String)
+ this.nodeService.getProperty(this.folderNodeRef,
+ ContentModel.PROP_DESCRIPTION);
+ }
+
+ public String getOutputPathForFormInstanceData(final String parentAVMPath,
+ final String formInstanceDataFileName,
+ final Document formInstanceData)
+ {
+ final String outputPathPattern = (String)
+ this.nodeService.getProperty(this.folderNodeRef,
+ WCMModel.PROP_OUTPUT_PATH_PATTERN_FOR_FORM_INSTANCE_DATA);
+
+ final TemplateHashModel formInstanceDataModel = new TemplateHashModel()
+ {
+
+ private TemplateModel formInstanceDataModel;
+
+ public TemplateModel get(final String key)
+ {
+ LOGGER.debug("looking up property " + key);
+ if ("xml".equals(key))
+ {
+ try
+ {
+ if (formInstanceDataModel == null)
+ {
+ formInstanceDataModel = NodeModel.wrap(formInstanceData);
+ }
+ return formInstanceDataModel;
+ }
+ catch (Exception e)
+ {
+ LOGGER.error(e);
+ return null;
+ }
+ }
+ else if ("name".equals(key))
+ {
+ return new SimpleScalar(formInstanceDataFileName);
+ }
+ return null;
+ }
+
+ public boolean isEmpty()
+ {
+ return false;
+ }
+ };
+
+ final Map root = new HashMap();
+ root.put("formInstanceData", formInstanceDataModel);
+ root.put("date", new SimpleDate(new Date(), SimpleDate.DATETIME));
+
+ String result = templateService.processTemplateString(null,
+ outputPathPattern,
+ new SimpleHash(root));
+ result = AVMConstants.buildAbsoluteAVMPath(parentAVMPath, result);
+ LOGGER.debug("processed pattern " + outputPathPattern + " as " + result);
+ return result;
+ }
+
+ public String getSchemaRootElementName()
+ {
+ return (String)
+ this.nodeService.getProperty(folderNodeRef,
+ WCMModel.PROP_XML_SCHEMA_ROOT_ELEMENT_NAME);
}
public Document getSchema()
+ throws IOException,
+ SAXException
{
- if (this.schema == null)
- {
- final FormsService ts = FormsService.getInstance();
- try
- {
- //XXXarielb maybe cloneNode instead?
- return /* this.schema = */ ts.parseXML(this.schemaNodeRef);
- }
- catch (Exception e)
- {
- LOGGER.error(e);
- }
- }
- return this.schema;
- }
-
- public NodeRef getNodeRef()
- {
- return this.schemaNodeRef;
+ final FormsService ts = FormsService.getInstance();
+ final NodeRef schemaNodeRef = (NodeRef)
+ this.nodeService.getProperty(folderNodeRef,
+ WCMModel.PROP_XML_SCHEMA);
+ return ts.parseXML(schemaNodeRef);
}
public List getFormProcessors()
@@ -94,18 +167,57 @@ public class FormImpl
return PROCESSORS;
}
- public void addRenderingEngine(final RenderingEngine output)
+ public void addRenderingEngineTemplate(final RenderingEngineTemplate ret)
{
- this.renderingEngines.add(output);
+// this.renderingEngineTemplates.add(ret);
+ throw new UnsupportedOperationException();
}
- public List getRenderingEngines()
+ public List getRenderingEngineTemplates()
{
- return this.renderingEngines;
+ final List result = new ArrayList();
+ for (AssociationRef assoc : this.nodeService.getTargetAssocs(this.folderNodeRef,
+ WCMModel.ASSOC_RENDERING_ENGINE_TEMPLATES))
+ {
+ final NodeRef retNodeRef = assoc.getTargetRef();
+ for (ChildAssociationRef assoc2 : this.nodeService.getChildAssocs(retNodeRef,
+ WCMModel.ASSOC_RENDITION_PROPERTIES,
+ RegexQNamePattern.MATCH_ALL))
+ {
+ final NodeRef renditionPropertiesNodeRef = assoc2.getChildRef();
+
+ final RenderingEngineTemplate ret =
+ new RenderingEngineTemplateImpl(retNodeRef,
+ renditionPropertiesNodeRef,
+ this.nodeService,
+ this.contentService,
+ this.templateService);
+ LOGGER.debug("loaded rendering engine template " + ret);
+ result.add(ret);
+ }
+ }
+ return result;
+ }
+
+ public void registerFormInstanceData(final NodeRef formInstanceDataNodeRef)
+ {
+ final Map props = new HashMap(2, 1.0f);
+ props.put(WCMModel.PROP_PARENT_FORM, this.folderNodeRef);
+ props.put(WCMModel.PROP_PARENT_FORM_NAME, this.getName());
+ this.nodeService.addAspect(formInstanceDataNodeRef, WCMModel.ASPECT_FORM_INSTANCE_DATA, props);
}
public int hashCode()
{
return this.getName().hashCode();
}
+
+ public String toString()
+ {
+ return (this.getClass().getName() + "{" +
+ "name: " + this.getName() + "," +
+ "schemaRootElementName: " + this.getSchemaRootElementName() + "," +
+ "renderingEngineTemplates: " + this.getRenderingEngineTemplates() +
+ "}");
+ }
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java
index d6f97c7977..f66e91d68f 100644
--- a/source/java/org/alfresco/web/forms/FormsService.java
+++ b/source/java/org/alfresco/web/forms/FormsService.java
@@ -26,12 +26,12 @@ import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
-import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Stack;
import javax.faces.context.FacesContext;
import javax.xml.parsers.DocumentBuilder;
@@ -57,6 +57,7 @@ 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.cmr.repository.TemplateService;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
@@ -89,6 +90,13 @@ public final class FormsService
/** internal storage of forms, keyed by the form name */
private HashMap forms = new HashMap();
+
+ private static final RenderingEngine[] RENDERING_ENGINES = new RenderingEngine[]
+ {
+ new FreeMarkerRenderingEngine(),
+ new XSLTRenderingEngine(),
+ new XSLFORenderingEngine()
+ };
private final ContentService contentService;
private final NodeService nodeService;
@@ -97,6 +105,7 @@ public final class FormsService
private final NamespaceService namespaceService;
private final SearchService searchService;
private final AVMService avmService;
+ private final TemplateService templateService;
private NodeRef contentFormsNodeRef;
@@ -107,7 +116,8 @@ public final class FormsService
final DictionaryService dictionaryService,
final NamespaceService namespaceService,
final SearchService searchService,
- final AVMService avmService)
+ final AVMService avmService,
+ final TemplateService templateService)
{
this.contentService = contentService;
this.nodeService = nodeService;
@@ -116,6 +126,7 @@ public final class FormsService
this.namespaceService = namespaceService;
this.searchService = searchService;
this.avmService = avmService;
+ this.templateService = templateService;
if (INSTANCE == null)
INSTANCE = this;
}
@@ -126,6 +137,45 @@ public final class FormsService
return FormsService.INSTANCE;
}
+ /**
+ * Provides all registered rendering engines.
+ */
+ public RenderingEngine[] getRenderingEngines()
+ {
+ return FormsService.RENDERING_ENGINES;
+ }
+
+ /**
+ * Returns the rendering engine with the given name.
+ *
+ * @param name the name of the rendering engine.
+ *
+ * @return the rendering engine or null if not found.
+ */
+ public RenderingEngine getRenderingEngine(final String name)
+ {
+ for (RenderingEngine re : this.getRenderingEngines())
+ {
+ if (re.getName().equals(name))
+ {
+ return re;
+ }
+ }
+ return null;
+ }
+
+ public RenderingEngine guessRenderingEngine(final String fileName)
+ {
+ for (RenderingEngine re : this.getRenderingEngines())
+ {
+ if (fileName.endsWith(re.getDefaultTemplateFileExtension()))
+ {
+ return re;
+ }
+ }
+ return null;
+ }
+
/**
* @return the cached reference to the WCM Content Forms folder
*/
@@ -169,7 +219,7 @@ public final class FormsService
for (ResultSetRow row : rs)
{
final NodeRef nodeRef = row.getNodeRef();
- result.add(this.newForm(nodeRef));
+ result.add(this.getForm(nodeRef));
}
return result;
}
@@ -202,7 +252,7 @@ public final class FormsService
}
if (result == null && LOGGER.isDebugEnabled())
LOGGER.debug("unable to find tempalte type " + name);
- return result != null ? this.newForm(result) : null;
+ return result != null ? this.getForm(result) : null;
}
/**
@@ -213,114 +263,70 @@ public final class FormsService
* @return the form for the given node ref.
*/
public Form getForm(final NodeRef nodeRef)
- {
- return this.newForm(nodeRef);
- }
-
- /**
- * instantiate a form. for now this will always generate the
- * xforms implementation, but will at some point be configurable such that
- * the form processor type implementation can be configured for the system,
- * or specified in the gui.
- */
- private Form newForm(final NodeRef schemaNodeRef)
{
if (LOGGER.isDebugEnabled())
- LOGGER.debug("creating form for " + schemaNodeRef);
- final String title = (String)
- this.nodeService.getProperty(schemaNodeRef, ContentModel.PROP_TITLE);
+ LOGGER.debug("loading form for " + nodeRef);
+ final Form result = new FormImpl(nodeRef,
+ this.nodeService,
+ this.contentService,
+ this.templateService);
if (LOGGER.isDebugEnabled())
- LOGGER.debug("title is " + title);
- final String schemaRootTagName = (String)
- this.nodeService.getProperty(schemaNodeRef, WCMModel.PROP_SCHEMA_ROOT_ELEMENT_NAME);
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("root tag name is " + schemaRootTagName);
- final Form tt = new FormImpl(title, schemaNodeRef, schemaRootTagName);
- for (AssociationRef assoc : this.nodeService.getTargetAssocs(schemaNodeRef,
- WCMModel.ASSOC_RENDERING_ENGINES))
- {
- final NodeRef tomNodeRef = assoc.getTargetRef();
- try
- {
- final Class formDataRendererType =
- Class.forName((String)this.nodeService.getProperty(tomNodeRef,
- WCMModel.PROP_RENDERING_ENGINE_TYPE));
-
- final Constructor c = formDataRendererType.getConstructor(NodeRef.class, NodeService.class, ContentService.class);
- final RenderingEngine tom = (RenderingEngine)
- c.newInstance(tomNodeRef, this.nodeService, this.contentService);
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug("loaded form data renderer type " + tom.getClass().getName() +
- " for extension " + tom.getFileExtensionForRendition() +
- ", " + tomNodeRef);
- }
- tt.addRenderingEngine(tom);
- }
- catch (Exception e)
- {
- throw new AlfrescoRuntimeException(e.getMessage(), e);
- }
- }
- return tt;
+ LOGGER.debug("loaded form " + result);
+ return result;
}
/**
* Generates renditions for the provided formInstanceData.
*
* @param formInstanceDataNodeRef the noderef containing the form instance data
- * @param formInstanceData the parsed contents of the form.
- * @param form the form to use when generating renditions.
*/
- public void generateRenditions(final NodeRef formInstanceDataNodeRef,
- final Document formInstanceData,
- final Form form)
+ public void generateRenditions(final NodeRef formInstanceDataNodeRef)
throws IOException,
+ SAXException,
RenderingEngine.RenderingException
{
- final String formInstanceDataFileName = (String)
- nodeService.getProperty(formInstanceDataNodeRef, ContentModel.PROP_NAME);
- final String formInstanceDataAvmPath = AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
- final String parentPath = AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[0];
+ final Form form =
+ this.getForm((NodeRef)this.nodeService.getProperty(formInstanceDataNodeRef,
+ WCMModel.PROP_PARENT_FORM));
+ final Document formInstanceData = this.parseXML(formInstanceDataNodeRef);
- for (RenderingEngine re : form.getRenderingEngines())
+ final String formInstanceDataFileName = (String)
+ this.nodeService.getProperty(formInstanceDataNodeRef, ContentModel.PROP_NAME);
+ final String formInstanceDataAvmPath =
+ AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
+ LOGGER.debug("generating renditions for " + formInstanceDataAvmPath);
+
+ for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{
// get the node ref of the node that will contain the content
- final String renditionFileName =
- (this.stripExtension(formInstanceDataFileName) +
- "." + re.getFileExtensionForRendition());
- final OutputStream out = this.avmService.createFile(parentPath, renditionFileName);
- final String renditionAvmPath = parentPath + '/' + renditionFileName;
+ final String renditionAvmPath =
+ this.getOutputAvmPathForRendition(ret, formInstanceDataNodeRef);
+ final String parentAVMPath = AVMNodeConverter.SplitBase(renditionAvmPath)[0];
+ this.makeAllDirectories(parentAVMPath);
+ final OutputStream out = this.avmService.createFile(parentAVMPath,
+ AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " + renditionAvmPath);
final HashMap parameters =
- this.getRenderingEngineParameters(formInstanceDataFileName,
- renditionFileName,
- parentPath);
- re.render(formInstanceData, parameters, out);
+ this.getRenderingEngineParameters(formInstanceDataAvmPath,
+ renditionAvmPath);
+ ret.getRenderingEngine().render(formInstanceData, ret, parameters, out);
out.close();
final NodeRef renditionNodeRef =
- AVMNodeConverter.ToNodeRef(-1, parentPath + '/' + renditionFileName);
+ AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
- Map props = new HashMap(2, 1.0f);
- props.put(WCMModel.PROP_PARENT_FORM, form.getNodeRef());
- props.put(WCMModel.PROP_PARENT_FORM_NAME, form.getName());
- nodeService.addAspect(renditionNodeRef, WCMModel.ASPECT_FORM_INSTANCE_DATA, props);
+ form.registerFormInstanceData(renditionNodeRef);
+ ret.registerRendition(renditionNodeRef, formInstanceDataNodeRef);
- props = new HashMap(2, 1.0f);
- props.put(WCMModel.PROP_PARENT_RENDERING_ENGINE, re.getNodeRef());
- props.put(WCMModel.PROP_PRIMARY_FORM_INSTANCE_DATA, formInstanceDataNodeRef);
- nodeService.addAspect(renditionNodeRef, WCMModel.ASPECT_RENDITION, props);
-
- props = new HashMap(1, 1.0f);
- props.put(ContentModel.PROP_TITLE, renditionFileName);
+ Map props = new HashMap(1, 1.0f);
+ props.put(ContentModel.PROP_TITLE, AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
nodeService.addAspect(renditionNodeRef, ContentModel.ASPECT_TITLED, props);
if (LOGGER.isDebugEnabled())
- LOGGER.debug("generated " + renditionFileName + " using " + re);
+ LOGGER.debug("generated " + renditionAvmPath + " using " + ret);
}
}
@@ -346,56 +352,100 @@ public final class FormsService
// other parameter values passed to rendering engine
final String formInstanceDataAvmPath = AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
- final String parentPath = AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[0];
+ LOGGER.debug("regenerating renditions for " + formInstanceDataAvmPath);
- for (RenderingEngine re : form.getRenderingEngines())
+ for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{
- final String renditionFileName =
- (this.stripExtension(formInstanceDataFileName) + "." +
- re.getFileExtensionForRendition());
+ final String renditionAvmPath =
+ this.getOutputAvmPathForRendition(ret, formInstanceDataNodeRef);
if (LOGGER.isDebugEnabled())
LOGGER.debug("regenerating file node for : " + formInstanceDataFileName +
" (" + formInstanceDataNodeRef.toString() +
- ") to " + parentPath +
- "/" + renditionFileName);
+ ") to " + renditionAvmPath);
// get a writer for the content and put the file
OutputStream out = null;
try
{
- out = this.avmService.getFileOutputStream(parentPath + "/" + renditionFileName);
+ out = this.avmService.getFileOutputStream(renditionAvmPath);
}
catch (AVMNotFoundException e)
{
- out = this.avmService.createFile(parentPath, renditionFileName);
+ out = this.avmService.createFile(AVMNodeConverter.SplitBase(renditionAvmPath)[0],
+ AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
}
final HashMap parameters =
- this.getRenderingEngineParameters(formInstanceDataFileName,
- renditionFileName,
- parentPath);
- re.render(formInstanceData, parameters, out);
+ this.getRenderingEngineParameters(formInstanceDataAvmPath, renditionAvmPath);
+ ret.getRenderingEngine().render(formInstanceData, ret, parameters, out);
out.close();
if (LOGGER.isDebugEnabled())
- LOGGER.debug("generated " + renditionFileName + " using " + re);
+ LOGGER.debug("generated " + renditionAvmPath + " using " + ret);
}
}
- private static HashMap getRenderingEngineParameters(final String formInstanceDataFileName,
- final String renditionFileName,
- final String parentAvmPath)
+ private 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 getRenderingEngineParameters(final String formInstanceDataAvmPath,
+ final String renditionAvmPath)
{
final HashMap parameters = new HashMap();
- parameters.put("avm_sandbox_url", AVMConstants.buildAVMStoreUrl(parentAvmPath));
- parameters.put("form_instance_data_file_name", formInstanceDataFileName);
- parameters.put("rendition_file_name", renditionFileName);
- parameters.put("parent_path", parentAvmPath);
+ parameters.put("avm_sandbox_url", AVMConstants.buildAVMStoreUrl(formInstanceDataAvmPath));
+ parameters.put("form_instance_data_file_name", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[1]);
+ parameters.put("rendition_file_name", AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
+ parameters.put("parent_path", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[0]);
final FacesContext fc = FacesContext.getCurrentInstance();
parameters.put("request_context_path", fc.getExternalContext().getRequestContextPath());
return parameters;
}
+
+ // XXXarielb relocate
+ public void makeAllDirectories(final String avmDirectoryPath)
+ {
+ LOGGER.debug("mkdir -p " + avmDirectoryPath);
+ String s = avmDirectoryPath;
+ final Stack dirNames = new Stack();
+ while (s != null)
+ {
+ try
+ {
+ if (this.avmService.lookup(-1, s) != null)
+ {
+ LOGGER.debug("path " + s + " exists");
+ break;
+ }
+ }
+ catch (AVMNotFoundException avmfe)
+ {
+ }
+ final String[] sb = AVMNodeConverter.SplitBase(s);
+ s = sb[0];
+ LOGGER.debug("pushing " + sb[1]);
+ dirNames.push(sb);
+ }
+
+ while (!dirNames.isEmpty())
+ {
+ final String[] sb = dirNames.pop();
+ LOGGER.debug("creating " + sb[1] + " in " + sb[0]);
+ this.avmService.createDirectory(sb[0], sb[1]);
+ }
+ }
/** utility function for creating a document */
public Document newDocument()
diff --git a/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java b/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java
index 567ce7ae0c..61d586c2c9 100644
--- a/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java
+++ b/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java
@@ -29,6 +29,7 @@ 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.web.bean.wcm.AVMConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.chiba.xml.util.DOMUtil;
@@ -48,11 +49,19 @@ public class FreeMarkerRenderingEngine
private static final Log LOGGER = LogFactory.getLog(FreeMarkerRenderingEngine.class);
- public FreeMarkerRenderingEngine(final NodeRef nodeRef,
- final NodeService nodeService,
- final ContentService contentService)
+ public FreeMarkerRenderingEngine()
{
- super(nodeRef, nodeService, contentService);
+ super();
+ }
+
+ public String getName()
+ {
+ return "FreeMarker";
+ }
+
+ public String getDefaultTemplateFileExtension()
+ {
+ return "ftl";
}
/**
@@ -62,25 +71,26 @@ public class FreeMarkerRenderingEngine
* all parameters and all extension functions.
*/
public void render(final Document xmlContent,
+ final RenderingEngineTemplate ret,
final Map parameters,
final OutputStream out)
throws IOException,
RenderingEngine.RenderingException
{
- final ContentReader contentReader =
- this.contentService.getReader(this.getNodeRef(), ContentModel.TYPE_CONTENT);
- final Reader reader = new InputStreamReader(contentReader.getContentInputStream());
+
final Configuration cfg = new Configuration();
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
-
- final Template t = new Template("freemarker_template", reader, cfg);
+
+ final Template t = new Template("freemarker_template",
+ new InputStreamReader(ret.getInputStream()),
+ cfg);
// wrap the xml instance in a model
final TemplateHashModel instanceDataModel = NodeModel.wrap(xmlContent);
// build models for each of the extension functions
final HashMap methodModels =
- new HashMap(3, 1.0f);
+ new HashMap(3, 1.0f);
methodModels.put("parseXMLDocument", new TemplateMethodModel()
{
public Object exec(final List args)
@@ -89,8 +99,8 @@ public class FreeMarkerRenderingEngine
try
{
final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions();
- final String path = FreeMarkerRenderingEngine.toAVMPath(parameters.get("parent_path"),
- (String)args.get(0));
+ final String path = AVMConstants.buildAbsoluteAVMPath(parameters.get("parent_path"),
+ (String)args.get(0));
final Document d = ef.parseXMLDocument(path);
return d != null ? d.getDocumentElement() : null;
}
@@ -110,8 +120,8 @@ public class FreeMarkerRenderingEngine
{
final FormDataFunctions ef = FreeMarkerRenderingEngine.getFormDataFunctions();
final String path =
- FreeMarkerRenderingEngine.toAVMPath(parameters.get("parent_path"),
- args.size() == 1 ? "" : (String)args.get(1));
+ AVMConstants.buildAbsoluteAVMPath(parameters.get("parent_path"),
+ args.size() == 1 ? "" : (String)args.get(1));
final Map resultMap = ef.parseXMLDocuments((String)args.get(0), path);
LOGGER.debug("received " + resultMap.size() + " documents in " + path);
@@ -156,8 +166,8 @@ public class FreeMarkerRenderingEngine
{
try
{
- return FreeMarkerRenderingEngine.toAVMPath(parameters.get("parent_path"),
- (String)args.get(0));
+ return AVMConstants.buildAbsoluteAVMPath(parameters.get("parent_path"),
+ (String)args.get(0));
}
catch (Exception e)
{
diff --git a/source/java/org/alfresco/web/forms/RenderingEngine.java b/source/java/org/alfresco/web/forms/RenderingEngine.java
index 083fc7fb30..922fa1d901 100644
--- a/source/java/org/alfresco/web/forms/RenderingEngine.java
+++ b/source/java/org/alfresco/web/forms/RenderingEngine.java
@@ -50,42 +50,35 @@ public interface RenderingEngine
/////////////////////////////////////////////////////////////////////////////
- /**
- * XXXarielb this shouldn't be in the interface... i'll figure out a
- * different id scheme once i make rendering engines configurable.
+ /**
+ * Returns the rendering engines name.
*
- * the noderef associated with this output method
+ * @return the name of the rendering engine.
*/
- public NodeRef getNodeRef();
+ public String getName();
+
+
+ /**
+ * Returns the default file extension for rendering engine templates for this
+ * rendering engine.
+ *
+ * @return the default file extension for rendering engine templates for this
+ * rendering engine.
+ */
+ public String getDefaultTemplateFileExtension();
/**
* Renders the xml data in to a presentation format.
*
- * @param formInstanceData the xml content to serialize
+ * @param formInstanceData the xml content to serialize.
+ * @param ret the rendering engine template
* @param form the form that collected the xml content.
* @param parameters the set of parameters to the rendering engine
* @param out the output stream to serialize to.
*/
public void render(final Document formInstanceData,
+ final RenderingEngineTemplate ret,
final Map parameters,
final OutputStream out)
throws IOException, RenderingException;
-
- /**
- * Returns the file extension to use when generating content for this
- * output method.
- *
- * @return the file extension to use when generating content for this
- * output method, such as html, xml, pdf.
- */
- public String getFileExtensionForRendition();
-
- /**
- * Returns the mimetype to use when generating content for this
- * output method.
- *
- * @return the mimetype to use when generating content for this
- * output method, such as text/html, text/xml, application/pdf.
- */
- public String getMimetypeForRendition();
}
diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java
new file mode 100644
index 0000000000..80122fc9c6
--- /dev/null
+++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java
@@ -0,0 +1,81 @@
+/*
+ * 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.forms;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Map;
+import org.w3c.dom.Document;
+
+/**
+ * Describes a template that is used for rendering form instance data.
+ *
+ * @author Ariel Backenroth
+ */
+public interface RenderingEngineTemplate
+ extends Serializable
+{
+ /** the name of the form, which must be unique within the FormsService */
+ public String getName();
+
+ /** the description of the form */
+ public String getDescription();
+
+ /**
+ * Provides the rendering engine to use to process this template.
+ *
+ * @return the rendering engine to use to process this template.
+ */
+ public RenderingEngine getRenderingEngine();
+
+ /**
+ * Provides the noderef for this template.
+ *
+ * @return the noderef for this template.
+ * @deprecated i'd rather not expose this
+ */
+ public NodeRef getNodeRef();
+
+ /**
+ * Provides an input stream to the rendering engine template.
+ *
+ * @return the input stream to the rendering engine template.
+ */
+ public InputStream getInputStream()
+ throws IOException;
+
+ /**
+ * Returns the output path for the rendition.
+ *
+ * @return the output path for the rendition.
+ */
+ public String getOutputPathForRendition(final NodeRef formInstanceDataNodeRef);
+
+ /**
+ * Returns the mimetype to use when generating content for this
+ * output method.
+ *
+ * @return the mimetype to use when generating content for this
+ * output method, such as text/html, text/xml, application/pdf.
+ */
+ public String getMimetypeForRendition();
+
+ public void registerRendition(final NodeRef rendition, final NodeRef primaryFormInstanceData);
+}
diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java
new file mode 100644
index 0000000000..a0ce41414c
--- /dev/null
+++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java
@@ -0,0 +1,213 @@
+/*
+ * 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.forms;
+
+import freemarker.ext.dom.NodeModel;
+import freemarker.template.SimpleDate;
+import freemarker.template.SimpleHash;
+import freemarker.template.SimpleScalar;
+import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import org.alfresco.model.ContentModel;
+import org.alfresco.model.WCMModel;
+import org.alfresco.repo.avm.AVMNodeConverter;
+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.cmr.repository.TemplateService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.web.bean.wcm.AVMConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Implementation of a rendering engine template
+ */
+public class RenderingEngineTemplateImpl
+ implements RenderingEngineTemplate
+{
+ private static final Log LOGGER = LogFactory.getLog(RenderingEngineTemplateImpl.class);
+
+ private final NodeRef nodeRef;
+ private final NodeRef renditionPropertiesNodeRef;
+ private final NodeService nodeService;
+ private final ContentService contentService;
+ private final TemplateService templateService;
+
+ protected RenderingEngineTemplateImpl(final NodeRef nodeRef,
+ final NodeRef renditionPropertiesNodeRef,
+ final NodeService nodeService,
+ final ContentService contentService,
+ final TemplateService templateService)
+ {
+ this.nodeRef = nodeRef;
+ this.renditionPropertiesNodeRef = renditionPropertiesNodeRef;
+ this.nodeService = nodeService;
+ this.contentService = contentService;
+ this.templateService = templateService;
+ }
+
+ public String getName()
+ {
+ return (String)
+ this.nodeService.getProperty(this.nodeRef,
+ ContentModel.PROP_TITLE);
+ }
+
+ public String getDescription()
+ {
+ return (String)
+ this.nodeService.getProperty(this.nodeRef,
+ ContentModel.PROP_DESCRIPTION);
+ }
+
+ public NodeRef getNodeRef()
+ {
+ return this.nodeRef;
+ }
+
+ /**
+ * Provides an input stream to the rendering engine template.
+ *
+ * @return the input stream to the rendering engine template.
+ */
+ public InputStream getInputStream()
+ throws IOException
+ {
+ final ContentReader contentReader =
+ this.contentService.getReader(this.nodeRef, ContentModel.TYPE_CONTENT);
+ return contentReader.getContentInputStream();
+ }
+
+ /**
+ * Provides the rendering engine to use when processing this template.
+ *
+ * @return the rendering engine to use when processing this template.
+ */
+ public RenderingEngine getRenderingEngine()
+ {
+ final String renderingEngineName = (String)
+ this.nodeService.getProperty(this.nodeRef,
+ WCMModel.PROP_PARENT_RENDERING_ENGINE_NAME);
+ final FormsService fs = FormsService.getInstance();
+ return fs.getRenderingEngine(renderingEngineName);
+ }
+
+ /**
+ * Returns the output path to use for renditions.
+ *
+ * @return the output path to use for renditions.
+ */
+ public String getOutputPathForRendition(final NodeRef formInstanceDataNodeRef)
+ {
+ final String outputPathPattern = (String)
+ this.nodeService.getProperty(this.renditionPropertiesNodeRef,
+ WCMModel.PROP_OUTPUT_PATH_PATTERN_FOR_RENDITION);
+ final String formInstanceDataAVMPath =
+ AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
+
+ final TemplateHashModel formInstanceDataModel = new TemplateHashModel()
+ {
+
+ private TemplateModel formInstanceDataModel;
+
+ public TemplateModel get(final String key)
+ {
+ LOGGER.debug("looking up property " + key);
+ if ("xml".equals(key))
+ {
+ try
+ {
+ if (formInstanceDataModel == null)
+ {
+ final FormsService fs = FormsService.getInstance();
+ final Document formInstanceData = fs.parseXML(formInstanceDataNodeRef);
+ formInstanceDataModel = NodeModel.wrap(formInstanceData);
+ }
+ return formInstanceDataModel;
+ }
+ catch (Exception e)
+ {
+ LOGGER.error(e);
+ return null;
+ }
+ }
+ else
+ {
+ final Map properties =
+ nodeService.getProperties(formInstanceDataNodeRef);
+ for (QName qname : properties.keySet())
+ {
+ if (qname.getLocalName().equals(key))
+ {
+ return new SimpleScalar((String)properties.get(qname));
+ }
+ }
+ }
+ return null;
+ }
+
+ public boolean isEmpty()
+ {
+ return false;
+ }
+ };
+
+ final Map root = new HashMap();
+ root.put("formInstanceData", formInstanceDataModel);
+ root.put("date", new SimpleDate(new Date(), SimpleDate.DATETIME));
+
+ String result = templateService.processTemplateString(null,
+ outputPathPattern,
+ new SimpleHash(root));
+ final String parentAVMPath = AVMNodeConverter.SplitBase(formInstanceDataAVMPath)[0];
+ result = AVMConstants.buildAbsoluteAVMPath(parentAVMPath, result);
+ LOGGER.debug("processed pattern " + outputPathPattern + " as " + result);
+ return result;
+ }
+
+ /**
+ * Returns the mime type to use for generated assets.
+ *
+ * @return the mime type to use for generated assets.
+ */
+ public String getMimetypeForRendition()
+ {
+ return (String)
+ this.nodeService.getProperty(this.renditionPropertiesNodeRef,
+ WCMModel.PROP_MIMETYPE_FOR_RENDITION);
+ }
+
+ public void registerRendition(final NodeRef renditionNodeRef,
+ final NodeRef primaryFormInstanceDataNodeRef)
+ {
+ final Map props = new HashMap(2, 1.0f);
+ props.put(WCMModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE, this.nodeRef);
+ props.put(WCMModel.PROP_PRIMARY_FORM_INSTANCE_DATA, primaryFormInstanceDataNodeRef);
+ this.nodeService.addAspect(renditionNodeRef, WCMModel.ASPECT_RENDITION, props);
+ }
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java b/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java
index dded5102b5..ff19168eeb 100644
--- a/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java
+++ b/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java
@@ -49,14 +49,23 @@ public class XSLFORenderingEngine
private static final Log LOGGER = LogFactory.getLog(XSLFORenderingEngine.class);
- public XSLFORenderingEngine(final NodeRef nodeRef,
- final NodeService nodeService,
- final ContentService contentService)
+ public XSLFORenderingEngine()
{
- super(nodeRef, nodeService, contentService);
+ super();
+ }
+
+ public String getName()
+ {
+ return "XSL-FO";
+ }
+
+ public String getDefaultTemplateFileExtension()
+ {
+ return "fo";
}
public void render(final Document xmlContent,
+ final RenderingEngineTemplate ret,
final Map parameters,
final OutputStream out)
throws IOException,
@@ -67,7 +76,7 @@ public class XSLFORenderingEngine
{
final FopFactory fopFactory = FopFactory.newInstance();
final FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
- final Fop fop = fopFactory.newFop(this.getMimetypeForRendition(),
+ final Fop fop = fopFactory.newFop(ret.getMimetypeForRendition(),
foUserAgent,
out);
// Resulting SAX events (the generated FO) must be piped through to FOP
@@ -79,7 +88,6 @@ public class XSLFORenderingEngine
throw new RenderingEngine.RenderingException(fope);
}
- super.render(new DOMSource(xmlContent), parameters, result);
-
+ super.render(new DOMSource(xmlContent), ret, parameters, result);
}
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java
index f08f902370..11a07dbb22 100644
--- a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java
+++ b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java
@@ -35,6 +35,7 @@ import javax.xml.transform.stream.StreamSource;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.web.bean.wcm.AVMConstants;
import org.alfresco.web.forms.FormsService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -59,18 +60,26 @@ public class XSLTRenderingEngine
private static final Log LOGGER = LogFactory.getLog(XSLTRenderingEngine.class);
- public XSLTRenderingEngine(final NodeRef nodeRef,
- final NodeService nodeService,
- final ContentService contentService)
+ public XSLTRenderingEngine()
{
- super(nodeRef, nodeService, contentService);
+ super();
+ }
+
+ public String getName()
+ {
+ return "XSLT";
+ }
+
+ public String getDefaultTemplateFileExtension()
+ {
+ return "xsl";
}
protected static String toAVMPath(final ExpressionContext ec, String path)
throws TransformerException
{
final XObject o = ec.getVariableOrParam(new QName(ALFRESCO_NS, ALFRESCO_NS_PREFIX, "parent_path"));
- return o == null ? null : XSLTRenderingEngine.toAVMPath(o.toString(), path);
+ return o == null ? null : AVMConstants.buildAbsoluteAVMPath(o.toString(), path);
}
/**
@@ -276,15 +285,17 @@ public class XSLTRenderingEngine
}
public void render(final Document formInstanceData,
+ final RenderingEngineTemplate ret,
final Map parameters,
final OutputStream out)
throws IOException,
RenderingEngine.RenderingException
{
- this.render(new DOMSource(formInstanceData), parameters, new StreamResult(out));
+ this.render(new DOMSource(formInstanceData), ret, parameters, new StreamResult(out));
}
protected void render(final Source formInstanceDataSource,
+ final RenderingEngineTemplate ret,
final Map parameters,
final Result result)
throws IOException,
@@ -296,7 +307,7 @@ public class XSLTRenderingEngine
Document xslTemplate = null;
try
{
- xslTemplate = ts.parseXML(this.getNodeRef());
+ xslTemplate = ts.parseXML(ret.getInputStream());
}
catch (final SAXException sax)
{
diff --git a/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java b/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java
index 5dadbc5069..6a14f69372 100644
--- a/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java
+++ b/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java
@@ -1175,15 +1175,6 @@ public class SchemaFormBuilder
pathToRoot,
relative,
checkIfExtension);
-
- Element realModel = modelSection;
- if (relative)
- {
- //modelSection: find the last element put in the modelSection = bind
- realModel = DOMUtil.getLastChildElement(modelSection);
- }
-
- this.endFormGroup(groupElement, controlType, o, realModel);
}
private void addComplexTypeChildren(final Document xForm,
@@ -2265,18 +2256,18 @@ public class SchemaFormBuilder
bindElement = this.startBindElement(bindElement, schema, controlType, owner, pathToRoot, o);
// add a group if a repeat !
- if (owner instanceof XSElementDeclaration && o.maximum != 1)
- {
- Element groupElement = this.createGroup(xForm,
- modelSection,
- formSection,
- (XSElementDeclaration) owner);
- //set content
- Element groupWrapper = groupElement;
- if (groupElement != modelSection)
- groupWrapper = this.wrapper.createGroupContentWrapper(groupElement);
- formSection = groupWrapper;
- }
+// if (owner instanceof XSElementDeclaration && o.maximum != 1)
+// {
+// Element groupElement = this.createGroup(xForm,
+// modelSection,
+// formSection,
+// (XSElementDeclaration) owner);
+// //set content
+// Element groupWrapper = groupElement;
+// if (groupElement != modelSection)
+// groupWrapper = this.wrapper.createGroupContentWrapper(groupElement);
+// formSection = groupWrapper;
+// }
//eventual repeat
final Element repeatSection = this.addRepeatIfNecessary(xForm,
@@ -3303,18 +3294,6 @@ public class SchemaFormBuilder
{
}
- /**
- * __UNDOCUMENTED__
- *
- * @param groupElement __UNDOCUMENTED__
- */
- public void endFormGroup(final Element groupElement,
- final XSTypeDefinition controlType,
- final Occurs o,
- final Element modelSection)
- {
- }
-
/**
* This method is invoked after an xforms:bind element is created for the specified SimpleType.
* The implementation is responsible for setting setting any/all bind attributes
diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java
index a74e5d0e22..610a146f75 100644
--- a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java
+++ b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java
@@ -53,6 +53,7 @@ import org.w3c.dom.ls.*;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
+import org.xml.sax.SAXException;
/**
* Bean for interacting with the chiba processor from the ui using ajax requests.
@@ -151,6 +152,14 @@ public class XFormsBean
{
LOGGER.error(fbe);
}
+ catch (IOException ioe)
+ {
+ LOGGER.error(ioe);
+ }
+ catch (SAXException saxe)
+ {
+ LOGGER.error(saxe);
+ }
}
/**
@@ -348,7 +357,9 @@ public class XFormsBean
final Form tt,
final String cwdAvmPath,
final HttpServletRequest request)
- throws FormBuilderException
+ throws FormBuilderException,
+ IOException,
+ SAXException
{
final Document schemaDocument = tt.getSchema();
this.rewriteInlineURIs(schemaDocument, cwdAvmPath);
@@ -365,7 +376,7 @@ public class XFormsBean
LOGGER.debug("building xform for schema " + tt.getName());
final Document result = builder.buildForm(xmlContent,
schemaDocument,
- tt.getRootTagName());
+ tt.getSchemaRootElementName());
LOGGER.debug("generated xform: " + result);
// LOGGER.debug(ts.writeXMLToString(result));
return result;
diff --git a/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp b/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp
index 0ca938b285..da6f8db455 100644
--- a/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp
+++ b/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp
@@ -47,41 +47,52 @@
-
-
+
<%
final FileUploadBean upload = (FileUploadBean)
- session.getAttribute(FileUploadBean.getKey(CreateFormWizard.FILE_RENDERING_ENGINE));
+ session.getAttribute(FileUploadBean.getKey(CreateFormWizard.FILE_RENDERING_ENGINE_TEMPLATE));
if (upload == null || upload.getFile() == null)
{
%>
-
+
-
+
-
<%
}
else
{
%>
+ value="#{WizardManager.bean.renderingEngineTemplateFileName}"/>
+
+
<%
}
%>
+
+
+ value="#{WizardManager.bean.renderingEngineName}">
+ value="#{WizardManager.bean.renderingEngineChoices}"/>
+ valueChangeListener="#{WizardManager.bean.mimetypeForRenditionChanged}"
+ value="#{WizardManager.bean.mimetypeForRendition}">
@@ -99,31 +111,31 @@ else
+ value="#{WizardManager.bean.outputPathPatternForRendition}"
+ style="width:100%;"/>
-
-
+ rendered="#{WizardManager.bean.renderingEngineTemplatesDataModel.rowCount != 0}">
@@ -134,29 +146,29 @@ else
-
+
-
+
-
+
-
+
-
-
+
+
+
+
+
+
-
+
<%
FileUploadBean upload = (FileUploadBean)
session.getAttribute(FileUploadBean.getKey("schema"));
if (upload == null || upload.getFile() == null)
{
%>
-
-
-
-
-
+
+
+
+
+
<%
} else {
%>
-
-
-
+
+
+
<%
}
%>
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+