- Create Web Content action (HTML and plain text) now creates content in the current AVM store
   - TODO: create in the correct sub-folder
 - Refactoring of the modified Create Content Wizard into a new wizard Create Web Content Wizard
   - Integrated XML form templating into the current website AVM path (still needs some testing/fixing up…)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3867 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2006-09-20 17:59:58 +00:00
parent 9fe7ccf523
commit ae0a118985
12 changed files with 699 additions and 650 deletions

View File

@@ -825,6 +825,8 @@ delete_folder=Delete Folder
delete_avm_folder_info=To remove this folder and its contents from the sandbox, click OK.
delete_avm_folder_confirm=Are you sure you want to remove \"{0}\" and its contents from the sandbox?
error_delete_folder=Unable to delete Folder due to system error:
create_web_content_title=Create Web Content Wizard
create_web_content_desc=This wizard helps you to create a new content item for a website.
# New User Wizard messages
new_user_title=New User Wizard

View File

@@ -178,7 +178,7 @@
<!-- Definition of the Create Web Content wizard -->
<wizard name="createWebContent" managed-bean="CreateWebContentWizard"
title-id="create_content_title" description-id="create_content_desc"
title-id="create_web_content_title" description-id="create_web_content_desc"
icon="/images/icons/new_content_large.gif">
<step name="details" title-id="details" description-id="create_content_step1_desc">
<page path="/jsp/wcm/create-web-content-wizard/details.jsp"

View File

@@ -46,8 +46,6 @@ import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.templating.OutputUtil;
import org.alfresco.web.templating.TemplatingService;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.apache.commons.logging.Log;
@@ -641,14 +639,6 @@ public class CheckinCheckoutBean
// commit the transaction
tx.commit();
if (nodeService.getProperty(node.getNodeRef(),
TemplatingService.TT_QNAME) != null)
{
OutputUtil.regenerate(node.getNodeRef(),
this.contentService,
this.nodeService);
}
// clean up and clear action context
clearUpload();
setDocument(null);

View File

@@ -334,7 +334,16 @@ public abstract class BaseContentWizard extends BaseWizardBean
protected void saveContent(File fileContent, String strContent) throws Exception
{
// get the node ref of the node that will contain the content
NodeRef containerNodeRef = getContainerNodeRef();
NodeRef containerNodeRef;
String nodeId = this.navigator.getCurrentNodeId();
if (nodeId == null)
{
containerNodeRef = this.nodeService.getRootNode(Repository.getStoreRef());
}
else
{
containerNodeRef = new NodeRef(Repository.getStoreRef(), nodeId);
}
FileInfo fileInfo = this.fileFolderService.create(
containerNodeRef,

View File

@@ -57,87 +57,94 @@ import org.xml.sax.SAXException;
*/
public class CreateXmlContentTypeWizard extends BaseWizardBean
{
private final static Log LOGGER =
LogFactory.getLog(CreateXmlContentTypeWizard.class);
private final static Log LOGGER =
LogFactory.getLog(CreateXmlContentTypeWizard.class);
private String presentationTemplateType;
protected ContentService contentService;
// ------------------------------------------------------------------------------
// Wizard implementation
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
// get the node ref of the node that will contain the content
NodeRef containerNodeRef = this.getContainerNodeRef();
FileInfo fileInfo =
this.fileFolderService.create(containerNodeRef,
this.getSchemaFileName(),
ContentModel.TYPE_CONTENT);
final NodeRef schemaFileNodeRef = 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 = contentService.getWriter(schemaFileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/xml");
writer.setEncoding("UTF-8");
writer.putContent(this.getSchemaFile());
fileInfo = this.fileFolderService.create(containerNodeRef,
this.getPresentationTemplateFileName(),
ContentModel.TYPE_CONTENT);
final NodeRef presentationTemplateFileNodeRef = fileInfo.getNodeRef();
private String presentationTemplateType;
protected ContentService contentService;
// ------------------------------------------------------------------------------
// Wizard implementation
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
// get the node ref of the node that will contain the content
NodeRef containerNodeRef;
String nodeId = this.navigator.getCurrentNodeId();
if (nodeId == null)
{
containerNodeRef = this.nodeService.getRootNode(Repository.getStoreRef());
}
else
{
containerNodeRef = new NodeRef(Repository.getStoreRef(), nodeId);
}
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " +
this.getPresentationTemplateFileName());
// get a writer for the content and put the file
writer = contentService.getWriter(presentationTemplateFileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/xml");
writer.setEncoding("UTF-8");
writer.putContent(this.getPresentationTemplateFile());
final TemplatingService ts = TemplatingService.getInstance();
final String rootTagName =
this.getSchemaFileName().replaceAll("([^\\.])\\..+", "$1");
final TemplateType tt = ts.newTemplateType(rootTagName, schemaFileNodeRef);
if (this.getPresentationTemplateFile() != null)
{
tt.addOutputMethod(new XSLTOutputMethod(presentationTemplateFileNodeRef));
}
ts.registerTemplateType(tt);
// return the default outcome
return outcome;
}
FileInfo fileInfo = this.fileFolderService.create(containerNodeRef,
this.getSchemaFileName(),
ContentModel.TYPE_CONTENT);
final NodeRef schemaFileNodeRef = 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 = contentService.getWriter(schemaFileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/xml");
writer.setEncoding("UTF-8");
writer.putContent(this.getSchemaFile());
fileInfo = this.fileFolderService.create(containerNodeRef,
this.getPresentationTemplateFileName(),
ContentModel.TYPE_CONTENT);
final NodeRef presentationTemplateFileNodeRef = fileInfo.getNodeRef();
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " +
this.getPresentationTemplateFileName());
// get a writer for the content and put the file
writer = contentService.getWriter(presentationTemplateFileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/xml");
writer.setEncoding("UTF-8");
writer.putContent(this.getPresentationTemplateFile());
final TemplatingService ts = TemplatingService.getInstance();
final String rootTagName =
this.getSchemaFileName().replaceAll("([^\\.])\\..+", "$1");
final TemplateType tt = ts.newTemplateType(rootTagName, schemaFileNodeRef);
if (this.getPresentationTemplateFile() != null)
{
tt.addOutputMethod(new XSLTOutputMethod(presentationTemplateFileNodeRef));
}
ts.registerTemplateType(tt);
// return the default outcome
return outcome;
}
@Override
public void init(Map<String, String> parameters)
{
super.init(parameters);
this.removeUploadedSchemaFile();
this.removeUploadedPresentationTemplateFile();
}
@Override
public String cancel()
{
this.removeUploadedSchemaFile();
this.removeUploadedPresentationTemplateFile();
return super.cancel();
this.removeUploadedSchemaFile();
this.removeUploadedPresentationTemplateFile();
return super.cancel();
}
@Override
@@ -153,8 +160,8 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
{
case 1:
{
disabled = (this.getSchemaFileName() == null ||
this.getSchemaFileName().length() == 0);
disabled = (this.getSchemaFileName() == null ||
this.getSchemaFileName().length() == 0);
break;
}
}
@@ -162,26 +169,26 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
return disabled;
}
// @Override
// protected String doPostCommitProcessing(FacesContext context, String outcome)
// {
// // as we were successful, go to the set properties dialog if asked
// // to otherwise just return
// if (this.showOtherProperties)
// {
// // we are going to immediately edit the properties so we need
// // to setup the BrowseBean context appropriately
// this.browseBean.setDocument(new Node(this.createdNode));
//
// return getDefaultFinishOutcome() + AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
// "dialog:setContentProperties";
// }
// else
// {
// return outcome;
// }
// }
// @Override
// protected String doPostCommitProcessing(FacesContext context, String outcome)
// {
// // as we were successful, go to the set properties dialog if asked
// // to otherwise just return
// if (this.showOtherProperties)
// {
// // we are going to immediately edit the properties so we need
// // to setup the BrowseBean context appropriately
// this.browseBean.setDocument(new Node(this.createdNode));
//
// return getDefaultFinishOutcome() + AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
// "dialog:setContentProperties";
// }
// else
// {
// return outcome;
// }
// }
/**
* Action handler called when the user wishes to remove an uploaded file
*/
@@ -192,7 +199,7 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
// refresh the current page
return null;
}
/**
* Action handler called when the user wishes to remove an uploaded file
*/
@@ -204,105 +211,106 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
return null;
}
// ------------------------------------------------------------------------------
// Bean Getters and Setters
/**
* @return Returns the mime type currenty selected
*/
public String getPresentationTemplateType()
{
if (this.getPresentationTemplateFileName() != null)
{
// String s = this.getPresentationTemplateFileName();
// String extension =
this.presentationTemplateType = "XSL";
}
return this.presentationTemplateType;
}
/**
* @param presentationTemplateType Sets the currently selected mime type
*/
public void setPresentationTemplateType(String presentationTemplateType)
{
this.presentationTemplateType = presentationTemplateType;
}
public String getPresentationTemplateType()
{
if (this.getPresentationTemplateFileName() != null)
{
// String s = this.getPresentationTemplateFileName();
// String extension =
this.presentationTemplateType = "XSL";
}
return this.presentationTemplateType;
}
/**
* @param presentationTemplateType Sets the currently selected mime type
*/
public void setPresentationTemplateType(String presentationTemplateType)
{
this.presentationTemplateType = presentationTemplateType;
}
private FileUploadBean getFileUploadBean(final String id)
{
final FacesContext ctx = FacesContext.getCurrentInstance();
final Map sessionMap = ctx.getExternalContext().getSessionMap();
return (FileUploadBean)sessionMap.get(FileUploadBean.getKey(id));
}
private FileUploadBean getFileUploadBean(final String id)
{
final FacesContext ctx = FacesContext.getCurrentInstance();
final Map sessionMap = ctx.getExternalContext().getSessionMap();
return (FileUploadBean)sessionMap.get(FileUploadBean.getKey(id));
}
/**
* @return Returns the name of the file
*/
private String getFileName(final String id)
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
final FileUploadBean fileBean = this.getFileUploadBean(id);
return fileBean == null ? null : fileBean.getFileName();
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
private File getFile(final String id)
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
final FileUploadBean fileBean = this.getFileUploadBean(id);
return fileBean != null ? fileBean.getFile() : null;
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public File getSchemaFile()
{
return this.getFile("schema");
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public String getSchemaFileName()
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
return this.getFileName("schema");
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public String getPresentationTemplateFileName()
{
return this.getFileName("pt");
}
/**
* @return Returns the presentationTemplate file or <tt>null</tt>
*/
public File getPresentationTemplateFile()
{
return this.getFile("pt");
}
private String getFileName(final String id)
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
final FileUploadBean fileBean = this.getFileUploadBean(id);
return fileBean == null ? null : fileBean.getFileName();
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
private File getFile(final String id)
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
final FileUploadBean fileBean = this.getFileUploadBean(id);
return fileBean != null ? fileBean.getFile() : null;
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public File getSchemaFile()
{
return this.getFile("schema");
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public String getSchemaFileName()
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
return this.getFileName("schema");
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public String getPresentationTemplateFileName()
{
return this.getFileName("pt");
}
/**
* @return Returns the presentationTemplate file or <tt>null</tt>
*/
public File getPresentationTemplateFile()
{
return this.getFile("pt");
}
/**
* @return Returns a list of mime types to allow the user to select from
*/
public List<SelectItem> getCreatePresentationTemplateTypes()
{
return (List<SelectItem>)Arrays.asList(new SelectItem[] {
new SelectItem("freemarker", "FreeMarker"),
new SelectItem("xslt", "XSLT")
});
return (List<SelectItem>)Arrays.asList(new SelectItem[] {
new SelectItem("freemarker", "FreeMarker"),
new SelectItem("xslt", "XSLT")
});
}
/**
* @return Returns the summary data for the wizard.
*/
@@ -312,15 +320,15 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
// TODO: show first few lines of content here?
return buildSummary(new String[] {
"Schema File",
"Presentation Template Type",
"Presentation Template"
},
new String[] {
this.getSchemaFileName(),
this.getPresentationTemplateType(),
this.getPresentationTemplateFileName()
});
"Schema File",
"Presentation Template Type",
"Presentation Template"
},
new String[] {
this.getSchemaFileName(),
this.getPresentationTemplateType(),
this.getPresentationTemplateFileName()
});
}
// ------------------------------------------------------------------------------
@@ -328,7 +336,7 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
// ------------------------------------------------------------------------------
// Service Injection
/**
* @param contentService The contentService to set.
*/
@@ -336,21 +344,21 @@ public class CreateXmlContentTypeWizard extends BaseWizardBean
{
this.contentService = contentService;
}
// ------------------------------------------------------------------------------
// Helper Methods
/**
*/
protected void clearUpload(final String id)
{
protected void clearUpload(final String id)
{
// remove the file upload bean from the session
FacesContext ctx = FacesContext.getCurrentInstance();
FileUploadBean fileBean = (FileUploadBean)
ctx.getExternalContext().getSessionMap().
get(FileUploadBean.getKey(id));
if (fileBean != null)
fileBean.setFile(null);
}
FacesContext ctx = FacesContext.getCurrentInstance();
FileUploadBean fileBean = (FileUploadBean)
ctx.getExternalContext().getSessionMap().
get(FileUploadBean.getKey(id));
if (fileBean != null)
fileBean.setFile(null);
}
}

View File

@@ -278,12 +278,4 @@ public abstract class BaseDialogBean implements IDialogBean
FacesContext.getCurrentInstance(), getErrorMessageId()),
exception.getMessage());
}
protected NodeRef getContainerNodeRef()
{
String nodeId = this.navigator.getCurrentNodeId();
return (nodeId == null
? this.nodeService.getRootNode(Repository.getStoreRef())
: new NodeRef(Repository.getStoreRef(), nodeId));
}
}

View File

@@ -28,11 +28,14 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.CheckinCheckoutBean;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.templating.OutputUtil;
import org.alfresco.web.templating.TemplatingService;
import org.alfresco.web.ui.common.Utils;
/**
@@ -55,6 +58,9 @@ public class AVMEditBean
/** The ContentService bean reference */
protected ContentService contentService;
/** The NodeService bean reference */
protected NodeService nodeService;
// ------------------------------------------------------------------------------
// Bean property getters and setters
@@ -83,6 +89,14 @@ public class AVMEditBean
this.contentService = contentService;
}
/**
* @param nodeService The nodeService to set.
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @return Returns the current AVM node context.
*/
@@ -250,14 +264,13 @@ public class AVMEditBean
// commit the transaction
tx.commit();
// TODO: generate template content
/*if (nodeService.getProperty(node.getNodeRef(),
TemplatingService.TT_QNAME) != null)
// TODO: regenerate template content
if (nodeService.getProperty(avmRef, TemplatingService.TT_QNAME) != null)
{
OutputUtil.regenerate(node.getNodeRef(),
OutputUtil.regenerate(avmRef,
this.contentService,
this.nodeService);
}*/
}
resetState();

View File

@@ -16,8 +16,15 @@
*/
package org.alfresco.web.bean.wcm;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
@@ -29,11 +36,20 @@ import javax.faces.model.SelectItem;
import org.alfresco.config.Config;
import org.alfresco.config.ConfigElement;
import org.alfresco.config.ConfigService;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.content.BaseContentWizard;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.data.QuickSort;
import org.alfresco.web.templating.OutputUtil;
@@ -47,11 +63,35 @@ import org.apache.commons.logging.LogFactory;
*/
public class CreateWebContentWizard extends BaseContentWizard
{
private static final Log logger = LogFactory.getLog(CreateWebContentWizard.class);
protected String content = null;
protected String templateTypeName;
protected List<SelectItem> createMimeTypes;
protected String createdPath = null;
private static final Log logger = LogFactory.getLog(CreateWebContentWizard.class);
/** AVM service bean reference */
protected AVMService avmService;
/** AVM Browse Bean reference */
protected AVMBrowseBean avmBrowseBean;
/**
* @param avmService The AVMService to set.
*/
public void setAvmService(AVMService avmService)
{
this.avmService = avmService;
}
/**
* @param avmBrowseBean The AVMBrowseBean to set.
*/
public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean)
{
this.avmBrowseBean = avmBrowseBean;
}
// ------------------------------------------------------------------------------
@@ -63,28 +103,69 @@ public class CreateWebContentWizard extends BaseContentWizard
{
logger.debug("saving file content to " + this.fileName);
saveContent(null, this.content);
if (this.templateTypeName != null)
if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.templateTypeName != null)
{
logger.debug("generating template output for " + this.templateTypeName);
this.nodeService.setProperty(this.createdNode,
this.nodeService.setProperty(AVMNodeConverter.ToNodeRef(-1, this.createdPath),
TemplatingService.TT_QNAME,
this.templateTypeName);
TemplatingService ts = TemplatingService.getInstance();
TemplateType tt = this.getTemplateType();
OutputUtil.generate(this.createdNode,
OutputUtil.generate(this.createdPath.substring(0, this.createdPath.lastIndexOf('/')),
ts.parseXML(this.content),
tt,
this.fileName,
this.getContainerNodeRef(),
this.fileFolderService,
this.contentService,
this.nodeService);
this.nodeService,
this.avmService);
}
// return the default outcome
return outcome;
}
// ------------------------------------------------------------------------------
// Helper methods
/**
* Save the specified content using the currently set wizard attributes
*
* @param fileContent File content to save
* @param strContent String content to save
*/
protected void saveContent(File fileContent, String strContent) throws Exception
{
// get the parent path of the location to save the content
String path;
AVMNode avmNode = this.avmBrowseBean.getAvmNode();
if (avmNode == null)
{
// create in root of current website
Node websiteNode = this.navigator.getCurrentNode();
String storeRoot = (String)websiteNode.getProperties().get(ContentModel.PROP_AVMSTORE);
path = AVMConstants.buildAVMStoreRootPath(AVMConstants.buildAVMStagingStoreName(storeRoot));
}
else
{
// create in current folder path
path = avmNode.getPath();
}
// put the content of the file into the AVM store
if (fileContent != null)
{
avmService.createFile(path, this.fileName, new BufferedInputStream(new FileInputStream(fileContent)));
}
else
{
avmService.createFile(path, this.fileName, new ByteArrayInputStream((strContent == null ? "" : strContent).getBytes()));
}
// remember the created path
this.createdPath = path + '/' + this.fileName;
}
@Override
public void init(Map<String, String> parameters)
{
@@ -117,25 +198,6 @@ public class CreateWebContentWizard extends BaseContentWizard
return disabled;
}
@Override
protected String doPostCommitProcessing(FacesContext context, String outcome)
{
// as we were successful, go to the set properties dialog if asked
// to otherwise just return
if (this.showOtherProperties)
{
// we are going to immediately edit the properties so we need
// to setup the BrowseBean context appropriately
this.browseBean.setDocument(new Node(this.createdNode));
return getDefaultFinishOutcome() + AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
"dialog:setContentProperties";
}
else
{
return outcome;
}
}
// ------------------------------------------------------------------------------
// Bean Getters and Setters

View File

@@ -16,15 +16,13 @@
*/
package org.alfresco.web.templating;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMContext;
import org.alfresco.service.cmr.avm.AVMExistsException;
import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
@@ -53,7 +51,7 @@ public class OutputUtil
private static String getAVMParentPath(NodeRef nodeRef,
NodeService nodeService)
throws Exception
throws Exception
{
ChildAssociationRef caf = nodeService.getPrimaryParent(nodeRef);
final String parentName = (String)
@@ -72,80 +70,47 @@ public class OutputUtil
}
}
public static void generate(NodeRef createdNode,
public static void generate(String parentPath,
Document xml,
TemplateType tt,
String fileName,
NodeRef containerNodeRef,
FileFolderService fileFolderService,
ContentService contentService,
NodeService nodeService)
throws Exception
NodeService nodeService,
AVMService avmService)
throws Exception
{
try
{
// get the node ref of the node that will contain the content
String generatedFileName = stripExtension(fileName) + ".shtml";
FileInfo fileInfo =
fileFolderService.create(containerNodeRef,
generatedFileName,
ContentModel.TYPE_CONTENT);
NodeRef fileNodeRef = fileInfo.getNodeRef();
OutputStream fileOut = avmService.createFile(parentPath, generatedFileName);
String fullAvmPath = parentPath + '/' + generatedFileName;
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " +
generatedFileName);
fullAvmPath);
// get a writer for the content and put the file
ContentWriter writer = contentService.getWriter(fileNodeRef,
ContentModel.PROP_CONTENT, true);
// set the mimetype and encoding
writer.setMimetype("text/html");
writer.setEncoding("UTF-8");
TemplateOutputMethod tom = tt.getOutputMethods().get(0);
OutputStreamWriter out =
new OutputStreamWriter(writer.getContentOutputStream());
OutputStreamWriter out = new OutputStreamWriter(fileOut);
tom.generate(xml, tt, out);
out.close();
nodeService.setProperty(fileNodeRef,
NodeRef outputNodeRef = AVMNodeConverter.ToNodeRef(-1, fullAvmPath);
nodeService.setProperty(outputNodeRef,
TemplatingService.TT_QNAME,
tt.getName());
LOGGER.debug("generated " + generatedFileName + " using " + tom);
if (createdNode != null)
{
nodeService.setProperty(createdNode,
TemplatingService.TT_GENERATED_OUTPUT_QNAME,
fileNodeRef.toString());
}
NodeRef createdNodeRef = AVMNodeConverter.ToNodeRef(-1, parentPath + '/' + fileName);
nodeService.setProperty(createdNodeRef,
TemplatingService.TT_GENERATED_OUTPUT_QNAME,
outputNodeRef.toString());
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
final String parentAVMPath = getAVMParentPath(createdNode, nodeService);
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, generatedFileName));
}
catch (AVMExistsException e)
{
out = new OutputStreamWriter(avmService.getFileOutputStream(parentAVMPath + "/" + generatedFileName));
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
try
// TODO: should this output go anywhere in the AVM world now we are writing directly?
/*try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, fileName));
}
@@ -156,7 +121,7 @@ public class OutputUtil
LOGGER.debug("writing xml " + fileName + " to avm");
final TemplatingService ts = TemplatingService.getInstance();
ts.writeXML(xml, out);
out.close();
out.close();*/
}
catch (Exception e)
{
@@ -169,7 +134,7 @@ public class OutputUtil
public static void regenerate(final NodeRef nodeRef,
final ContentService contentService,
final NodeService nodeService)
throws Exception
throws Exception
{
try
{
@@ -203,14 +168,14 @@ public class OutputUtil
writer.setEncoding("UTF-8");
// put a loop to generate all output methods
TemplateOutputMethod tom = tt.getOutputMethods().get(0);
OutputStreamWriter out =
new OutputStreamWriter(writer.getContentOutputStream());
OutputStreamWriter out = new OutputStreamWriter(writer.getContentOutputStream());
tom.generate(xml, tt, out);
out.close();
LOGGER.debug("generated " + fileName + " using " + tom);
AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
// TODO: do we need these now - as the NodeRef's above are now AVM NodeRefs...?
/*AVMService avmService = (AVMService)AVMContext.fgInstance.fAppContext.getBean("avmService");
final String parentAVMPath = getAVMParentPath(nodeRef, nodeService);
try
{
@@ -222,9 +187,9 @@ public class OutputUtil
}
LOGGER.debug("generating " + generatedFileName + " to avm");
tom.generate(xml, tt, out);
out.close();
out.close();*/
try
/*try
{
out = new OutputStreamWriter(avmService.createFile(parentAVMPath, fileName));
}
@@ -234,7 +199,7 @@ public class OutputUtil
}
LOGGER.debug("writing xml " + fileName + " to avm");
ts.writeXML(xml, out);
out.close();
out.close();*/
}
catch (Exception e)
{

View File

@@ -50,345 +50,342 @@ import org.alfresco.web.bean.repository.Repository;
/**
* Provides management of template types.
*/
public final class TemplatingService
implements Serializable
public final class TemplatingService implements Serializable
{
////////////////////////////////////////////////////////////////////////////
/**
* Encapsulation of configuration file management.
*/
private static class Configuration
{
/** indicates whether or not the configuration file has been loaded */
public static boolean loaded = false;
private static NodeRef configFileNodeRef = null;
/**
* locate the configuration file. currently it is stored as
* <tt>templating_config.xml</tt> at the root of the data dictionary.
*
* @return the configuration file, which is currently all the
* <tt>TemplateTypes</tt> serialized using object serialization.
*/
private static NodeRef getConfigFile()
{
if (configFileNodeRef == null)
{
final TemplatingService ts = TemplatingService.INSTANCE;
LOGGER.debug("loading config file");
// get the template from the special Email Templates folder
FacesContext fc = FacesContext.getCurrentInstance();
String xpath = (Application.getRootPath(fc) + "/" +
Application.getGlossaryFolderName(fc));
NodeRef rootNodeRef = ts.nodeService.getRootNode(Repository.getStoreRef());
List<NodeRef> results = ts.searchService.selectNodes(rootNodeRef, xpath, null, ts.namespaceService, false);
if (results.size() != 1)
throw new RuntimeException("expected one result for " + xpath);
NodeRef dataDictionaryNodeRef = results.get(0);
LOGGER.debug("loaded data dictionary " + dataDictionaryNodeRef);
try
{
Configuration.configFileNodeRef =
ts.fileFolderService.create(dataDictionaryNodeRef,
"templating_configuration.xml",
ContentModel.TYPE_CONTENT).getNodeRef();
}
catch (FileExistsException fee)
{
Configuration.configFileNodeRef =
ts.fileFolderService.searchSimple(dataDictionaryNodeRef, "templating_configuration.xml");
}
LOGGER.debug("loaded config file " + configFileNodeRef);
assert Configuration.configFileNodeRef != null : "unable to load templating_configuration.xml";
}
return Configuration.configFileNodeRef;
}
/**
* Load the configuration file into the templating service.
*/
public static void load()
throws IOException
{
final TemplatingService ts = TemplatingService.INSTANCE;
final NodeRef configFileNodeRef = getConfigFile();
FacesContext fc = FacesContext.getCurrentInstance();
final ContentReader contentReader = ts.contentService.getReader(configFileNodeRef,
ContentModel.TYPE_CONTENT);
if (contentReader == null)
LOGGER.debug("templating_config.xml is empty");
else
{
LOGGER.debug("parsing templating_config.xml");
final InputStream contentIn = contentReader.getContentInputStream();
final ObjectInputStream in = new ObjectInputStream(contentIn);
try
{
while (true)
{
try
{
final TemplateType tt = (TemplateType)in.readObject();
TemplatingService.INSTANCE.registerTemplateType(tt);
}
catch (EOFException eof)
{
break;
}
}
in.close();
}
catch (ClassNotFoundException cnfe)
{
TemplatingService.LOGGER.error(cnfe);
}
}
loaded = true;
}
/**
* Save the current state of the templating service to the configuration file.
*/
public static void save()
throws IOException
{
final TemplatingService ts = TemplatingService.INSTANCE;
FacesContext fc = FacesContext.getCurrentInstance();
final NodeRef configFileNodeRef = getConfigFile();
final OutputStream contentOut = ts.contentService.getWriter(configFileNodeRef, ContentModel.TYPE_CONTENT, true).getContentOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(contentOut);
for (TemplateType tt : TemplatingService.INSTANCE.getTemplateTypes())
{
out.writeObject(tt);
}
out.close();
}
}
////////////////////////////////////////////////////////////////////////////
/**
* temporary location of the property on nodes that are xml files created
* by templating.
*/
public static final org.alfresco.service.namespace.QName TT_QNAME =
org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt");
/**
* temporary location of the property on nodes generated from xml assets.
*/
public static final org.alfresco.service.namespace.QName TT_GENERATED_OUTPUT_QNAME =
org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt_generated_output");
private static final Log LOGGER = LogFactory.getLog(TemplatingService.class);
/** the single instance initialized using spring */
private static TemplatingService INSTANCE;
/** internal storage of template types, keyed by the template name */
private HashMap<String, TemplateType> templateTypes =
new HashMap<String, TemplateType>();
private final ContentService contentService;
private final NodeService nodeService;
private final FileFolderService fileFolderService;
private final DictionaryService dictionaryService;
private final NamespaceService namespaceService;
private final SearchService searchService;
/** instantiated using spring */
public TemplatingService(final ContentService contentService,
final NodeService nodeService,
final FileFolderService fileFolderService,
final DictionaryService dictionaryService,
final NamespaceService namespaceService,
final SearchService searchService)
{
this.contentService = contentService;
this.nodeService = nodeService;
this.fileFolderService = fileFolderService;
this.dictionaryService = dictionaryService;
this.namespaceService = namespaceService;
this.searchService = searchService;
if (INSTANCE == null)
INSTANCE = this;
}
/** Provides the templating service instance, loads config if necessary */
public static TemplatingService getInstance()
{
if (!Configuration.loaded)
{
LOGGER.debug("loading configuration");
try
{
Configuration.load();
}
catch (Throwable t)
{
LOGGER.error(t);
t.printStackTrace();
}
}
return TemplatingService.INSTANCE;
}
/** returns all registered template types */
public Collection<TemplateType> getTemplateTypes()
{
return this.templateTypes.values();
}
/** return the template type by name or <tt>null</tt> if not found */
public TemplateType getTemplateType(final String name)
{
return this.templateTypes.get(name);
}
/** registers a template type. if one exists with the same name, it is replaced */
public void registerTemplateType(final TemplateType tt)
{
this.templateTypes.put(tt.getName(), tt);
try
{
Configuration.save();
}
catch (IOException ioe)
{
LOGGER.error(ioe);
}
}
/**
* instantiate a template type. for now this will always generate the
* xforms implementation, but will at some point be configurable such that
* the template type implementation can be configured for the system,
* or specified in the gui.
*/
public TemplateType newTemplateType(final String name,
final NodeRef schemaNodeRef)
{
return new TemplateTypeImpl(name, schemaNodeRef);
}
/** utility function for creating a document */
public Document newDocument()
{
try
{
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
final DocumentBuilder db = dbf.newDocumentBuilder();
return db.newDocument();
}
catch (ParserConfigurationException pce)
{
assert false : pce;
LOGGER.error(pce);
return null;
}
// catch (SAXException saxe)
// {
// LOGGER.error(saxe);
// }
// catch (IOException ioe)
// {
// LOGGER.error(ioe);
// }
}
/** utility function for serializing a node */
public void writeXML(final Node n, final Writer output)
{
try
{
final TransformerFactory tf = TransformerFactory.newInstance();
final Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("writing out a document for " +
(n instanceof Document
? ((Document)n).getDocumentElement()
: n).getNodeName() +
" to " + output);
final StringWriter sw = new StringWriter();
t.transform(new DOMSource(n), new StreamResult(sw));
LOGGER.debug(sw.toString());
}
t.transform(new DOMSource(n), new StreamResult(output));
}
catch (TransformerException te)
{
te.printStackTrace();
assert false : te.getMessage();
}
}
/** utility function for serializing a node */
public void writeXML(final Node n, final File output)
throws IOException
{
this.writeXML(n, new FileWriter(output));
}
/** utility function for serializing a node */
public String writeXMLToString(final Node n)
{
final StringWriter result = new StringWriter();
this.writeXML(n, result);
return result.toString();
}
/** utility function for parsing xml */
public Document parseXML(final String source)
throws ParserConfigurationException,
SAXException,
IOException
{
return this.parseXML(new ByteArrayInputStream(source.getBytes()));
}
/** utility function for parsing xml */
public Document parseXML(final NodeRef nodeRef)
throws ParserConfigurationException,
SAXException,
IOException
{
final ContentReader contentReader =
this.contentService.getReader(nodeRef, ContentModel.TYPE_CONTENT);
final InputStream in = contentReader.getContentInputStream();
return this.parseXML(in);
}
/** utility function for parsing xml */
public Document parseXML(final File source)
throws ParserConfigurationException,
SAXException,
IOException
{
return this.parseXML(new FileInputStream(source));
}
/** utility function for parsing xml */
public Document parseXML(final InputStream source)
throws ParserConfigurationException,
SAXException,
IOException
{
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document result = db.parse(source);
source.close();
return result;
}
////////////////////////////////////////////////////////////////////////////
/**
* Encapsulation of configuration file management.
*/
private static class Configuration
{
/** indicates whether or not the configuration file has been loaded */
public static boolean loaded = false;
private static NodeRef configFileNodeRef = null;
/**
* locate the configuration file. currently it is stored as
* <tt>templating_config.xml</tt> at the root of the data dictionary.
*
* @return the configuration file, which is currently all the
* <tt>TemplateTypes</tt> serialized using object serialization.
*/
private static NodeRef getConfigFile()
{
if (configFileNodeRef == null)
{
final TemplatingService ts = TemplatingService.INSTANCE;
LOGGER.debug("loading config file");
// get the template from the special Email Templates folder
FacesContext fc = FacesContext.getCurrentInstance();
String xpath = (Application.getRootPath(fc) + "/" +
Application.getGlossaryFolderName(fc));
NodeRef rootNodeRef = ts.nodeService.getRootNode(Repository.getStoreRef());
List<NodeRef> results = ts.searchService.selectNodes(rootNodeRef, xpath, null, ts.namespaceService, false);
if (results.size() != 1)
throw new RuntimeException("expected one result for " + xpath);
NodeRef dataDictionaryNodeRef = results.get(0);
LOGGER.debug("loaded data dictionary " + dataDictionaryNodeRef);
try
{
Configuration.configFileNodeRef =
ts.fileFolderService.create(dataDictionaryNodeRef,
"templating_configuration.xml",
ContentModel.TYPE_CONTENT).getNodeRef();
}
catch (FileExistsException fee)
{
Configuration.configFileNodeRef =
ts.fileFolderService.searchSimple(dataDictionaryNodeRef, "templating_configuration.xml");
}
LOGGER.debug("loaded config file " + configFileNodeRef);
assert Configuration.configFileNodeRef != null : "unable to load templating_configuration.xml";
}
return Configuration.configFileNodeRef;
}
/**
* Load the configuration file into the templating service.
*/
public static void load()
throws IOException
{
final TemplatingService ts = TemplatingService.INSTANCE;
final NodeRef configFileNodeRef = getConfigFile();
FacesContext fc = FacesContext.getCurrentInstance();
final ContentReader contentReader = ts.contentService.getReader(configFileNodeRef,
ContentModel.TYPE_CONTENT);
if (contentReader == null)
LOGGER.debug("templating_config.xml is empty");
else
{
LOGGER.debug("parsing templating_config.xml");
final InputStream contentIn = contentReader.getContentInputStream();
final ObjectInputStream in = new ObjectInputStream(contentIn);
try
{
while (true)
{
try
{
final TemplateType tt = (TemplateType)in.readObject();
TemplatingService.INSTANCE.registerTemplateType(tt);
}
catch (EOFException eof)
{
break;
}
}
in.close();
}
catch (ClassNotFoundException cnfe)
{
TemplatingService.LOGGER.error(cnfe);
}
}
loaded = true;
}
/**
* Save the current state of the templating service to the configuration file.
*/
public static void save()
throws IOException
{
final TemplatingService ts = TemplatingService.INSTANCE;
FacesContext fc = FacesContext.getCurrentInstance();
final NodeRef configFileNodeRef = getConfigFile();
final OutputStream contentOut = ts.contentService.getWriter(configFileNodeRef, ContentModel.TYPE_CONTENT, true).getContentOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(contentOut);
for (TemplateType tt : TemplatingService.INSTANCE.getTemplateTypes())
{
out.writeObject(tt);
}
out.close();
}
}
////////////////////////////////////////////////////////////////////////////
/**
* temporary location of the property on nodes that are xml files created
* by templating.
*/
public static final org.alfresco.service.namespace.QName TT_QNAME =
org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt");
/**
* temporary location of the property on nodes generated from xml assets.
*/
public static final org.alfresco.service.namespace.QName TT_GENERATED_OUTPUT_QNAME =
org.alfresco.service.namespace.QName.createQName(org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI, "tt_generated_output");
private static final Log LOGGER = LogFactory.getLog(TemplatingService.class);
/** the single instance initialized using spring */
private static TemplatingService INSTANCE;
/** internal storage of template types, keyed by the template name */
private HashMap<String, TemplateType> templateTypes =
new HashMap<String, TemplateType>();
private final ContentService contentService;
private final NodeService nodeService;
private final FileFolderService fileFolderService;
private final DictionaryService dictionaryService;
private final NamespaceService namespaceService;
private final SearchService searchService;
/** instantiated using spring */
public TemplatingService(final ContentService contentService,
final NodeService nodeService,
final FileFolderService fileFolderService,
final DictionaryService dictionaryService,
final NamespaceService namespaceService,
final SearchService searchService)
{
this.contentService = contentService;
this.nodeService = nodeService;
this.fileFolderService = fileFolderService;
this.dictionaryService = dictionaryService;
this.namespaceService = namespaceService;
this.searchService = searchService;
if (INSTANCE == null)
INSTANCE = this;
}
/** Provides the templating service instance, loads config if necessary */
public static TemplatingService getInstance()
{
if (!Configuration.loaded)
{
LOGGER.debug("loading configuration");
try
{
Configuration.load();
}
catch (Throwable t)
{
LOGGER.error(t);
t.printStackTrace();
}
}
return TemplatingService.INSTANCE;
}
/** returns all registered template types */
public Collection<TemplateType> getTemplateTypes()
{
return this.templateTypes.values();
}
/** return the template type by name or <tt>null</tt> if not found */
public TemplateType getTemplateType(final String name)
{
return this.templateTypes.get(name);
}
/** registers a template type. if one exists with the same name, it is replaced */
public void registerTemplateType(final TemplateType tt)
{
this.templateTypes.put(tt.getName(), tt);
try
{
Configuration.save();
}
catch (IOException ioe)
{
LOGGER.error(ioe);
}
}
/**
* instantiate a template type. for now this will always generate the
* xforms implementation, but will at some point be configurable such that
* the template type implementation can be configured for the system,
* or specified in the gui.
*/
public TemplateType newTemplateType(final String name,
final NodeRef schemaNodeRef)
{
return new TemplateTypeImpl(name, schemaNodeRef);
}
/** utility function for creating a document */
public Document newDocument()
{
try
{
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
final DocumentBuilder db = dbf.newDocumentBuilder();
return db.newDocument();
}
catch (ParserConfigurationException pce)
{
assert false : pce;
LOGGER.error(pce);
return null;
}
// catch (SAXException saxe)
// {
// LOGGER.error(saxe);
// }
// catch (IOException ioe)
// {
// LOGGER.error(ioe);
// }
}
/** utility function for serializing a node */
public void writeXML(final Node n, final Writer output)
{
try
{
final TransformerFactory tf = TransformerFactory.newInstance();
final Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("writing out a document for " +
(n instanceof Document
? ((Document)n).getDocumentElement()
: n).getNodeName() +
" to " + output);
final StringWriter sw = new StringWriter();
t.transform(new DOMSource(n), new StreamResult(sw));
LOGGER.debug(sw.toString());
}
t.transform(new DOMSource(n), new StreamResult(output));
}
catch (TransformerException te)
{
te.printStackTrace();
assert false : te.getMessage();
}
}
/** utility function for serializing a node */
public void writeXML(final Node n, final File output)
throws IOException
{
this.writeXML(n, new FileWriter(output));
}
/** utility function for serializing a node */
public String writeXMLToString(final Node n)
{
final StringWriter result = new StringWriter();
this.writeXML(n, result);
return result.toString();
}
/** utility function for parsing xml */
public Document parseXML(final String source)
throws ParserConfigurationException,
SAXException,
IOException
{
return this.parseXML(new ByteArrayInputStream(source.getBytes()));
}
/** utility function for parsing xml */
public Document parseXML(final NodeRef nodeRef)
throws ParserConfigurationException,
SAXException,
IOException
{
final ContentReader contentReader =
this.contentService.getReader(nodeRef, ContentModel.TYPE_CONTENT);
final InputStream in = contentReader.getContentInputStream();
return this.parseXML(in);
}
/** utility function for parsing xml */
public Document parseXML(final File source)
throws ParserConfigurationException,
SAXException,
IOException
{
return this.parseXML(new FileInputStream(source));
}
/** utility function for parsing xml */
public Document parseXML(final InputStream source)
throws ParserConfigurationException,
SAXException,
IOException
{
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document result = db.parse(source);
source.close();
return result;
}
}

View File

@@ -569,6 +569,14 @@
<property-name>dictionaryService</property-name>
<value>#{DictionaryService}</value>
</managed-property>
<managed-property>
<property-name>avmService</property-name>
<value>#{AVMService}</value>
</managed-property>
<managed-property>
<property-name>avmBrowseBean</property-name>
<value>#{AVMBrowseBean}</value>
</managed-property>
</managed-bean>
<managed-bean>

View File

@@ -74,6 +74,9 @@
<div class="mainSubText"><h:outputText value="#{msg.sandbox_info}" id="msg3" /></div>
<div class="mainSubText"><h:outputText value="#{NavigationBean.nodeProperties.description}" id="msg4" /></div>
</td>
<td align=right>
<a:actionLink value="#{msg.sandbox_create}" image="/images/icons/new_content.gif" actionListener="#{AVMBrowseBean.setupSandboxAction}" action="wizard:createWebContent" />
</td>
</tr>
</table>