Alfresco’s highly customizable repository can often seem overwhelming. Learn approaches for adding common customizations requests (Extending Javascript API, Content Modeling, Permission Modeling, packaging, etc.) from current and former Alfresco consulting staff. Learn where we often see the most common errors and participate in open Q&A.
2. Pre - Install!
Environment Validation Tool or EVT
• Available on Google Code !
• (http://code.google.com/p/alfresco-environment-validation/)!
• Currently targets version 3.3 (though mostly still
applicable)!
• Maintained by Support!
Zero Day Config Guide or ZDC
• Enterprise Only!
• Available in the KB section of support site!
3. Donʼt Query if Donʼt Have to Query!
Know you nodes
JavaScript!
!search.findNode()!
Java!
!new NodeRef()!
4. There is a cost!
Web Scripts in the Repo? For Shame!
• Extra IO!
• To both the DB and the File System!
• Lightly used vs High usage!
6. Do you really need a type?
Important questions to ask!
• Is it likely to change frequently!
• Is it a fixed state!
7. But I really need to change that type!?!
Adding is OK
Subtraction is Not
If you must remove!
• Hide it from the users in the client!
• Mark Java references deprecated!
• NEVER modify the DB directly!
8. Donʼt Force It!
• Donʼt force your model to fit the UI!
• Sometimes the best approach is a
simple custom UI!
• The repository has capabilities
beyond what Explorer and Share!
9. We Enforce the Law!!
There was a bug the allowed you to work
incorrectly across models. We’ve fixed the
bug. This may result in broken models
when upgrading from earlier versions.
Take care to thoroughly test your models
before upgrading. You may need to not
only fix your model, but massage the data,
!
or fix your custom code.
10. Have you
tried
Turn It Off! turning it
off…
When Possible Turn off unneeded
Services
• File interfaces!
• Indexing (Less important in 4.0)!
• Quota Calculations!
• Subsystems!
11. Youʼre Using Web Services!?!
SOAP just makes me feel dirty
•
• !
*Though creating your own SOAP Client won’t be as easy as just using
Apache Chemistry
12. Bulk File System Import Tool!
Available on Google Code, not BFSIT!?!
official supported by Alfresco.
Maintained by Alfresco
Employees.!
Single purpose import:!
Read content (metadata and
versions supported) from the
Filesystem!
http://code.google.com/p/
alfresco-bulk-filesystem-import/!
20. A few things learned!
Echo --- having a build process that includes deployment
early on, is very useful.
– Building an AMP file is not as much trouble as it may seem.!
– Many folks already have an Ant or Maven build config around that
you can use (do not re-invent the wheel)!
Naming Conventions are important.
– If you plan on having multiple customizations in a single repository,
this will help avoid conflicts!
– Enterprise customers who have a mix of internal development teams
and partners must think about this from Day 1.!
23. Some Ant examples – Start/Stop Alfresco!
<target name="start-alfresco"
description="Start the Alfresco Repository">
<exec executable="/bin/sh">
<arg line='-c "${alfresco.dir}/alfresco.sh start"'/>
</exec>
</target>
<target name="stop-alfresco“
description="Stop the Alfresco Repository">
<exec executable="/bin/sh">
<arg line='-c "${alfresco.dir}/alfresco.sh stop"'/>
</exec>
</target>
24. About The Example!
This example implements a simple customization that allows
documents to be tagged as sendable.
Each document has a status and a document ID
– The document ID does not have to be the object ID and is guaranteed
to be unique in the repository.!
– The valid statuses are staged, effective and retired.!
Users must have ManageSendable Permission to change the
sendable status.
25. Extending Permissions!
Why Extend Permissions
– Allows Developers to Secure new functionality with ACLs!
– Allows Developers to Expose new combinations of low level
permissions a new role.!
Examples of Extended Permissions
– Share!
– Records Management!
Caveats and Gotchas
– If you create new permissions you will have some extra work
around security.!
26. Steps!
Create Permissions Model File
– The Records Management and Share Permissions files are good
examples!
– The DTD is another good source of documentation -- http://
wiki.alfresco.com/wiki/PermissionModelDTD!
Wire in the bean
– Add the permissionModelBootstrap bean!
– Wire in any additional permissions using Security Interceptors (if
needed)!
– Add any needed permissions to the
slingshotDocLibCustomResponse bean!
27. Permission Model Code Snippet!
<permissions>
<!-- Namespaces used in type references -->
….
<permissionSet type="senddoc:content" expose="all">
<permissionGroup name="ManageSendable" expose="true"
allowFullControl="false"/>
<!-- The low level permission to control setting the owner of a node -->
<permission name="_ManageSendable" expose="false" requiresType="false">
<grantedToGroup permissionGroup="ManageSendable" />
<requiredPermission on="node" type="sys:base" name="_ReadProperties" />
</permission>
</permissionSet>
</permissions>
29. Creating JavaScript APIs!
Why Create JavaScript APIs
– Exposes key functionality to JavaScript!
– Allows for the encapsulation of the “heavy lifting” functionality!
Some examples of how Custom Javascript APIs are used
– Called from Javascript Based webscripts!
– Unit testing underlying Java Functionality from JavaScript Scripts that
can be run with the Execute Script Action!
30. Steps!
Create the Java Class that will provide the API
– Extend the
org.alfresco.repo.jscript.BaseScopableProcessorExtension class!
– All public methods that are not setters and getters will be exposed as
JavaScript methods.!
– Make sure that you convert NodeRefs into ScriptNodes and visa
versa.!
– Make sure that arguments passed and returned are Scalars,
Scriptables, Arrays or Maps.!
Wire in the bean
– Extend the baseJavaScriptExtension bean!
– Set the extensionName property!
31. Code Snippet!
public class SendableScriptAPI extends
BaseScopableProcessorExtension {
// Code Omitted
public ScriptNode getNodeRefById(String docId) {
NodeRef result = sendableService.getNodeRefById(docId);
return new
ScriptNode(result, this.serviceRegistry, getScope());
}
public void makeSendable(ScriptNode nodeRef,String docId) {
sendableService.makeSendable(nodeRef.getNodeRef(), docId);
}
}
33. Attribute Service!
What is the Attribute Service
– Allows for the storage of arbitrary key value pairs!
– Each key can have up to 3 segments.!
– The key segments and values are all Serializables (i.e. can be
anything).!
Why Use Atrribute Service
– There are a number of use cases…..!
– Our use case – properties that must have a unique value across
nodes.!
• Allows making associations between values and nodes via the Database!
• Allows for Enforcing Uniqueness of certain Values!
– AttributeService also allowed for retrieving nodes (immediately across
all nodes in a cluster) by a property value. (This is less of an issue in
swift).!
34. Steps For Using the Attribute Server!
Determine how you will plan on using it.
– Think about the Key space – use the fact that the key is segmented.!
– Think about the core operations!
– Wrap it all in a component.!
35. Example Code Snippet…!
public static final String SENDABLE_ATTR_NAME = "..SENDABLE_ID..";
public static final String SENDABLE_DOC_ID_ATTR_NAME = "..DOC_ID..";
public void storeDocId(String doc_id,NodeRef nodeRef) {
if (attributeService.exists(SENDABLE_ATTR_NAME,
SENDABLE_DOC_ID_ATTR_NAME,doc_id)) {
// Check to see if this node has already been registered
if (!attributeService.getAttribute(SENDABLE_ATTR_NAME,
SENDABLE_DOC_ID_ATTR_NAME,doc_id).equals(nodeRef)) {
throw new SendableRuntimeException("Duplicate entry
id:"+doc_id);
}
}
attributeService.setAttribute(nodeRef,SENDABLE_ATTR_NAME,
SENDABLE_DOC_ID_ATTR_NAME,doc_id);
}