- removing templating config file

- renamed create xml content type to create form
- writing xsds and xsls into the data dictionary
- using search to implement TemplatingService.getTempalteTypes()
- adding fields to create form screen for the root tag name to use within the schema and for a display name within the dropdown (friendly non file name name)
- using aspects from the wcmModel to categorize and relate templates and templateoutputmethods 



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4014 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-10-04 05:04:35 +00:00
parent cea94661de
commit 76fa148539
8 changed files with 255 additions and 270 deletions

View File

@@ -20,7 +20,6 @@ import org.w3c.dom.Document;
import java.util.List;
import java.net.URI;
import java.io.Serializable;
//import org.alfresco.service.cmr.repository.NodeRef;
/**
* Encapsulation of a template type.
@@ -32,15 +31,12 @@ public interface TemplateType
/** the name of the template, which must be unique within the TemplatingService */
public String getName();
/** the root tag to use within the schema */
public String getRootTagName();
/** the xml schema for this template type */
public Document getSchema();
// public String /* URI */ getSchemaURI();
// public void setSchemaNodeRef(final NodeRef nodeRef);
//
// public NodeRef getSchemaNodeRef();
//XXXarielb not used currently and not sure if it's necessary...
// public void addInputMethod(final TemplateInputMethod in);

View File

@@ -36,11 +36,12 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
import org.alfresco.util.TempFileProvider;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.search.*;
import org.alfresco.service.cmr.model.*;
import org.alfresco.service.namespace.NamespaceService;
import javax.faces.context.FacesContext;
@@ -52,121 +53,6 @@ import org.alfresco.web.bean.repository.Repository;
*/
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
@@ -196,14 +82,16 @@ public final class TemplatingService implements Serializable
private final DictionaryService dictionaryService;
private final NamespaceService namespaceService;
private final SearchService searchService;
private NodeRef contentFormsNodeRef;
/** instantiated using spring */
public TemplatingService(final ContentService contentService,
final NodeService nodeService,
final FileFolderService fileFolderService,
final DictionaryService dictionaryService,
final NamespaceService namespaceService,
final SearchService searchService)
final NodeService nodeService,
final FileFolderService fileFolderService,
final DictionaryService dictionaryService,
final NamespaceService namespaceService,
final SearchService searchService)
{
this.contentService = contentService;
this.nodeService = nodeService;
@@ -218,46 +106,78 @@ public final class TemplatingService implements Serializable
/** 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;
}
/**
* @return the cached reference to the WCM Content Forms folder
*/
public NodeRef getContentFormsNodeRef()
{
if (this.contentFormsNodeRef == null)
{
final FacesContext fc = FacesContext.getCurrentInstance();
final String xpath = (Application.getRootPath(fc) + "/" +
Application.getGlossaryFolderName(fc) + "/" +
Application.getContentFormsFolderName(fc));
LOGGER.debug("locating content forms at " + xpath);
final List<NodeRef> results =
searchService.selectNodes(nodeService.getRootNode(Repository.getStoreRef()),
xpath,
null,
namespaceService,
false);
this.contentFormsNodeRef = (results != null && results.size() == 1 ? results.get(0) : null);
}
return this.contentFormsNodeRef;
}
/** returns all registered template types */
public Collection<TemplateType> getTemplateTypes()
{
return this.templateTypes.values();
try
{
final SearchParameters sp = new SearchParameters();
sp.addStore(Repository.getStoreRef());
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
final String q = "ASPECT:\"" + WCMModel.ASPECT_TEMPLATE + "\"";
sp.setQuery(q);
LOGGER.debug("running query [" + q + "]");
final ResultSet rs = this.searchService.query(sp);
LOGGER.debug("received " + rs.length() + " results");
final Collection<TemplateType> result = new LinkedList<TemplateType>();
for (ResultSetRow row : rs)
{
final NodeRef nodeRef = row.getNodeRef();
result.add(this.newTemplateType(nodeRef));
}
return result;
}
catch (RuntimeException re)
{
LOGGER.error(re);
throw re;
}
}
/** 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();
final SearchParameters sp = new SearchParameters();
sp.addStore(Repository.getStoreRef());
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("ASPECT:\"" + WCMModel.ASPECT_TEMPLATE +
"\" AND @" + Repository.escapeQName(ContentModel.PROP_TITLE) +
":\"" + name + "\"");
final ResultSet rs = this.searchService.query(sp);
return (rs.length() == 1 ? this.newTemplateType(rs.getNodeRef(0)) : null);
}
catch (IOException ioe)
catch (RuntimeException re)
{
LOGGER.error(ioe);
LOGGER.error(re);
throw re;
}
}
@@ -267,10 +187,21 @@ public final class TemplatingService implements Serializable
* the template type implementation can be configured for the system,
* or specified in the gui.
*/
public TemplateType newTemplateType(final String name,
final NodeRef schemaNodeRef)
private TemplateType newTemplateType(final NodeRef schemaNodeRef)
{
return new TemplateTypeImpl(name, schemaNodeRef);
LOGGER.debug("creating template type for " + schemaNodeRef);
final String title = (String)
this.nodeService.getProperty(schemaNodeRef, ContentModel.PROP_TITLE);
LOGGER.debug("title is " + title);
final String schemaRootTagName = (String)
this.nodeService.getProperty(schemaNodeRef, WCMModel.PROP_SCHEMA_ROOT_TAG_NAME);
LOGGER.debug("root tag name is " + schemaRootTagName);
TemplateType tt = new TemplateTypeImpl(title, schemaNodeRef, schemaRootTagName);
final NodeRef xslNodeRef = (NodeRef)
this.nodeService.getProperty(schemaNodeRef, WCMModel.ASSOC_TEMPLATE_OUTPUT_METHODS);
LOGGER.debug("xsl noderef is " + xslNodeRef);
tt.addOutputMethod(new XSLTOutputMethod(xslNodeRef));
return tt;
}
/** utility function for creating a document */

View File

@@ -31,83 +31,76 @@ import org.xml.sax.SAXException;
public class TemplateTypeImpl
implements TemplateType
{
private static final Log LOGGER = LogFactory.getLog(TemplateTypeImpl.class);
private static final Log LOGGER = LogFactory.getLog(TemplateTypeImpl.class);
private transient Document schema;
private final NodeRef schemaNodeRef;
private final String name;
private final String rootTagName;
private final LinkedList<TemplateOutputMethod> outputMethods =
new LinkedList<TemplateOutputMethod>();
private final static LinkedList<TemplateInputMethod> INPUT_METHODS =
new LinkedList<TemplateInputMethod>();
static
{
INPUT_METHODS.add(new XFormsInputMethod());
}
public TemplateTypeImpl(final String name,
final NodeRef schemaNodeRef,
final String rootTagName)
{
this.name = name;
this.schemaNodeRef = schemaNodeRef;
this.rootTagName = rootTagName;
}
public String getName()
{
return this.name;
}
private transient Document schema;
private final NodeRef schemaNodeRef;
private final String name;
private final LinkedList<TemplateOutputMethod> outputMethods =
new LinkedList<TemplateOutputMethod>();
private final static LinkedList<TemplateInputMethod> INPUT_METHODS =
new LinkedList<TemplateInputMethod>();
public String getRootTagName()
{
return this.rootTagName;
}
static
{
INPUT_METHODS.add(new XFormsInputMethod());
}
public TemplateTypeImpl(final String name,
final NodeRef schemaNodeRef)
{
this.name = name;
this.schemaNodeRef = schemaNodeRef;
}
public Document getSchema()
{
if (this.schema == null)
{
final TemplatingService ts = TemplatingService.getInstance();
try
{
//XXXarielb maybe cloneNode instead?
return /* this.schema = */ ts.parseXML(this.schemaNodeRef);
}
catch (Exception e)
{
LOGGER.error(e);
}
}
return this.schema;
}
public String getName()
{
return this.name;
}
public List<TemplateInputMethod> getInputMethods()
{
return INPUT_METHODS;
}
public String /* URI */ getSchemaURI()
{
final javax.faces.context.FacesContext fc =
javax.faces.context.FacesContext.getCurrentInstance();
final javax.servlet.http.HttpSession session = (javax.servlet.http.HttpSession)
fc.getExternalContext().getSession(true);
org.alfresco.web.bean.repository.User user = (org.alfresco.web.bean.repository.User)
session.getAttribute(org.alfresco.web.app.servlet.AuthenticationHelper.AUTHENTICATION_USER);
public void addOutputMethod(TemplateOutputMethod output)
{
this.outputMethods.add(output);
}
String result = DownloadContentServlet.generateDownloadURL(this.schemaNodeRef, this.name + ".xsd");
result += "?ticket=" + user.getTicket();
return result;
}
public List<TemplateOutputMethod> getOutputMethods()
{
return this.outputMethods;
}
public Document getSchema()
{
if (this.schema == null)
{
final TemplatingService ts = TemplatingService.getInstance();
try
{
//XXXarielb maybe cloneNode instead?
return /* this.schema = */ ts.parseXML(this.schemaNodeRef);
}
catch (Exception e)
{
LOGGER.error(e);
}
}
return this.schema;
}
public List<TemplateInputMethod> getInputMethods()
{
return INPUT_METHODS;
}
public void addOutputMethod(TemplateOutputMethod output)
{
this.outputMethods.add(output);
}
public List<TemplateOutputMethod> getOutputMethods()
{
return this.outputMethods;
}
public int hashCode()
{
return this.getName().hashCode();
}
public int hashCode()
{
return this.getName().hashCode();
}
}

View File

@@ -301,7 +301,7 @@ public class XFormsBean
LOGGER.debug("building xform for schema " + tt.getName());
final Document result = builder.buildForm(xmlContent,
schemaDocument,
tt.getName());
tt.getRootTagName());
LOGGER.debug("generated xform: " + result);
// LOGGER.debug(ts.writeXMLToString(result));
return result;