Tag: Alfresco Developer Series

Updated tutorial: Creating custom advanced workflows in Alfresco

I have published a major revision of my “Creating custom advanced workflows in Alfresco” tutorial. Major changes include:

  • The tutorial now uses the Alfresco Maven SDK to instantiate the projects and to produce and install AMPs.
  • The tutorial no longer refers to jBPM, except to give brief historical context as to why the platforms includes both jBPM and Activiti.
  • The tutorial no longer includes any references to the old Alfresco Explorer client, except where it pertains to using the Alfresco Workflow Console, which is only available as part of the Alfresco Explorer Client.
  • Significant wordsmithing and re-organization to improve style and clarity.

I have tested the steps and the code against Alfresco 4.2.e Community Edition and version 5.14 of the Activiti Process Designer for Eclipse.

By the end of the tutorial, you will know how to:

  • Create, deploy, and run business processes using Activiti embedded within Alfresco.
  • Configure Alfresco Share to display custom forms when starting Activiti workflows or managing workflow tasks.
  • Use the Alfresco Workflow Console to deploy process definitions, start workflows, and delete workflows.
  • Add business logic to your process definitions using JavaScript and Java.
  • Assign workflow tasks to users and groups.
  • Add timers to your process definitions to take an action automatically after a specific time period.

The tutorial assumes you already know how to use the Alfresco Maven SDK. If you have never used it, take a look at this tutorial. The workflow tutorial also assumes you have worked through the Custom Content Types, Custom Actions, and Intro to Web Scripts tutorials.

The source code and the tutorial itself reside in GitHub. If you find problems or want to make improvements, please fork the project, make the change, and send me a pull request.

Updated tutorial: Introduction to Alfresco Web Scripts

I have published a new version of my Introduction to Web Scripts tutorial. This is a major revision that refactors the tutorial to leverage the Alfresco Maven SDK and AMPs. In addition, I have done a little bit of reorganization to improve clarity and a lot of wordsmithing to make the tutorial more consistent with the others in the Alfresco Developer Series.

By the end of this tutorial, you will know how to:

  • Extend Alfresco with your own custom RESTful API.
  • Write web scripts that respond to GET, POST, and DELETE requests over HTTP/S and return data in both HTML and JSON.
  • Use the web scripts console to display documentation and debug info on your custom and out-of-the-box web scripts.
  • Make AJAX calls to your custom web scripts.

The tutorial assumes you already know how to use the Alfresco Maven SDK. If you don’t, take a look this tutorial.

The tutorial text and all of the source code related to it are on GitHub. If you see problems or opportunities for improvement, please fork the project and send me a pull request.

Updated tutorial: Implementing Custom Behaviors in Alfresco

I have published a major revision to my Implementing Custom Behaviors in Alfresco tutorial. I hadn’t really touched it since 2007–behaviors, the ability to bind programming logic to types, aspects, and events in Alfresco, haven’t changed at all since then.

The changes are mainly around using the Alfresco Maven SDK to produce AMPs and the addition of unit tests to the project. I also gave it a bit of a style scrub to make it more consistent with other tutorials.

The tutorial continues with the SomeCo example. In this tutorial you will create the content model and behavior needed to implement the back-end for SomeCo’s five star rating functionality. By the end of this tutorial you will know:

  • What a behavior is
  • How to bind a behavior to specific policies such as onCreateNode and onDeleteNode
  • How to write behaviors in Java as well as server-side JavaScript
  • How to write a unit test that tests your behavior

This tutorial, the source code that accompanies it, and the rest of the tutorials in the Alfresco Developer Series reside on GitHub. If you want to help with improvements, fork the project and send me a pull request.

Next week I hope to publish a major revision of the Introduction to Web Scripts tutorial.

Updated tutorial: Working with Custom Content Types in Alfresco

The Working with Custom Content Types tutorial has just been given a major revision. I’ve updated it to match the refactored code. Here is a summary of the high-level changes:

  • Instructions now assume you are using the Alfresco Maven SDK. If you haven’t played with the Alfresco Maven SDK yet, check out my recently published tutorial on the subject.
  • Removed all mention of Alfresco Explorer. The tutorial is now exclusively focused on Alfresco Share for the user interface part.
  • Removed all mention of the Alfresco Web Services API. The tutorial is now exclusively focused on CMIS as the preferred API for performing CRUD functions against the Alfresco repository.

The code and the tutorial text reside in GitHub. If you find issues or make improvements, please fork the repository and send me a pull request.

New Tutorial: Getting Started with the Alfresco Maven SDK

I’ve written a new tutorial about Getting Started with the Alfresco Maven SDK. I hope it helps newcomers to Alfresco get started writing customizations quickly. And if you are an experienced Alfresco developer who still uses Ant-based builds, I hope it motivates you to make the switch to Apache Maven.

The Alfresco Maven SDK is the preferred way to bootstrap, manage, and build your Alfresco modules. The cool thing is that you don’t need anything to get started–if you already have a JDK and Apache Maven installed, you are ready to write custom Alfresco modules for the Alfresco repository and Alfresco Share, whether you are using Community Edition or Enterprise Edition.

The tutorial itself is an HTML page on this site, but I wrote it using Markdown. It lives in a GitHub repository, along with my older tutorials on custom content types, actions, behaviors, web scripts, and advanced workflows. Those tutorials have also recently been converted to Markdown and the accompanying source code has been refactored to use the Alfresco Maven SDK and AMPs, but I am still busy revising the tutorial text to match the refactored code.

I hope that by writing these tutorials in Markdown and storing them in GitHub the Alfresco community will be more likely to help me maintain them over time by forking the repository and sending me pull requests.

Alfresco Developer Series tutorial source code now on github

The source code for the tutorials in my Alfresco Developer Series has always been available to download as a zip. But for some reason I never put it in a project where we could collaborate on it. That’s fixed now. The code’s now on github. (Note that the source code that accompanies the Alfresco Developer Guide is on Google Code. I don’t intend to maintain that going forward and will instead focus on these github projects).

As part of that I’ve made sure that the content types, behaviors, actions, web scripts, and workflow tutorial code works on 4.0.d and 4.2.c. The original zips referenced in the tutorial PDF still work with the versions they were written for, of course, but if you grab the source from github, they’ll work on the version they are tagged for.

One thing I’ve realized as part of this is that with the actual tutorials in PDF, keeping the written instructions in sync with the code is tough. Maybe I should convert the tutorial text into markdown or something similar and check that into the source code repo as well. Let me know what you think about that idea.

Next step for the code is to convert from the old Ant-based Alfresco SDK to the new Maven-based SDK.

Alfresco tutorial: Advanced Workflows using Activiti

In 2007, I wrote a tutorial on Alfresco’s advanced workflows which I later used as the basis for the workflow chapter in the Alfresco Developer Guide. It showed examples using jBPM and the old Alfresco Explorer web client.

Then, in April of 2011 I posted a short article comparing Alfresco workflows built with jBPM to the same workflows built with Activiti, the new advanced workflow engine embedded in Alfresco 4. The article provided a quick glimpse into the new Activiti engine aimed at those who had heard about the Alfresco-sponsored project.

Today I’m making available the 2nd edition of the advanced workflow tutorial. It combines the SomeCo whitepaper example from 2007 with a few hello world examples to show you how to use the Activiti Process Designer Eclipse plug-in and the Activiti engine to design and run the example workflows, including how to configure your workflows in the Alfresco Share web client.

The accompanying source code builds on the workflow model and associated customizations created in the 2nd editions of the custom content types and custom actions tutorials.

UPDATE 7/18/2013: Thanks to a user on #alfresco who reported a bug in the sample workflows that have a UI. None of those workflows could be started in Alfresco Community Edition 4.2.c. I have corrected the bug. So if you are using 4.2.c, please use this zip instead.

Special thanks go to Joram Barrez and Tijs Rademakers for reviewing the tutorial and providing valuable feedback. Both are on the Activiti team. In fact, Tijs has been working on an Activiti book called Activiti in Action which should be out soon, so keep an eye out for that.

Anyway, take a look and let me know what you think.

Alfresco Tutorial: Custom actions including Share configuration

I’ve published a revision of my original Alfresco custom actions tutorial. The second edition greatly expands on the first by adding a UI action example. The original included only a rule action example. Just like the second edition of the content types tutorial, I’ve added instructions on how to configure the actions in Alfresco Share. The Alfresco Explorer steps are still there–they’ve been moved to the Appendix.

The code that accompanies the tutorial builds on the content types tutorial, so it includes the SomeCo content model and the user interface configuration needed to expose that to the Alfresco Share and Alfresco Explorer user interface.

This should be helpful to anyone who read the first edition who now wants to learn how to do the same thing using Alfresco Share, including some of the new extension points available in Alfresco 4.

Take a look and tell me what you think.

Alfresco tutorial: Custom content types including Share config and CMIS

UPDATE (2014): I’ve moved the tutorial and the source code to GitHub. The HTML version of the tutorial is here. It has been updated for Maven and AMPs.

It is hard to believe that the original version of my “Working With Custom Content Types” tutorial for Alfresco is almost five years old. That page has had over 37,000 unique visits since it was posted. It makes sense that it would be popular–creating a content model, exposing it to the user interface, and then performing CRUD functions against the repository through code are the first steps for most Alfresco development projects.

The fundamentals of content modeling haven’t changed since 2007, but since the original tutorial was posted the Alfresco Share web client has replaced Alfresco Explorer as the preferred user interface and the Content Management Interoperability Services (CMIS) API has become the first choice for writing remote code against the repository. That, combined with the influx of newcomers to the platform and a continued demand for how-to’s on the basics motivated me to revise the tutorial.

The second edition moves the Alfresco Explorer configuration to the Appendix and replaces it with steps for doing the same thing in Alfresco Share. I also moved the Java Web Services API to the Appendix and replaced that with Java examples that leverage the Apache Chemistry OpenCMIS API to create, update, query, and delete content in the repository. I’m executing the same queries as the first edition, just implemented using CMIS, so if you want to compare Lucene queries to CMIS Query Language, this is one place to do it.

I tested the document and the %

Grasping Thumbnails in Alfresco 3

With Alfresco 3 (both Labs and Enterprise), Alfresco added a new thumbnail service. It isn’t documented too well yet so I thought I’d write up a quick example.

What is it

The Thumbnail Service is used to create alternate renditions of objects. Typically, those alternate renditions are small images called “thumbnails”. You can see a working application of the thumbnail service if you take a look at Alfresco Share’s document library. When you upload a document, the thumbnail service is invoked, and a small image is shown next to each item in the list.

Where thumbnails live

Like everything else in Alfresco, thumbnails are stored as nodes. Nodes are instances of cm:thumbnail and are stored as children of the object they represent. (You can see this for yourself by looking at the thumbnailed object in the node browser). Objects can have any number of thumbnails. This lets you have thumbnails of different sizes and mime types, for example.

Once Alfresco generates a thumbnail for an object, the object will have the cm:thumbnailed aspect applied to it so it is easy to find or filter objects based on whether or not they have at least one thumbnail.

Thumbnail definitions & thumbnail names

Every thumbnail has a thumbnail definition. The thumbnail definition keeps track of things like the mime type, transformation options, placeholder path, and thumbnail name. The thumbnail name uniquely identifies the thumbnail definition in the thumbnail registry. When you want to generate or display a thumbnail for an object, you must specify the name. For example, given a thumbnail definition named “scImageThumbnail”, you could use JavaScript to create a thumbnail for an object by calling the “createThumbnail” method on a ScriptNode like this:

document.createThumbnail("scImageThumbnail", true);

The first argument is the name of the thumbnail definition. The second argument says the thumbnail should be generated asynchronously.

Registering thumbnail definitions

The thumbnail registry needs to know about your thumbnail definitions. The out-of-the-box thumbnails are registered in the thumbnail-service-context.xml file. I don’t see a clean way to extend that without repeating the definitions, so in my example, I wrote a bean that calls the Thumbnail Registry and registers the custom thumbnail definitions provided in the Spring context file:


public class ThumbnailRegistryBootstrap {
  private ThumbnailService thumbnailService;
  private List<ThumbnailDefinition> thumbnailDefinitions;
  private Logger logger = Logger.getLogger(ThumbnailRegistryBootstrap.class);

public void init() {
  ThumbnailRegistry thumbnailRegistry = thumbnailService.getThumbnailRegistry();
    for (ThumbnailDefinition thumbDef : thumbnailDefinitions) {
      logger.info("Adding thumbnail definition:" + thumbDef.getName());
      thumbnailRegistry.addThumbnailDefinition(thumbDef);
    }
}

public void setThumbnailService(ThumbnailService thumbnailService) {
  this.thumbnailService = thumbnailService;
}

public void setThumbnailDefinitions(
  List<ThumbnailDefinition> thumbnailDefinitions) {
  this.thumbnailDefinitions = thumbnailDefinitions;
}

}

So this class will add all of my thumbnail definitions to the thumbnail registry. The class and the definitions are configured in a Spring context file. The config for a single thumbnail called “scImageThumbnail” which is a PNG 100 pixels high and retains the original aspect ratio of the image would be:


<bean id="someco.thumbnailRegistry"
 class="com.someco.thumbnails.ThumbnailRegistryBootstrap"
 depends-on="ThumbnailService"
 init-method="init">
  <property name="thumbnailService" ref="ThumbnailService" />
  <property name="thumbnailDefinitions">
    <list>
      <bean class="org.alfresco.repo.thumbnail.ThumbnailDefinition">
        <property name="name" value="scImageThumbnail" />
        <property name="mimetype" value="image/png"/>
        <property name="transformationOptions">
          <beanĀ  class="org.alfresco.repo.content.transform.magick.ImageTransformationOptions">
            <property name="resizeOptions">
              <bean class="org.alfresco.repo.content.transform.magick.ImageResizeOptions">
              <property name="height" value="100"/>
              <property name="maintainAspectRatio" value="true"/>
              <property name="resizeToThumbnail" value="true" />
            </bean>
          </property>
        </bean>
     </property>
     <property name="placeHolderResourcePath" value="alfresco/extension/thumbnail/thumbnail_placeholder_scImageThumbnail.png" />
   </bean>
 </list>
 </property>
</bean>

The placeholder is a graphic that the thumbnail service can return as the thumbnail if the thumbnail for a given node has not been generated. In my example I just copied one of the out-of-the-box placeholders and renamed it but you could use anything you want there.

Example

I built a simple example to show how this works. Here is a screencast that shows it running or you can download the source and build it yourself.

In the example, a simple form is presented to allow a file to be uploaded. The form posts to a web script which creates a new node using the file provided. The form GET and POST web scripts are essentially the “helloworldform” web scripts from the Alfresco Developer Guide.

The “image list” is a simple GET web script that queries the folder where the images are uploaded to and writes out a list of image tags. The interesting thing to note here is the URL that’s used:

${url.serviceContext}/api/node/workspace/SpacesStore/${image.id}/content/thumbnails/scImageThumbnail?ph=true&c=queue

That URL is an out-of-the-box web script that returns the specified thumbnail for a given node reference. In my example I’m using the “ph” and “c” arguments. The “ph” argument says whether or not the placeholder image should be returned if the thumbnail does not exist. The “c” argument says that if a thumbnail doesn’t exist, queue a request for thumbnail creation. (Note that the descriptor says the queue create argument is “qc” but if you look at the controller source you’ll see it is actually just “c”. I’ll check to see if there’s a Jira on that).

When you add a new image and then go to the image list you’ll see the placeholder graphic. Behind the scenes, a thumbnail creation request has been queued. If you refresh the page, the thumbnail should show up because Alfresco has had a chance to generate it. If you wanted to queue the request when the node is created, you could either create a rule on the folder that holds the images, or you could add a call to “createThumbnail” in the upload POST web script controller, as shown earlier. (I’ve got an example of that commented out in the source).

That’s it

Hopefully this has given you some insight into the new thumbnail service in Alfresco. If you want to play with it yourself, you can download the source for the example and build it with Ant (make sure you set build.properties to match your environment first) by running “ant deploy”. Make sure you’ve got ImageMagick installed on your Alfresco server–the thumbnail service depends on it. You’ll also need the SDK to compile the registry bootstrap class. If you want to see what the thumbnail service is actually doing you’ll need the Alfresco source. None of the thumbnail source is included in the source code that currently accompanies the SDK.