Template extension spring configuration support

- similar pattern to existing script bean extension support
 - new root model helper objects and custom methods can be added via spring configuration
Cleanup of script extension spring support
Fix to thread safety of configured script extension beans that use the Scopable interface

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5369 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2007-03-09 12:30:34 +00:00
parent e4e89f4db1
commit 9323a8cd7a
24 changed files with 363 additions and 151 deletions

View File

@@ -26,23 +26,19 @@ package org.alfresco.repo.jscript;
import org.alfresco.config.JNDIConstants;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.ServiceRegistry;
import org.mozilla.javascript.Scriptable;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
/**
* Helper to access AVM nodes from a script context.
*
* @author Kevin Roast
*/
public final class AVM extends BaseScriptImplementation implements Scopeable
public final class AVM extends BaseScopableScriptImplementation
{
/** Repository Service Registry */
private ServiceRegistry services;
/** Root scope for this object */
private Scriptable scope;
/**
* Set the service registry
*
@@ -53,14 +49,6 @@ public final class AVM extends BaseScriptImplementation implements Scopeable
this.services = serviceRegistry;
}
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Return an AVM Node representing the public store root folder.
*
@@ -77,7 +65,7 @@ public final class AVM extends BaseScriptImplementation implements Scopeable
AVMNodeDescriptor nodeDesc = this.services.getAVMService().lookup(-1, rootPath);
if (nodeDesc != null)
{
rootNode = new AVMNode(AVMNodeConverter.ToNodeRef(-1, rootPath), this.services, this.scope);
rootNode = new AVMNode(AVMNodeConverter.ToNodeRef(-1, rootPath), this.services, getScope());
}
}
return rootNode;
@@ -98,7 +86,7 @@ public final class AVM extends BaseScriptImplementation implements Scopeable
AVMNodeDescriptor nodeDesc = this.services.getAVMService().lookup(-1, path);
if (nodeDesc != null)
{
node = new AVMNode(AVMNodeConverter.ToNodeRef(-1, path), this.services, this.scope);
node = new AVMNode(AVMNodeConverter.ToNodeRef(-1, path), this.services, getScope());
}
}
return node;

View File

@@ -30,21 +30,17 @@ import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ActionService;
import org.mozilla.javascript.Scriptable;
/**
* Scripted Action service for describing and executing actions against Nodes.
*
* @author davidc
*/
public final class Actions extends BaseScriptImplementation implements Scopeable
public final class Actions extends BaseScopableScriptImplementation
{
/** Repository Service Registry */
private ServiceRegistry services;
/** Root scope for this object */
private Scriptable scope;
/**
* Set the service registry
*
@@ -54,14 +50,6 @@ public final class Actions extends BaseScriptImplementation implements Scopeable
{
this.services = serviceRegistry;
}
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Gets the list of registered action names
@@ -102,7 +90,7 @@ public final class Actions extends BaseScriptImplementation implements Scopeable
{
Action action = actionService.createAction(actionName);
scriptAction = new ScriptAction(this.services, action, actionDef);
scriptAction.setScope(scope);
scriptAction.setScope(getScope());
}
return scriptAction;
}

View File

@@ -0,0 +1,49 @@
/*
* 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.repo.jscript;
import org.mozilla.javascript.Scriptable;
/**
* Abstract base class for a script implementation that requires a script execution scope.
*
* The scope is local to the currently executing script and therefore a ThreadLocal is required.
*
* @author Kevin Roast
*/
public class BaseScopableScriptImplementation extends BaseScriptImplementation implements Scopeable
{
private static ThreadLocal<Scriptable> scope = new ThreadLocal<Scriptable>();
/**
* Set the Scriptable global scope
*
* @param script relative global scope
*/
public void setScope(Scriptable scope)
{
this.scope.set(scope);
}
/**
* @return script global scope
*/
public Scriptable getScope()
{
return this.scope.get();
}
}

View File

@@ -31,18 +31,14 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.namespace.QName;
import org.mozilla.javascript.Scriptable;
/**
* Support class for finding categories, finding root nodes for categories and creating root categories.
*
* @author Andy Hind
*/
public final class Classification extends BaseScriptImplementation implements Scopeable
public final class Classification extends BaseScopableScriptImplementation
{
@SuppressWarnings("unused")
private Scriptable scope;
private ServiceRegistry services;
private StoreRef storeRef;
@@ -67,14 +63,6 @@ public final class Classification extends BaseScriptImplementation implements S
this.services = services;
}
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Find all the category nodes in a given classification.
*
@@ -137,7 +125,7 @@ public final class Classification extends BaseScriptImplementation implements S
int i = 0;
for (ChildAssociationRef car : cars)
{
categoryNodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.scope);
categoryNodes[i++] = new CategoryNode(car.getChildRef(), this.services, getScope());
}
return categoryNodes;
}

View File

@@ -37,24 +37,13 @@ import org.mozilla.javascript.Scriptable;
*
* @author Kevin Roast
*/
public final class CrossRepositoryCopy extends BaseScriptImplementation implements Scopeable
public final class CrossRepositoryCopy extends BaseScopableScriptImplementation
{
public final static String BEAN_NAME = "crossCopyScript";
/** Service registry */
private ServiceRegistry services;
/** Root scope for this object */
private Scriptable scope;
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Set the service registry
*
@@ -98,7 +87,7 @@ public final class CrossRepositoryCopy extends BaseScriptImplementation implemen
AVMNodeDescriptor node = this.services.getAVMService().lookup(-1, destPath);
if (node != null)
{
result = ((AVMNode)dest).newInstance(destPath, -1, this.services, this.scope);
result = ((AVMNode)dest).newInstance(destPath, -1, this.services, getScope());
}
}
else if (dest.getNodeRef().getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_WORKSPACE))

View File

@@ -1550,9 +1550,13 @@ public class Node implements Serializable, Scopeable
private String processTemplate(String template, NodeRef templateRef, ScriptableObject args)
{
// build default model for the template processing
Map<String, Object> model = FreeMarkerProcessor.buildDefaultModel(services, ((Node) ((Wrapper) scope.get(
"person", scope)).unwrap()).getNodeRef(), ((Node) ((Wrapper) scope.get("companyhome", scope)).unwrap())
.getNodeRef(), ((Node) ((Wrapper) scope.get("userhome", scope)).unwrap()).getNodeRef(), templateRef, null);
Map<String, Object> model = FreeMarkerProcessor.buildDefaultModel(
services,
((Node)((Wrapper)scope.get("person", scope)).unwrap()).getNodeRef(),
((Node)((Wrapper)scope.get("companyhome", scope)).unwrap()).getNodeRef(),
((Node)((Wrapper)scope.get("userhome", scope)).unwrap()).getNodeRef(),
templateRef,
null);
// add the current node as either the document/space as appropriate
if (this.getIsDocument())

View File

@@ -33,22 +33,18 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
import org.mozilla.javascript.Scriptable;
/**
* Scripted People service for describing and executing actions against People & Groups.
*
* @author davidc
*/
public final class People extends BaseScriptImplementation implements Scopeable
public final class People extends BaseScopableScriptImplementation
{
/** Repository Service Registry */
private ServiceRegistry services;
private AuthorityDAO authorityDAO;
/** Root scope for this object */
private Scriptable scope;
/**
* Set the service registry
*
@@ -69,14 +65,6 @@ public final class People extends BaseScriptImplementation implements Scopeable
this.authorityDAO = authorityDAO;
}
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Gets the Person given the username
*
@@ -90,7 +78,7 @@ public final class People extends BaseScriptImplementation implements Scopeable
if (personService.personExists(username))
{
NodeRef personRef = personService.getPerson(username);
person = new Node(personRef, services, scope);
person = new Node(personRef, services, getScope());
}
return person;
}
@@ -107,7 +95,7 @@ public final class People extends BaseScriptImplementation implements Scopeable
NodeRef groupRef = authorityDAO.getAuthorityNodeRefOrNull(groupName);
if (groupRef != null)
{
group = new Node(groupRef, services, scope);
group = new Node(groupRef, services, getScope());
}
return group;
}

View File

@@ -69,7 +69,7 @@ public class RhinoScriptService implements ScriptService
private ServiceRegistry services;
/** List of global scripts */
private List<ScriptImplementation> globalScripts = new ArrayList<ScriptImplementation>(5);
private List<ScriptImplementation> globalScripts = new ArrayList<ScriptImplementation>();
/**
* Set the Service Registry

View File

@@ -39,7 +39,7 @@ public interface Scopeable
/**
* Set the Scriptable global scope
*
* @param scope global scope
* @param script relative global scope
*/
void setScope(Scriptable scope);
}

View File

@@ -26,29 +26,17 @@ package org.alfresco.repo.jscript;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.mozilla.javascript.Scriptable;
/**
* Place for general and miscellenous utility functions not already found in generic JavaScript.
*
* @author Kevin Roast
*/
public final class ScriptUtils extends BaseScriptImplementation implements Scopeable
public final class ScriptUtils extends BaseScopableScriptImplementation
{
/** Root scope for this object */
private Scriptable scope;
/** Services */
private ServiceRegistry services;
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Sets the service registry
*
@@ -86,6 +74,6 @@ public final class ScriptUtils extends BaseScriptImplementation implements Scope
public Node getNodeFromString(String nodeRefString)
{
NodeRef nodeRef = new NodeRef(nodeRefString);
return (Node)new ValueConverter().convertValueForScript(this.services, this.scope, null, nodeRef);
return (Node)new ValueConverter().convertValueForScript(this.services, getScope(), null, nodeRef);
}
}

View File

@@ -40,7 +40,6 @@ import org.alfresco.service.cmr.search.SearchService;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.mozilla.javascript.Scriptable;
/**
* Search component for use by the ScriptService.
@@ -55,7 +54,7 @@ import org.mozilla.javascript.Scriptable;
*
* @author Kevin Roast
*/
public final class Search extends BaseScriptImplementation implements Scopeable
public final class Search extends BaseScopableScriptImplementation
{
/** Service registry */
private ServiceRegistry services;
@@ -63,9 +62,6 @@ public final class Search extends BaseScriptImplementation implements Scopeable
/** Default store reference */
private StoreRef storeRef;
/** Root scope for this object */
private Scriptable scope;
/**
* Set the default store reference
*
@@ -86,14 +82,6 @@ public final class Search extends BaseScriptImplementation implements Scopeable
this.services = services;
}
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
public void setScope(Scriptable scope)
{
this.scope = scope;
}
/**
* Find a single Node by the Node reference
*
@@ -251,7 +239,7 @@ public final class Search extends BaseScriptImplementation implements Scopeable
for (ResultSetRow row: results)
{
NodeRef nodeRef = row.getNodeRef();
set.add(new Node(nodeRef, services, this.scope));
set.add(new Node(nodeRef, services, getScope()));
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.repo.template;
import org.alfresco.service.cmr.repository.TemplateExtensionImplementation;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateService;
/**
* Abstract base class for a template extension implementation
*
* @author Kevin Roast
*/
public abstract class BaseTemplateExtensionImplementation implements TemplateExtensionImplementation
{
/** The template service instance */
private TemplateService templateService;
/** The name of the template extension */
private String extensionName;
/** The TemplateImageResolver for the current template execution thread */
private ThreadLocal<TemplateImageResolver> resolver = new ThreadLocal<TemplateImageResolver>();
/**
* @param templateService The TemplateService to set.
*/
public void setTemplateService(TemplateService templateService)
{
this.templateService = templateService;
}
/**
* @see org.alfresco.service.cmr.repository.TemplateExtensionImplementation#setTemplateImageResolver(org.alfresco.service.cmr.repository.TemplateImageResolver)
*/
public void setTemplateImageResolver(TemplateImageResolver resolver)
{
this.resolver.set(resolver);
}
/**
* @see org.alfresco.service.cmr.repository.TemplateExtensionImplementation#getTemplateImageResolver()
*/
public TemplateImageResolver getTemplateImageResolver()
{
return this.resolver.get();
}
/**
* Registers this template extension with the Template Service
*/
public void register()
{
this.templateService.registerExtension(this);
}
/**
* Returns the name of the template extension
*
* @return the name of the template extension
*/
public String getExtensionName()
{
return extensionName;
}
/**
* @param extensionName The template extension name.
*/
public void setExtensionName(String extensionName)
{
this.extensionName = extensionName;
}
}

View File

@@ -32,8 +32,6 @@ import org.alfresco.repo.jscript.CategoryTemplateNode;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.namespace.QName;
@@ -42,19 +40,29 @@ import org.alfresco.service.namespace.QName;
*
* @author Andy Hind
*/
public final class Classification
public class Classification extends BaseTemplateExtensionImplementation
{
private ServiceRegistry services;
private TemplateImageResolver imageResolver;
private StoreRef storeRef;
public Classification(StoreRef storeRef, ServiceRegistry services, TemplateImageResolver imageResolver)
/**
* Sets the service registry
*
* @param services the service registry
*/
public void setServiceRegistry(ServiceRegistry services)
{
this.storeRef = storeRef;
this.services = services;
this.imageResolver = imageResolver;
}
/**
* @param storeUrl The store ref url to set.
*/
public void setStoreUrl(String storeUrl)
{
this.storeRef = new StoreRef(storeUrl);
}
/**
* Find all the category nodes in a given classification.
*
@@ -110,7 +118,7 @@ public final class Classification
ArrayList<CategoryTemplateNode> categoryNodes = new ArrayList<CategoryTemplateNode>(cars.size());
for (ChildAssociationRef car : cars)
{
categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, this.imageResolver));
categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, getTemplateImageResolver()));
}
return categoryNodes;
}

View File

@@ -43,7 +43,7 @@ import freemarker.template.TemplateNumberModel;
* dateCompare(dateA, dateB) - 1 if dateA if greater than dateB
* dateCompare(dateA, dateB, millis) - 1 if dateA is greater than dateB by at least millis, else 0
*/
public final class DateCompareMethod implements TemplateMethodModelEx
public class DateCompareMethod extends BaseTemplateExtensionImplementation implements TemplateMethodModelEx
{
/**
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)

View File

@@ -34,10 +34,8 @@ import freemarker.template.TemplateNumberModel;
/**
* @author Roy Wetherall
*
*/
public final class DateIncrementMethod implements TemplateMethodModelEx
public class DateIncrementMethod extends BaseTemplateExtensionImplementation implements TemplateMethodModelEx
{
/**
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)

View File

@@ -35,6 +35,7 @@ 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.TemplateException;
import org.alfresco.service.cmr.repository.TemplateExtensionImplementation;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.repository.TemplateProcessor;
@@ -100,7 +101,7 @@ public class FreeMarkerProcessor implements TemplateProcessor
{
this.contentService = contentService;
}
/**
* Set the default template encoding
*
@@ -338,18 +339,13 @@ public class FreeMarkerProcessor implements TemplateProcessor
// current date/time is useful to have and isn't supplied by FreeMarker by default
model.put("date", new Date());
// Session support
model.put("session", new Session(services, imageResolver));
// Classification support
model.put("classification", new Classification(companyHome.getStoreRef(), services, imageResolver));
// add custom method objects
model.put("hasAspect", new HasAspectMethod());
model.put("message", new I18NMessageMethod());
model.put("dateCompare", new DateCompareMethod());
model.put("incrementDate", new DateIncrementMethod());
// add the template extensions to the model
// the extensions include custom root helper objects and custom template method objects
for (TemplateExtensionImplementation ext : services.getTemplateService().getExtensions())
{
ext.setTemplateImageResolver(imageResolver);
model.put(ext.getExtensionName(), ext);
}
return model;
}

View File

@@ -24,14 +24,11 @@
*/
package org.alfresco.repo.template;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.namespace.QName;
import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.StringModel;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
@@ -44,9 +41,9 @@ import freemarker.template.TemplateScalarModel;
* Method returns whether a TemplateNode has a particular aspect applied to it. The aspect
* name can be either the fully qualified QName or the short prefixed name string.
* <p>
* Usage: hasAspect(TemplateNode node, String aspect)
* Usage: hasAspect(TemplateNode node, String aspect) - 1 on true, 0 on false
*/
public final class HasAspectMethod implements TemplateMethodModelEx
public class HasAspectMethod extends BaseTemplateExtensionImplementation implements TemplateMethodModelEx
{
/**
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)

View File

@@ -37,11 +37,11 @@ import freemarker.template.TemplateScalarModel;
*
* Custom FreeMarker Template language method.
* <p>
* Method an I18N message resolved for the current locale and specified message ID.
* Returns an I18N message resolved for the current locale and specified message ID.
* <p>
* Usage: message(String id)
*/
public final class I18NMessageMethod implements TemplateMethodModelEx
public class I18NMessageMethod extends BaseTemplateExtensionImplementation implements TemplateMethodModelEx
{
/**
* @see freemarker.template.TemplateMethodModel#exec(java.util.List)

View File

@@ -32,20 +32,20 @@ import org.alfresco.service.cmr.repository.TemplateImageResolver;
*
* @author Andy Hind
*/
public class Session
public class Session extends BaseTemplateExtensionImplementation
{
private ServiceRegistry services;
@SuppressWarnings("unused")
private TemplateImageResolver imageResolver;
public Session(ServiceRegistry services, TemplateImageResolver imageResolver)
/**
* Sets the service registry
*
* @param services the service registry
*/
public void setServiceRegistry(ServiceRegistry services)
{
this.services = services;
this.imageResolver = imageResolver;
}
/**
* Get the current authentication ticket.
*

View File

@@ -26,11 +26,15 @@ package org.alfresco.repo.template;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.ScriptImplementation;
import org.alfresco.service.cmr.repository.TemplateException;
import org.alfresco.service.cmr.repository.TemplateExtensionImplementation;
import org.alfresco.service.cmr.repository.TemplateProcessor;
import org.alfresco.service.cmr.repository.TemplateService;
import org.apache.commons.logging.Log;
@@ -40,6 +44,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* Implementation of the TemplateService using Spring configured template engines.
*
* @author Kevin Roast
*/
public class TemplateServiceImpl implements TemplateService, ApplicationContextAware
@@ -58,6 +64,10 @@ public class TemplateServiceImpl implements TemplateService, ApplicationContextA
/** Threadlocal instance for template processor cache */
private static ThreadLocal<Map<String, TemplateProcessor>> processors = new ThreadLocal<Map<String, TemplateProcessor>>();
/** List of global template extensions */
private List<TemplateExtensionImplementation> globalExtensions = new ArrayList<TemplateExtensionImplementation>();
/**
* Set the application context
*
@@ -68,6 +78,22 @@ public class TemplateServiceImpl implements TemplateService, ApplicationContextA
this.applicationContext = applicationContext;
}
/**
* @see org.alfresco.service.cmr.repository.TemplateService#registerExtension(org.alfresco.service.cmr.repository.TemplateExtensionImplementation)
*/
public void registerExtension(TemplateExtensionImplementation extension)
{
this.globalExtensions.add(extension);
}
/**
* @see org.alfresco.service.cmr.repository.TemplateService#getExtensions()
*/
public List<TemplateExtensionImplementation> getExtensions()
{
return this.globalExtensions;
}
/**
* @param defaultTemplateEngine The default Template Engine name to set.
*/

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.repository;
/**
* Interface to represent a server side template extension implementation
*
* @author Kevin Roast
*/
public interface TemplateExtensionImplementation
{
/**
* Returns the name of the template extension
*
* @return the name of the template extension
*/
String getExtensionName();
/**
* Set the template image resolver for this extension
*
* @param resolver TemplateImageResolver
*/
void setTemplateImageResolver(TemplateImageResolver resolver);
/**
* Get the template image resolver for this extension
*
* @return TemplateImageResolver
*/
TemplateImageResolver getTemplateImageResolver();
}

View File

@@ -25,6 +25,7 @@
package org.alfresco.service.cmr.repository;
import java.io.Writer;
import java.util.List;
import org.alfresco.service.Auditable;
import org.alfresco.service.PublicService;
@@ -111,4 +112,20 @@ public interface TemplateService
*/
@Auditable(warn = true, parameters = {"engine"})
public TemplateProcessor getTemplateProcessor(String engine);
/**
* Registers a template extension implementation with the Template service
*
* @param extension the template extension implementation
*/
@Auditable(parameters = {"extension"})
public void registerExtension(TemplateExtensionImplementation extension);
/**
* Returns a list of the Template Extension objects configured for this service
*
* @return list of the Template Extension objects configured for this service
*/
@Auditable(warn = true, recordReturnedObject = false)
public List<TemplateExtensionImplementation> getExtensions();
}