You are on page 1of 133

Alfresco 3.

1
Configuration and Customisation Exercises

Alfresco 3.1

Installing and Using Alfresco Exercises

Contents
MODULE 1 EXERCISES ............................................................................................................................. I EXERCISE 1.01 FAMILIARISING YOURSELF WITH THE DOMAIN MODEL........................................................ I EXERCISE 1.02 USING THE NODE BROWSER ................................................................................................ I MODULE 2 EXERCISES ............................................................................................................................II EXERCISE 2.01 CREATE NEW ASPECT PROJECT PROPERTIES ................................................................... II EXERCISE 2.02 ADVANCED SEARCH .......................................................................................................... II MODULE 3 EXERCISES .......................................................................................................................... III EXERCISE 3.01 WRITE A BASIC TEMPLATE ................................................................................................ III EXERCISE 3.02 PRINTING YOUR USERNAME ............................................................................................. III EXERCISE 3.03 GETTING THE NUMBER OF CHILD NODES ........................................................................... III EXERCISE 3.04 LINKING TO CONTENT ...................................................................................................... III EXERCISE 3.05 DISPLAYING DATES AND NUMBERS.................................................................................. III EXERCISE 3.06 PERFORMING A SEARCH....................................................................................................IV MODULE 4 EXERCISES ............................................................................................................................ V EXERCISE 4.01 CREATING NEW DOCUMENTS ............................................................................................ V EXERCISE 4.02 ADDING ASPECTS .............................................................................................................. V EXERCISE 4.03 EXECUTING SEARCHES ...................................................................................................... V MODULE 5 EXERCISES .......................................................................................................................... VI EXERCISE 5.01 CREATING A BASIC WEB SCRIPT .......................................................................................VI EXERCISE 5.02 ADDING A JAVASCRIPT CONTROLLER ...............................................................................VI EXERCISE 5.03 OVERRIDING WEB SCRIPTS...............................................................................................VI MODULE 6 EXERCISES ......................................................................................................................... VII EXERCISE 6.01 CLIENT CONFIG ACTIONS ............................................................................................ VII EXERCISE 6.02 SERVER CONFIG CATEGORIES ...................................................................................... VII EXERCISE 6.03 SERVER CONFIG TRANSFORMATIONS .......................................................................... VII

Installing and Using Alfresco Exercises - i

Module 1 Exercises
Exercise 1.01 Familiarising yourself with the domain model
1. Find and open contentModel.xml and spend time viewing it. Make yourself familiar with the <type> and <aspect> tags. 2. Find and open applicationModel.xml and spend time viewing it. Make yourself familiar with the <type> and <aspect> tags. 3. Find and open systemModel.xml and spend time viewing it. Make yourself familiar with the <type> and <aspect> tags. 4. Find and open dictionaryModel.xml and spend time viewing it. Make yourself familiar with the <type> and <aspect> tags.

Exercise 1.02 Using the node browser


1. Use the Alfresco node browser to browse to the Company Home node and the spaces within it. 2. View the nodes Properties and Aspects. 3. Use a Lucene search to find the node in the system with description User managed definitions (Hint: use cm:description attribute). 4. Create a new space called Marketing within Company Home and use a Lucene PATH query to return the node (Hint: The association name should be cm:Marketing).

Module 2 Exercises
Exercise 2.01 Create new Aspect Project Properties
5. Create a new Aspect named Project Properties. 6. You can use the example namespace my or if you wish create a new namespace. 7. Give the aspect a logical referenceable name like my:projectproperties. 8. create properties like: my:projectname my:projectclient my:projectdeveloper my:projectteamleader my:projectmanager my:projectstartdate my:projectenddate

9. Make all the properties in the aspect mandatory. 10. Remember to add the aspect you created to the web-client-config-custom.xml in order to be able to use it in the web client. 11. Restart the alfresco server and create a space called projects. 12. Add a rule to the space that will apply the Project Properties aspect to any content added to the projects space. 13. Test the rule by adding some content to the projects space.

Exercise 2.02 Advanced Search


Make due date on effectivity searchable. Tomcat/shared/classes/alfresco/extension. Rename sample file.

14. Edit <extension>/web-client-config-custom.xml. 15. Find <advanced-search> <custom-properties>

16. Add <metadata> element. <meta-data aspect= "cm:effectivity" property="cm:to" /> 17. Restart the Alfresco server. 18. Add effectivity aspect and dates for a document. 19. Go to Advanced Search and try to find the document.

Module 3 Exercises
Exercise 3.01 Write a basic template
Write a basic template helloworld.ftl which simply prints the following HTML code: <p>Hello World!</p>

Exercise 3.02 Printing your Username


Based on the template produced in Exercise 3.01, produce a further template hellouser.ftl which prints your user name in the HTML code as follows: <p>Hello World!</p> Hint Use the person.properties.userName property.

Exercise 3.03 Getting the number of child nodes


Write a template showchildren.ftl which shows the number of items in the current users home space as follows: If there are no items in the space the output should display the text There are no items in your home space. If there is only one item in the space the output should display the text There is one item in your home space. If there are two or more items in the space then the output should display the text There are X items in your home space, where X denotes the number of items found. Your output should be marked up in appropriate HTML. Hint: mynode.children?size will return the number of items in the children property on mynode.

Exercise 3.04 Linking to Content


Extend the template produced in Exercise 3.03, to list the files present in the home directory following the existing text. Each list item should appear on a new line and should show the file name contained within a hyperlink pointing to the content of the document. Your output should be marked up in appropriate HTML. Hint 1 Use the Freemarker <#list> directive. Hint 2 Use the url property of a node to get the hyperlink target.

Exercise 3.05 Displaying Dates and Numbers


Extend the template produced in Exercise 3.04, to also show the file size in bytes and the modification time of the documents. Hint 1 mynode.properties.modified will return the last modified date for a node. Hint 2 The Freemarker expression mydate?string.short will return a short string representation of the date mydate.

Exercise 3.06 Performing a Search


Modify the template produced in Exercise 3.04 to find your home space using the childByNamePath map on the companyhome node. Then, do the same thing by performing a Lucene search on the companyhome node. Which do you think is better?

Module 4 Exercises
Exercise 4.01 Creating New Documents
20. Write a script that creates a new JavaScript Test file within Company Home and sets its content to be the text This is a test JavaScript file with the mimetype text/plain. 21. Place the script inside the Scripts space within the Data Dictionary so it is picked up by the system 22. Navigate to Company Home and click More Actions and Select View Details. 23. Run the script by clicking the Run Action link on the right side and selecting Execute Script from the list. 24. Navigate to Company Home to check the file was created. 25. Delete the test file from Company Home. Hint 1 The mynode.createFile(name) function will create the file and return a reference to its node. Hint 2 You can use a nodes content property to read or set its content. You should also set the MIME type of the content, via the dummy mimetype property.

Exercise 4.02 Adding Aspects


26. Extend the script written in Exercise 4.01 to add the versionable aspect to the new file after it has been created. 27. Run the script via the Run Action wizard. 28. View the files details screen and expend the Version History section to check that versioning has been turned on. Hint Use the addAspect(aspectname) function on the new node.

Exercise 4.03 Executing Searches


Write a new script which locates the newly created file via a Lucene search on the companyhome node and sets its title property to Modified JavaScript test. Hint Use the search.luceneSearch(query) function to fetch the results of the search. You can test your search query in the Node Browser first if you wish.

Module 5 Exercises
Exercise 5.01 Creating a basic Web Script
Re-use the hellouser.ftl template you built in Exercise 3.02 to create a Web Script which does the same thing. You will need to create an XML descriptor file and place this together with the Freemarker file into the Data Dictionary.

Exercise 5.02 Adding a JavaScript controller


Add a JavaScript script to the Web Script created in the previous exercise, which sets the value of a username property in the top level of the model passed to the template. Then, modify the Freemarker template to use this value instead of retrieving it from the person object.

Exercise 5.03 Overriding Web Scripts


Copy the Web Script into the Web Script Extensions space and modify the JavaScript logic to achieve the following: If the firstName and lastName properties are set for the current user (and not empty), the users full name is passed to the template in the username property. If they are not set or are empty then the raw username should be passed over as before.

Module 6 Exercises
Exercise 6.01 Client Config Actions
29. Change the configuration for the space_details and doc_details action groups. 30. Make the create_shortcut action appear at the top of the list for both the space_details and document_details. 31. Add the Create_shortcut action to the document_browse_menu action group. 32. Restart Alfresco and test.

Exercise 6.02 Server Config Categories


33. Go to <config>/bootstrap/categories.xml 34. View the file. You will recognise the Regions Categories. 35. Under <cm:name>Southern Africa</cm:name> add a category for country Mozambique. 36. Restart Alfresco and test the category has been added. 37. Add a new Software Document Category (Training Document). 38. Add subcategories to the Training Document. Slides Software Bundles Demo Documents Course Outline

Exercise 6.03 Server Config Transformations


39. Open and view the file <config>/mimetype/mimetype-map.xml. 40. Check to see that the mime-type XHTML is available. <mimetype mimetype="application/xhtml+xml" display="XHTML"> <extension default="true">xhtml</extension> </mimetype> 41. Edit <extension>/web-client-config-custom.xml. 42. Add the following to the Action Wizards config evaluator: <transformers> <transformer name="application/xhtml+xml"/> </transformers> 43. Rename the file <extension>/transformers-custom-context.xml.sample. 44. Upload readme.html and run the new transform.

Alfresco 3.1
Installing and Using Alfresco Exercises

Alfresco 3.1

Installing and Using Alfresco Exercises

Contents
MODULE 1 EXERCISES ............................................................................................................................. 1 EXERCISE 1.01 - INSTALLATION .................................................................................................................... 1 EXERCISE 1.02 CONNECTING TO MYSQL DATABASE................................................................................ 1 MODULE 2 EXERCISES ............................................................................................................................. 2 EXERCISE 2.01 USER OPTIONS ................................................................................................................... 2 EXERCISE 2.02 MY ALFRESCO DASHBOARD .............................................................................................. 2 EXERCISE 2.03 WORKING WITH SPACES .................................................................................................... 2 EXERCISE 2.04 WORKING WITH THE SHELF ............................................................................................... 3 EXERCISE 2.05 WORKING WITH CONTENT ................................................................................................. 4 EXERCISE 2.06 ADDING CONTENT ............................................................................................................. 4 EXERCISE 2.07 CREATING AND EDITING CONTENT .................................................................................... 5 EXERCISE 2.09 DELETING SPACES/CONTENT ............................................................................................. 5 EXERCISE 2.10 SEARCHING ........................................................................................................................ 6 EXERCISE 2.11 ADVANCED SPACE WIZARD............................................................................................... 7 MODULE 3 EXERCISES ............................................................................................................................. 8 EXERCISE 3.01 COLLABORATING WITH USERS .......................................................................................... 8 EXERCISE 3.02 RECOVERING DELETED ITEMS ........................................................................................... 8 EXERCISE 3.03 DISCUSSIONS ATTACHED TO CONTENT ............................................................................. 8 MODULE 4 EXERCISES ............................................................................................................................. 9 EXERCISE 4.01 APPLYING VERSIONABLE ASPECT TO CONTENT................................................................. 9 EXERCISE 4.02 CHECK OUT AND CHECK IN ................................................................................................ 9 EXERCISE 4.03 CATEGORIZING AND ADVANCED SEARCHING ................................................................... 10 EXERCISE 4.04 ACCESSING CONTENT WITH FTP...................................................................................... 10 EXERCISE 4.05 ACCESSING CONTENT WITH WEBDAV ............................................................................ 11 EXERCISE 4.06 ACCESSING CONTENT WITH AS A SHARED NETWORK DRIVE (CIFS) ................................ 11 EXERCISE 4.07 MAPPING A NETWORK DRIVE (CIFS) ............................................................................... 11 MODULE 5 EXERCISES ........................................................................................................................... 12 EXERCISE 5.01 CONTENT ACTIONS TRANSFORMING CONTENT ............................................................ 12 EXERCISE 5.02 CONTENT ACTIONS APPLYING ASPECTS ....................................................................... 12 EXERCISE 5.03 CONTENT RULES AND ACTIONS ....................................................................................... 13 EXERCISE 5.04 SIMPLE WORKFLOW ........................................................................................................ 14 EXERCISE 5.05 COMPOUND WORKFLOW ................................................................................................. 14 MODULE 6 EXERCISES ........................................................................................................................... 16 EXERCISE 6.01 PRESENTATION TEMPLATES ON CONTENT AND SPACES .................................................. 16 EXERCISE 6.02 APPLYING CUSTOM VIEWS .............................................................................................. 16

Installing and Using Alfresco Exercises - i

Alfresco 3.1

Installing and Using Alfresco Exercises

Module 1 Exercises
Exercise 1.01 - Installation
45. If not already done, install the jdk on your machine. a. Set the standard Environment Variables (JAVA_HOME, etc). b. Set the non-standard Environment Variables (JAVA_OPTS). 46. Install OpenOffice. 47. Install Alfresco Tomcat bundle. a. Enable CIFS server and Image manipulation by adding <alfresco_home>\bin to the path Environment Variable. b. Check for port conflicts (netstat). c. Create the alfresco database. d. Start Alfresco. 48. Test your installation. a. Test Web Client. b. Test CIFS.

Exercise 1.02 Connecting to MySQL Database


49. Install MySQL Database Server c. Enable port 3306 for firewall. d. Set Environment Variable (path). e. Install MySQL Administrator. f. Install MySQL Query Browser.

50. Configure alfresco to connect to the MySQL Database. 51. Test your installation.

Installing and Using Alfresco Exercises - 1

Alfresco 3.1

Installing and Using Alfresco Exercises

Module 2 Exercises
Exercise 2.01 User Options
1. Log in as admin: username = admin password = admin 2. Modify the users properties: g. Change the users first name to your first name. h. Change the users last name to your last name. i. Change the users password to demo.

3. Change the users start location to My Alfresco.

Exercise 2.02 My Alfresco Dashboard


1. Configure your dashboard: a. Choose a 2 or 3 column display (you choose). b. Distribute the available Dashlets evenly amongst the available columns. 2. Log out and log in again to verify that the users settings are preserved.

Exercise 2.03 Working with Spaces


1. Navigate to your home space. 2. Create a space named Training. 3. Navigate into Training. Notice that the breadcrumb shows your navigation history (not the actual path), 4. Create three sub-spaces inside named Documents, Presentations, and Private 5. View Details of Documents Space. a. Use Next and Previous Item actions (top right corner of details page) to cycle around the details of all the spaces in Training. b. Take note of the Actions available in details page (right side of details page). c. Take note of the drop-down menus: Custom Views Links Properties Workflows Category Rules RSS Feed

Installing and Using Alfresco Exercises - 2

Alfresco 3.1

Installing and Using Alfresco Exercises

6. Click the Modify in the Properties menu. 7. Change the description and icon. d. Close the Properties. 8. Navigate to the Users Space inside Company Home: a. Take note of all the users home spaces. 9. Change the Icon View to Icon and Details to see the differences. a. Take note of the number of items displayed for each view. b. Change the number of spaces displayed for each view and press Enter. 10. Sort spaces and content in the Details view. a. Click the down arrow against the Name column to sort it in reverse. Click again to sort it alphabetically. b. Click the down arrow against another column to sort on it. 11. Navigating the Toolbar: c. Use The Toolbar to go to Company Home, My Home, Guest Home, My Alfresco.

Exercise 2.04 Working with the Shelf


1. Navigate to Guest Home and copy Alfresco-Tutorial.pdf to the Clipboard. 2. Return to Training (Recent Spaces or My Home). 3. Paste from clipboard. Note You can also paste a link (like a Windows style shortcut).

4. Remove from Clipboard (or Remove All). Note Does not delete the actual item.

5. Cut the just copied Alfresco-Tutorial.pdf to the Clipboard. The content remains until pasted. You can cancel the cut by removing it from the Clipboard. The icon in the Clipboard indicates whether it was from a cut or copy. 6. Paste from Clipboard to Documents. a. Navigate into Documents and paste from the Clipboard. b. Check it is no longer in Training. c. It is automatically removed from the Clipboard.

7. In Documents, click its View Details. 8. On the Actions frame, choose Create Shortcut. It adds link to space in the Shelf. Click the shortcut to navigate to the space view. 9. On the Alfresco-Tutorial.pdf, click View Details and from the Actions frame, choose Create Shortcut. It adds link to content details. a. Click Close to return to Documents b. Click the shortcut to return to the details for Alfresco-Tutorial.pdf.

Installing and Using Alfresco Exercises - 3

Alfresco 3.1

Installing and Using Alfresco Exercises

10. Select Remove Item in the Shortcuts to remove the shortcut, but not the item to which it is linked. Recent spaces remembers the last 6 spaces you visited for quick navigation.

Exercise 2.05 Working with Content


1. Navigate to Documents. 2. View Alfresco-Tutorial.pdf by clicking on its icon or name. If recognized by the browser, it is displayed directly in a new window. 3. View its details using the View Details icon. 4. Click the Modify icon (top RHS of the Properties frame). c. Change the title and description. d. Click OK to save change, but stay in Details page. 5. Download a file by clicking the icon in the properties section and choosing to save it your Windows desktop. 6. Close the Details view.

Exercise 2.06 Adding Content


1. In Documents choose the Add Content action. 2. Find any text based file to upload (example: html, txt, xml, dat). 3. When setting details of the upload, check the option to make inline editable. Only for HTML and text content. Automatically turned on for html content.

4. Check default details and click Finish. 5. Check the document has been added to Alfresco by viewing it. 6. Use Add Content to upload any word document to the Training space. Notice that Alfresco extracts metadata, such as title, automatically 7. Open the word document by clicking on it. If it can not be viewed directly in the browser, it will prompt to save or open. Important Any edits made to a document through the open prompt are on a temporary file, and are not kept automatically by Alfresco, but may be saved using Save As if available

Installing and Using Alfresco Exercises - 4

Alfresco 3.1

Installing and Using Alfresco Exercises

Exercise 2.07 Creating and Editing Content


HTML and Text content can be created and edited through the browser (inline). 1. In the Create menu in the Documents space, choose Create Content. 2. Choose HTML content, and click Next to open the WYSIWYG editor. 3. Click Next to enter details save as simple.html. Inline editable is enabled by default for HTML. Turn it on for plain text if wanted.

4. Either click Finish to complete, or Next to see a summary of changes about to be made and then click Finish. 5. Select the Edit icon for simple.html and make changes. As it is inline editable, you can use the WYSIWYG editor. 6. Save the changes. 7. Editing other content (not inline editable). 8. In Training, select the Edit for myword.doc. 9. Follow the instructions to download. a. Right-click the link and choose Save link as or Save target as. b. Choose where to save, such as the desktop. 10. Edit the file (MS Word or WordPad), make changes, and save. 11. Click the More Actions icon for myword.doc in Alfresco and choose Update. a. Browse to the Windows desktop and select the recently changed myword.doc and upload it. 12. View the document in Alfresco to see the changes have been made.

Exercise 2.09 Deleting Spaces/Content


1. Create a space Test Delete. 2. Add content/create content inside this space. 3. Create a subspace inside Test Delete. 4. Delete the Test Delete Space (play around with the various options: only delete subspaces, etc).

Installing and Using Alfresco Exercises - 5

Alfresco 3.1

Installing and Using Alfresco Exercises

Exercise 2.10 Searching


1. Quick Search from the Toolbar 2. Enter search text, e.g. system (one or more words). Searches all content (folder names, file names, and file content). Do not need to use wildcards (*) for partial word match. Use Options to search on: a. Just content b. Just content names c. Just space names d. Content and content names e. Everything (the default search option) Press ENTER to search or click search icon in the Toolbar or options menu.

3. Search results returned ordered on best match. Same options for views, use Details View to reorder results

4. View the Details of one of the matched results, then use Next and Previous Item to cycle through them 5. Close the search results using the Close Search action. 6. Select Advanced Search from the Toolbar search options. 7. On the Advanced options page, search within a space. Optionally, its sub-spaces. Matches a given category, optionally sub-categories Matches properties (Title, Description, Author) Within Date Ranges (Created, Modified)

8. Try restricting the search to Documents b. Click to specify a space c. Defaults to current space d. Click Training to navigate into sub-spaces e. Navigate into Documents f. Click OK to confirm selection Click Go Up to navigate to parent spaces/ Note

9. Clear all options using Reset All Action 10. Save a search for personal use. 11. Save another search for public use. 12. Log in as another user and try to load your publicly saved search.

Installing and Using Alfresco Exercises - 6

Alfresco 3.1

Installing and Using Alfresco Exercises

Exercise 2.11 Advanced Space Wizard


1. Navigate to the Training space. 2. Create a space using the Advanced Space Wizard action in the Create menu. 3. From scratch: a. Similar to simple Create Space b. Option to choose Space Type Folder Space Discussion Space 4. Based on existing Space: c. Choose an existing space. d. All content, sub-spaces and smart space information will be copied. e. Try creating a new space based on Training. f. Check to see that all the content has been copied too.

5. Based on a Space Template: g. Ensure you are in the Training space. h. Create a space using the Advanced Space Wizard action in the Create menu. i. j. k. Select Using a Template. Choose the Software Engineering Project template. Name the new space ProjectX. All content, sub-spaces and smart space information will be copied.

6. Creating space templates by hand. Copy or create space in the Company Home>Data Dictionary>Space Templates Just as if a normal space.

Installing and Using Alfresco Exercises - 7

Alfresco 3.1

Installing and Using Alfresco Exercises

Module 3 Exercises
Exercise 3.01 Collaborating With Users
1. Log in as admin user. 2. Create a space My Shared Space. 3. Create some Inline Editable content in this new space (example.txt). 4. Within My Shared Space, select More Actions > Manage Space Users. 5. Uncheck Inherit Parent Space Permissions and invite the Guest user as a Consumer. 6. Repeat Step 5 for the Company Home space. 7. Log out and log in as guest. 8. Navigate to My Shared Space. 9. Notice what operations you can perform within this space.

Exercise 3.02 Recovering Deleted Items


1. Log in as admin user. 2. Navigate to My Shared Space. 3. Delete the content document inside this space. 4. Select More Actions>Manage Deleted Items. 5. Click Show All and view the content item you have just deleted. 6. Notice under the Actions column you can permanently delete the item or recover it. 7. Click Recover to recover the item. 8. Allow the item to be recovered to the same place it was deleted from. Click Yes. 9. Go back to the My Shared Space space to verify the document has been recovered.

Exercise 3.03 Discussions Attached to Content


10. Log in as admin user. 11. Navigate to the document you created in My Shared Space. 12. In the list of options for that content item, click Start Discussion. 13. Give it a Subject and a Message. 14. Log in as training1 and post a reply on the discussion for that content item.

Installing and Using Alfresco Exercises - 8

Alfresco 3.1

Installing and Using Alfresco Exercises

Module 4 Exercises
Exercise 4.01 Applying Versionable Aspect to content
1. Log in as the admin user. 2. Create a space Document Management. 3. Invite user training1 to be a Coordinator on this space. 4. Create some HTML content inline my-content.html. 5. View the Properties for my-content.html. Make sure the document is inline editable.

6. Expand the Version History frame at the bottom of the page. 7. Click the link Allow Versioning. 8. Take note of the information displayed in the Version History frame. 9. Close the properties page to go back to the Document Management space. 10. Click Edit to edit the document and make some changes. 11. Go back to the documents properties and view the Version History again. What happens if two users try to edit the same document at the same time?

Exercise 4.02 Check out and check in


In the previous example, if two people tried to edit the same document at the same time, only one of the users changes would be retained, so now we must use checkout. 1. Click the Check Out icon below my-content.html. 2. Allow checked out copy to be placed in the Current Space and click Check Out. 3. Click OK. You now have 2 copies, a locked version, and a working copy. 4. Edit the working copy, and save the changes to the document. 5. Log in as training1 browse to the Document Management space and try to edit the checked out copy. Notice that only the person who checkout the document can edit it while it is checked out. Notice that the user training1 can check in the document. Can you say why?

6. Log in as training1 user, edit the document and save changes again. 7. Click the Check In icon to check in changes made to the document and unlock it. a. You can add some Version Notes. b. Uncheck Minor Change to update the major version number. c. Can optionally check in changes and keep file checked out. d. Can upload a local copy from your desktop if you wish.

Installing and Using Alfresco Exercises - 9

Alfresco 3.1

Installing and Using Alfresco Exercises

8. Click Check In. 9. View the document to see the changes have been made. 10. View the documents properties to see its version history.

Exercise 4.03 Categorizing and advanced searching


1. Log in as the admin user. 2. View the details page for my-content.html. 3. Expand the Category frame (just above the Version History frame). 4. Click Allow Categorization. We have enabled the Classifiable aspect to this document.

We now need to apply a specific category to this item. 1. Click the Change Category icon on the right side of Category frame. This is to edit the categories properties. 2. Click Select to select a category. 3. Navigate down the Regions category to select United Kingdom and add to list. 4. Select another category inside the Languages category. 5. Click OK. 6. Close the Details view of my-content.html. 7. On the top right side of the browser window, click Advanced Search. 8. Select the Show me results in the categories dropdown list. 9. Use the advanced categories to search for all documents in the United Kingdom category. 10. Notice you can also select a parent category and search all categories under the parent categories by checking the Include sub-categories box. 11. When finished, close the advanced search window.

Exercise 4.04 Accessing content with FTP


1. Open an Internet Explorer window and type in the URL: ftp://localhost/Alfresco/. 2. Log in as admin user. 3. Navigate to admin home space. 4. Create a folder FTP and add some content to it. 5. Go back to the web client and check that the FTP space has been created with the new content.

Installing and Using Alfresco Exercises - 10

Alfresco 3.1

Installing and Using Alfresco Exercises

Exercise 4.05 Accessing content with WebDAV


1. Open any Browser window and type in the URL: http://localhost:8080/alfresco/webdav. 2. Log in as admin user. 3. Navigate to the admin home page. 4. View the content you created in the FTP folder.

Exercise 4.06 Accessing content with as a shared network drive (CIFS)


1. Open any Windows Explorer window. 2. Change the URL to \\<machine name>A\Alfresco. 3. Log in as admin user. 4. Navigate to the admin home page. 5. Create a folder CIFS and add some content to it. 6. Go back to the web client and check that the CIFS space has been created with the new content.

Exercise 4.07 Mapping a network drive (CIFS)


7. In Windows, go to My Computer. 8. Click Tools > Map Network Drive. 9. Select any drive letter. 10. Change the Folder URL to \\<machine name>A\Alfresco and click Finish.

Installing and Using Alfresco Exercises - 11

Alfresco 3.1

Installing and Using Alfresco Exercises

Module 5 Exercises
Exercise 5.01 Content Actions Transforming Content
1. Log in as admin user and create a space named Images. 2. Use Add Content to upload logo.jpg into your home. 3. Copy logo.jpg to the clipboard. 4. Inside Images, create a sub-space named Web Ready. 5. Paste logo.jpg from the clipboard into Web Ready. 6. View the Details page for logo.jpg and select Run Action from the Actions menu. 7. Choose Transform and copy image to a specific space and click Next. 8. Select a required format of PNG. 9. For options put -resize 200x200. 10. For destination choose the Web Ready space. 11. Click Finish to run the action. 12. Find and view the transformed image. 13. Finally, delete logo.jpg in Images and the transformed image.

Exercise 5.02 Content Actions Applying Aspects


1. Log in as admin user and create some new HTML content. Select Create Content from the Create menu. 2. View its Details page and select the Run Action from the Actions list. 3. Choose Add aspect to item and click Next. 4. Select Dublin Core and click Next or Finish. 5. Notice the extra properties. 6. Modify the properties and add some data. 7. Close the View Details page.

Installing and Using Alfresco Exercises - 12

Alfresco 3.1

Installing and Using Alfresco Exercises

Exercise 5.03 Content Rules and Actions


1. Within the Images space, select Manage Content Rules from the More Actions menu. 2. Shows a list of all rules defined in this space. 3. Choose the Create Rule action. 4. For the rule condition, select Items with the specified MIME type. 5. Click Set Values and Add. 6. Select JPEG Image and click OK. Conditions can be removed by clicking Remove next to the condition.

7. Click Next to define the actions. 8. For the rule action, select Transform and copy image in a given format to a specific location. 9. Click Set Values and Add. 10. Select a required format of PNG. 11. For options, put -resize 200x200. 12. For destination, choose the Web Ready space. Remember that the rules will run again if the destination is the same space. This is not a problem in this example, as the rule will not match since it is now .png.

13. Click OK and click Next to move to the next page of the wizard. 14. Choose a rule Type of Inbound and give it a title of resize to png. 15. Click Next to view a summary of the rule. 16. Click Finish to save the rule. 17. Close the list of rules. 18. Paste logo.jpg into the Images space. It should still be in the clipboard from earlier, if not copy again from your home 19. There should now be a transformed copy. 20. Delete logo.jpg in Images and the transformed copy.

Installing and Using Alfresco Exercises - 13

Alfresco 3.1

Installing and Using Alfresco Exercises

Exercise 5.04 Simple Workflow


1. Within the Images space, create a space named Approved Images. 2. Go into the Web Ready space and open the Manage Content Rules page. 3. Create a new rule. 4. Set the condition to be All items. 5. Select the Add simple workflow action. 6. Enter an approve step named Approve and choose to move to Approved Images as the destination space. 7. Select No for providing a reject step. 8. Save the rule and return to the Images space. 9. Once again, paste logo.jpg into Images. 10. Go into Web Ready and select the More Actions menu for the transformed image 11. Select Approve. The image will now be moved to the Approved Images space Note Rules can be given option to apply to sub-spaces and may be run in the background. The list of rules for a space can show or hide inherited rules.

Exercise 5.05 Compound Workflow


1. Log in as admin user. 2. Navigate to space ProjectX > Documentation. 3. View the Drafts space details page. 4. In the Actions frame, click Manage Content Rules. 5. Click Create Rule. 6. Step One Select Conditions: a. Choose All Items and Add to List. b. Click Next. 7. Step Two - Select Actions: a. Add Aspect - Add the Classifiable aspect to item b. Add Aspect - Add the Versionable aspect to item c. Link Item to Category choose any category (e.g. Region>UK) d. Add simple workflow to item: Name for approve step = Request Approval And move to = Pending Approval space Choose No for Reject Flow Click OK e. You now have four Actions set up for this rule.

Installing and Using Alfresco Exercises - 14

Alfresco 3.1

Installing and Using Alfresco Exercises

8. Step Three Enter Details: a. Choose Type=Inbound b. Set Title=Drafts Rules c. Check Apply rule to sub spaces d. Uncheck Run rule in background 9. Click Next/Finish/Close. 10. Now view the Pending Approval space details page. 11. In the Actions frame click Manage Content Rules. 12. Click Create Rule. 13. Step One Select Conditions: Choose All Items and Add to List

14. Click Next. 15. Step Two - Select Actions: a. Add simple workflow to item: Name for approve step = Publish Document Action for approve step = move to Publish space Name for reject step = Reject Document Action for reject step = move to Drafts space Click OK/Next 16. Step Three Enter Details: a. Choose Type=Inbound b. Set Title=Pending Approval Rules c. Check Apply rule to sub spaces d. Uncheck Run rule in background 17. Click Next/Finish/Close. 18. Now we must test that our work flow behaves as planed a. Add content to Drafts b. Check its details to see that the aspects have been applied Check the Workflow Check the Category Check the Version History 19. For the content items actions, click Request Approval. This kicks off the workflow rule you created. Notice the item has been removed from the Drafts space. 20. Navigate to the Pending Approval space. The content item is now in this space. 21. On the content items Actions click Reject Document. The item is copied back to Drafts. 22. Repeat steps 18 to 21, and this time Approve Document.

Installing and Using Alfresco Exercises - 15

Alfresco 3.1

Installing and Using Alfresco Exercises

Module 6 Exercises
Exercise 6.01 Presentation Templates on Content and Spaces
1. Navigate to some content. 2. Click on the Content items Action Preview in Template. 3. Use the drop-down menu on the top right side of the page to view the document with various templates. doc_info.ftl general_example.ftl localizable.ftl my_summary.ftl recent_docs.ftl translatable.ftl

4. Perform steps 1 to 3 on a space. What are the differences?

Exercise 6.02 Applying Custom Views


1. Create a new Custom View Example space in Company Home. 2. View the Space Details. 3. In the top frame Custom View click on Apply Custom View. 4. Select template from the drop-down readme.ftl. 5. Close the Details view. 6. Note the contents of the custom view page. 7. Create a new HTML file called readme.html and enter some text into it. 8. Return to the space view. What can you see in the custom view area? What does this tell you about the template?

Installing and Using Alfresco Exercises - 16

Alfresco 2.1 Partner Bootcamp


Part 3 - API Development

Contents
Getting Started .......................................................................................................................... Alfresco SDK ................................................................................................................5 Introduction.............................................................................................................. 6 Downloading and Unpacking the Alfresco SDK...................................................... 7 Importing the Alfresco SDK projects into Eclipse.................................................... 9 Associating Source Code and Javadocs with the Alfresco Libraries..................... 12 SDK samples......................................................................................................... 15 SVN Repository..................................................................................................... 19 SDK Reference..................................................................................................... 20 Best Practices ............................................................................................................ 23 Coding Standards.................................................................................................. 24 Alfresco Module Packages (AMP)......................................................................... 25 Alfresco Repository Architecture ............................................................................ 27 Out of the Box....................................................................................................... 28 Service & Component Architecture....................................................................... 30 Repository Foundation Services API..................................................................... 33 Repository APIs..................................................................................................... 35 Developing against the Alfresco Repository ......................................................................... Spring Framework ..................................................................................................... 39 Introduction............................................................................................................ 40 Inversion of Control (IoC)...................................................................................... 41 Foundation Services API .......................................................................................... 43 Introduction............................................................................................................ 44 Access to Repository Foundation Services........................................................... 45 FirstFoundationClientwalkthrough......................................................................... 46 Other Foundation Services.................................................................................... 55 JCR API .......................................................................................................................57 Introduction............................................................................................................ 58 Web Services API ...................................................................................................... 59 Introduction............................................................................................................ 60 Available Web Services......................................................................................... 61 Separating Concerns using AOP ............................................................................. 63 Public Services and AOP proxies.......................................................................... 64 Extending the Alfresco Repository ......................................................................................... Repository Policies ................................................................................................... 67 Introduction............................................................................................................ 68 Available Policies.................................................................................................. 69 Policy Types.......................................................................................................... 70 Custom Aspect with Behaviour Howto.................................................................. 71 Repository Actions ....................................................................................................79 Introduction............................................................................................................ 80 Content Transformers ............................................................................................... 81 Introduction............................................................................................................ 82 Metadata Extractors .................................................................................................. 83 Introduction............................................................................................................ 84 MetadataExtracterRegistry.................................................................................... 85 Extending the Alfresco Web Client ......................................................................................... JavaServer Faces ...................................................................................................... 89 Introduction............................................................................................................ 90 Actions Framework ................................................................................................... 91 Introduction............................................................................................................ 92 Dialog Framework ......................................................................................................93 Introduction............................................................................................................ 94 Wizard Framework .....................................................................................................95

Introduction............................................................................................................ 96

Section 1
Getting Started

Getting Started - 3

4 - Getting Started

Part 3 - API Development

Alfresco SDK

Module 1
Alfresco SDK

Alfresco SDK - 5

Alfresco SDK

Part 3 - API Development

Introduction
The Alfresco SDK provides support for developers who wish to extend or customise the Alfresco platform. It has been designed for the developer to get developing with minimal fuss for the following development scenarios: Developing extensions for the Alfresco Repository and Web Client. Embedding Alfresco into applications via Alfresco's Java Foundation Services API or standards-compliant JCR API. Developing applications against a remote Alfresco Repository via Alfresco's Web Services API. Typically, the SDK is used stand-alone, but an Alfresco installation is also required if performing any of the following: Customising the Alfresco Web Client Deploying a custom module to a remote Alfresco repository Testing a custom application that connects to a remote Alfresco repository Note: The SDK is not designed for re-building Alfresco since it does not provide full build scripts and artifacts. If you wish to develop bug fixes or extend the core functionality of the Alfresco platform, you should use the full Alfresco development environment provided in the Alfresco SVN Repository. For more information, see SVN Repository on page 19 .

6 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

Downloading and Unpacking the Alfresco SDK


You will need to install the following software and development tools in order to use the SDK correctly: the Java SE Development Kit (JDK) version 1.5 (5.0) or above; a supported database of your choice (MySQL is recommended for development purposes); the Eclipse IDE 3.x (highly recommended). The Alfresco SDK bundle is provided with each release of Alfresco, for both the Enterprise and Community Networks.

1) Downloading the Alfresco SDK


The Enterprise SDK is only available to Enterprise clients and partners. The Community SDK is freely available and can be downloaded from the Download Alfresco Community Network page on the Alfresco Developer web site. The SDK is provided in both ZIP and TAR (tar.gz) formats.

2) Unpacking the Alfresco SDK


To install the SDK, simply unpack the downloaded ZIP or TAR bundle to a directory of your choice.

Alfresco SDK - 7

Alfresco SDK

Part 3 - API Development

For a description of the contents of the Alfresco SDK, see SDK Contents on page 20 .

8 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

Importing the Alfresco SDK projects into Eclipse


When using the Alfresco SDK, the Eclipse IDE is highly recommended. The SDK contains several pre-configured Eclipse projects that you can import directly into Eclipse with the following procedure.

1) Setting the Eclipse Compiler Compliance Level


Alfresco uses Java 1.5 (5.0) language features, therefore Eclipse must be configured appropriately for the Java SE Development Kit (JDK) version 1.5 (5.0) or above.

1.1) From the Eclipse main menu, select Window --> Preferences... 1.2) In the Preferences dialog, select Java --> Compiler in the tree view. 1.3) In the JDK Compliance panel, set the Compiler compliance level to 5.0 or above:

1.4) Click OK

2) Importing the Alfresco SDK projects


2.1) From the Eclipse main menu, select File --> Import... 2.2) In the Import dialog, select General --> Existing Projects into Workspace import source and click Next > 2.3) Choose Select root directory option and click Browse... 2.4) Navigate to the file system directory where you unpacked the Alfresco SDK and click OK. The Alfresco SDK projects are now listed under Projects.
Alfresco SDK - 9

Alfresco SDK

Part 3 - API Development

Note: Do not navigate to the samples sub-directory, otherwise you will not see the SDK AlfrescoEmbedded and SDK AlfrescoRemote projects in the list.

In order to run the samples or to develop your own extension modules, you must import at least the SDK AlfrescoEmbedded and SDK AlfrescoRemote projects. The other SDK projects are samples for common development scenarios that you can study and run to learn more about developing Alfresco extension modules.

10 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

2.5) Once you have selected the projects you wish to import, click Finish.
The imported projects are displayed in the Package Explorer:

Alfresco SDK - 11

Alfresco SDK

Part 3 - API Development

Associating Source Code and Javadocs with the Alfresco Libraries


Once the Alfresco SDK projects have been imported into Eclipse, it is useful to have access to Alfresco's source code and Java documentation. The following procedure explains how to do this by associating the source code and Javadocs with the Alfresco libraries within Eclipse.

1) Expand the SDK AlfrescoEmbedded project in the Project Explorer. 2) Right click on the alfresco-repository.jar and select Properties from the popup menu.
Note: The JAR files may not be in alphabetical order.

3) Associating source code


3.1) In the Properties for alfresco-repository.jar dialog, select Java Source Attachment in the tree view. 3.2) In the Java Source Attachment panel, click External File... 3.3) Navigate to src directory within your unpacked Alfresco SDK. 3.4) Select repository-src.zip and click Open.

4) Associating Javadocs
4.1) In the Properties for alfresco-repository.jar dialog, select Javadoc Location in the tree view. 4.2) In the Javadoc Location panel, select Javadoc in archive and click Browse... 4.3) Navigate to doc/api directory within your unpacked Alfresco SDK.
12 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

4.4) Select repository-doc.zip and click Open.

4.5) Click Validate... to validate the Javadoc location, then click either OK to view the Javadocs in a web browser or Cancel if not.

5) Click OK, to close the Properties dialog.


Once the source code and Javadocs have been attached, the alfresco-repository.jar icon changes to include a small document:

Alfresco SDK - 13

Alfresco SDK

Part 3 - API Development

Note: The above steps need to be repeated for the following JARs: alfresco-core.jar alfresco-remote-api.jar alfresco-web-client.jar alfresco-web-service-client.jar (only Java source code is available)

14 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

SDK samples
FirstFoundationClient and JCR Samples
The SDK FirstFoundationClient, SDK FirstJCRClient and SDK JCRSamples sample projects demonstrate how to access an embedded Alfresco repository via the Foundation Services API and the standards-compliant JCR API. These samples can be tested directly from within Eclipse and will automatically start an Alfresco repository in embedded mode. Before starting, the embedded repository needs to be configured. By default, the sample projects are configured to use a MySQL database named alfresco and a data directory with a relative path of ./alf_data. These parameters are defined in the custom-repository.properties file in the source/alfresco/extension directory of each project. It is good practice to define an absolute path for the data directory (dir.root parameter) and to configure all of the SDK projects to share the same database and the same dir.root. Example custom-repository.properties file:
dir.root=C:/alf_data #db.username=alfresco #db.password=alfresco # # MySQL connection (This is default and requires mysql-connector-java-3.1.12-bin.jar, which ships with the Alfresco server) # #db.driver=org.gjt.mm.mysql.Driver #db.url=jdbc:mysql://localhost/alfresco

The alfresco MySQL database also needs to be created using the scripts provided in the extras/databases/mysql directory of the unpacked Alfresco SDK. To create the database from the command line:
C:\alfresco-enterprise-sdk\extras\databases\mysql>mysql -u root -p < db_setup.sql Enter password: ********

The samples can now be tested by running the main Java classes from within Eclipse. In the following example, the FirstFoundationClient class is run as a Java Application:

Alfresco SDK - 15

Alfresco SDK

Part 3 - API Development

The Alfresco repository is automatically started in embedded mode. Because this is the first time the repository has been started, the initial bootstrap is executed to create the database tables. As you can see from the console messages below, the embedded repository uses C:\alf_data as it's data directory (dir.root).

The other embedded repository samples (SDK FirstJCRClient and SDK JCRSamples) can be run in the same way.

Web Services Samples


The SDK FirstWebServiceClient and SDK WebServiceSamples sample projects demonstrate how to access a remote Alfresco repository via the Web Services API. A remote Alfresco repository needs to be installed and running before testing one of these samples. Before running one of the Web Services samples, a remote repository needs to be installed and configured. The easiest solution for development purposes is to install Alfresco on the local machine and configure it to use the same alfresco MySQL database and the same C:/alf_dir data directory as the embedded repository used for the other samples.

16 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

The location of the remote repository is configured in the webserviceclient.properties file in the source/alfresco/extension directory of each Web Services project. If the remote repository is installed on the same machine and configured to use the default 8080 port, you will not have to modify the default value. Example webserviceclient.properties file:
# # Set the following property to reference the Alfresco server that you would like web service client # to communicate with repository.location=http://localhost:8080/alfresco/api

Once the remote repository has been installed and started, the Web Clients samples can be tested by running the main Java classes from within Eclipse. In the following example, the FirstWebServiceClient class is run as a Java Application:

Custom Repository Samples


The SDK CustomAction and SDK CustomAspect sample projects demonstrate how to develop custom modules that may be deployed to an Alfresco repository. Initially, custom repository modules can be developed and tested using unit tests and an embedded Alfresco repository. The SDK CustomAspect project has a sample unit test that does this. An Ant build.xml file is provided for packaging the repository samples. The package target packages the compiled classes and extension files into a JAR file. To deploy the samples, copy the JAR file to the WEB-INF/lib folder of an existing Alfresco installation and restart the application server. For deployment in a production environment, a custom repository module should be packaged as an Alfresco Module Package (AMP). For more information on creating a custom repository action, see the Repository Action Howto on page . For a detailed presentation of the SDK CustomAspect sample, see the Custom Aspect with Behaviour Howto on page 71 .

Custom Web Client Samples


The SDK CustomDialog, SDK CustomJSP, SDK CustomLogin, SDK CustomWizard, and SDK TaggingSample sample projects demonstrate how to develop custom modules for the Alfresco Web Client. Custom Web Client modules have to be deployed to an existing Alfresco installation for testing. An Ant build.xml file is provided for packaging the Web Client samples. The package-jar target packages the compiled classes and extension files into a JAR file. The package-extension target then packages the JAR file along with the JSPs into a ZIP file. The optional integrate-extension target can be used to integrate the packaged ZIP file into an Alfresco Web Client WAR file. The alfresco.war file must be copied to the same directory as the build.xml file before running the
Alfresco SDK - 17

Alfresco SDK

Part 3 - API Development

Ant build and then re-deployed to the application server. For deployment in a production environment, a custom Web Client module should be packaged as an Alfresco Module Package (AMP). The SDK CustomDialog and SDK CustomWizard are presented in detail in the Custom Dialog Howto on page and the Custom Wizard Howto on page . The SDK TaggingSample sample is presented in detail in the Repository Action Howto on page .

Basic AMP Sample


The SDK Basic AMP sample project demonstrates how to structure a project and how to arrange classes and configuration files to generate an Alfresco Module Package (AMP). For more information see Alfresco Module Packages on page .

18 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

SVN Repository
The Alfresco Subversion repository gives you access to all of the Alfresco source code and build artifacts. It provides the latest work-in-progress developments. It should only be used if you wish to extend the Alfresco core framework or work on Alfresco bug fixes as it allows you to perform full re-builds of Alfresco itself. For most requirements, it is best to use the Alfresco SDK. Public read-only access to the Alfresco Subversion repository is available from the Alfresco web site. To checkout the source code, use the following procedure: 1. Install Subversion and ensure that svn is on the path. 2. Checkout the HEAD of the code stream:
svn co svn://svn.alfresco.com/alfresco/HEAD

or
svn co http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD

3. Keep up to date by issuing the command:


svn update

Alfresco SDK - 19

Alfresco SDK

Part 3 - API Development

SDK Reference
SDK Contents
An expanded Alfresco SDK contains the following directories and top-level files: bin Supporting dll's, exe's. doc Zipped Javadoc's for all pre-built libraries. extras Additional files - database setup and migration scripts. lib Alfresco pre-built libraries (JAR files). lib/deployment Alfresco libraries required for WCM deployment to a remote server. lib/remote Alfresco libraries required for access to a remote Alfresco repository via web services. lib/server Alfresco libraries required for embedding an Alfresco repository. licenses License files. samples Sample Eclipse projects for common development scenarios (see SDK Eclipse Projects on page 20 ). src Zipped source code for all pre-built libraries. license.txt Alfresco licence file. notice.txt Notices readme.txt Alfresco SDK readme.

SDK Eclipse Projects


The Alfresco SDK contains the following pre-configured Eclipse projects: SDK AlfrescoEmbedded Project containing all of the Alfresco libraries needed to build a custom module that will be embedded into the Alfresco repository or Web Client. SDK AlfrescoRemote Project containing all of the Alfresco libraries needed to build a custom Web Services client. SDK Basic AMP Sample project demonstrating how to build an AMP (Alfresco Module Package) file. SDK CustomAction Sample project demonstrating how to develop a custom Action that may be deployed to an Alfresco repository. SDK CustomAspect Sample project demonstrating how to develop a custom Aspect with behaviour that may be deployed to an Alfresco repository. SDK CustomDialog Sample project demonstrating how to develop and configure a custom Dialog for the Alfresco Web Client. SDK CustomJSP
20 - Alfresco SDK

Part 3 - API Development

Alfresco SDK

Sample project demonstrating how to develop and configure a custom JSP for the Alfresco Web Client. SDK CustomLogin Sample project demonstrating how to override the Login page of the Alfresco Web Client. SDK CustomWizard Sample project demonstrating how to develop and configure a custom Wizard for the Alfresco Web Client. SDK FirstFoundationClient Sample project demonstrating how to access an Alfresco (embedded) repository via the Foundation Services API. SDK FirstJCRClient Sample project demonstrating how to access an Alfresco (embedded) repository via the standards-compliant JCR API. SDK FirstWebServiceClient Sample project demonstrating how to access a remote Alfresco repository via the Web Services API. SDK JCRSamples More sample projects demonstrating how to access an Alfresco (embedded) repository via the standards-compliant JCR API. SDK TaggingSample Advanced sample project demonstrating how to develop a custom Action that takes parameters. SDK WebServiceSamples More sample projects demonstrating how to access a remote Alfresco repository via the Web Services API.

Alfresco SDK - 21

Alfresco SDK

Part 3 - API Development

22 - Alfresco SDK

Part 3 - API Development

Best Practices

Module 2
Best Practices

Best Practices - 23

Best Practices

Part 3 - API Development

Coding Standards
Coding Standards - Formatting
The core coding standards are the standard Java Code Conventions . Braces are on new lines. 4 space for tabbing, except for Web Client project that uses 3 spaces. 120 characters on a line is fine. Import declarations are managed by Eclipse's standard ordering rules (CTRL-SHIFT-O). This helps prevent code merge conflicts. XML documents use 3 space tabbing. The Eclipse plug-in, XMLBuddy, is generally used.

Coding Standards - Exceptions


When generating a new exception, always attach the cause to it. Don't log exceptions unless you are adding the logic to absorb the exception. Put as much context and formatting into the error message as possible. Use RuntimeException derived exceptions, unless there is a really good reason to bother the client code with a checked exception. Pay attention to the Javadoc specification on unchecked exceptions. Don't declare them on the interface, just in the Javadocs.

Coding Standards - Logging


Use the Apache Commons Logging API so that all logging output is uniform. Use the class hierarchy categories, but where deviations are made, add comments to the Javadocs. INFO messages are only added at the request of Alfresco users. All other informative messages are DEBUG. Put as much context and formatting into the message as time will allow. Wrap all calls to logger.debug and logger.info, and only log messages if logger.isDebugEnabled and logger.isInfoEnabled respectively.

Coding Standards - File Formats


UTF-8 encoding of all text files Windows line endings (CR-LF)

24 - Best Practices

Part 3 - API Development

Best Practices

Alfresco Module Packages (AMP)


An Alfresco Module Package (AMP) is a collection of code, XML, images, CSS, etc. that collectively extend the functionality or data provided by the standard Alfresco Repository. An AMP file can contain as little as a set of custom templates or a new category. It can contain a custom model and associated UI customisations. It could contain a complete new set of functionality, for example records management. As a general rule of thumb, anything that is considered to be an installable extension to the Alfresco repository should be called a module and packaged as an AMP file. AMP files can be installed into the Alfresco WAR using the Module Management Tool. An AMP file has a standard format that can be customised if required. Once the contents of the AMP file has been mapped into an Alfresco WAR using the Module Management Tool, the WAR can be deployed to the application server. When the repository is next started, the installed module configuration will be detected, and the repository will be bootstrapped to include the new module functionality and data.

AMP Project Structure


An Alfresco Module project can be structured in any way that suits the developer environment. As long as the resulting AMP file is packaged correctly and the required property and context files are present, the module will install successfully. The recommended project structure is as follows:
\ |-- source | |-- java |-- <module package structure starts here> | |-- web |-- css |-- images |-- jsp |-- scripts | |-- config |-- <resource package structure starts here> | |-- build |-- dist |-- lib | |-- build.xml

source/java/ Contains the Java source for the Alfresco Module. source/web/ Contains any web UI resources (JSPs, images, CSS, JavaScript). config/ Contains configuration files and resources used by the module. build/ Build directory for compiled class files. build/dist/ Build directory for AMP files. build/lib/ Build directory for JAR files. The recommended package structure for Java source (source/java), configuration files and resources (config) is org.alfresco.module.<moduleid>, where moduleid is the unique

Best Practices - 25

Best Practices

Part 3 - API Development

module id of the module. Alfresco Module Packages are presented in more detail later on in the course. For more details, see Alfresco Module Packages on page .

26 - Best Practices

Part 3 - API Development

Alfresco Repository Architecture

Module 3
Alfresco Repository Architecture

Alfresco Repository Architecture - 27

Alfresco Repository Architecture

Part 3 - API Development

Out of the Box


Out-of-the-box, Alfresco's simple installation procedure provides a pre-configured deployment aimed at reaching a complete and working Content Management application as quickly and easily as possible. The deployment is as follows:

This is typical of a web architecture, where an application server houses the logic for both the user interface and domain. Storage of data and content is provided by persistent back-ends such as a database or file system. Any number of web browsers can connect to the application without prior client installation costs. In this particular case, the application server houses both the Alfresco Application and the Alfresco Repository. An Alfresco Application provides a complete solution tailored for a specific area of Content Management such as Document Management (DM), Web Content Management (WCM) and Records Management (RM). The Alfresco Repository provides a set of reusable cross-cutting Content Management services such as content storage, query, versioning and transformation which may be utilised by one or more applications. Although this is the default installed deployment, it is only one of many ways of utilising the capabilities and components of Alfresco. When we first set out to design Alfresco, we wanted to break away from
28 - Alfresco Repository Architecture

Part 3 - API Development

Alfresco Repository Architecture

the mould of typical Content Management architectures which are monolithic and closed. The result is that Alfresco can neatly fit into existing environments and each of its components may be used in isolation or together to form the basis of many differing Content Management solutions. The remainder of this module explores the anatomy of the Alfresco Repository which will give a good understanding of the concepts and capabilities and how it achieves openness, scalability and flexibility.

Alfresco Repository Architecture - 29

Alfresco Repository Architecture

Part 3 - API Development

Service & Component Architecture


Every part of the Alfresco Repository is either a component or a service. A component is an implementation black box that provides a specific feature or capability. A service is an interface entry point for a client to bind to and use. This fundamental approach allows for existing components to be switched with new implementations, new components to be added with ease and for clients to connect and use services without knowledge of how they're implemented. If there's a feature of Alfresco you don't need, you can take it out, providing a lighter and possibly faster Alfresco. If there's a feature you wish to re-implement, you can replace it, either by providing a better implementation, or integrating with your existing environment. Implementation of this approach is simplified by using the open source project Spring Framework which Alfresco has taken to heart and has made a core foundation of its architecture. With Spring, Alfresco components are declaratively configured and bound together. Aspect-oriented programming allows the weaving of infrastructure concerns such as Transactions and Security into components without polluting their implementation. Environment touch points are abstracted such as resource (e.g. database) connections. The Alfresco Repository structure looks like this:

30 - Alfresco Repository Architecture

Part 3 - API Development

Alfresco Repository Architecture

The public interface point is the Alfresco Repository Foundation Services. Each service is exposed as a Java Interface to which a Repository client can bind and invoke without knowledge of its underlying implementation. A Service Registry lists the available services. Behind services are the implementation black boxes i.e. components. Each service and component is configured via the Spring framework in XML context files. Note: The Spring context file public-service-context.xml provides the configuration and binding of the Alfresco Repository Foundation Services. The Repository Foundation Services are the lowest level of public interface providing access to all Repository capabilities. Binding to this interface is possible via the Repository Service Registry, or via Spring dependency injection if the client is also Spring aware. Access to Foundation Services is limited to Repository clients who reside in the same process as the Repository. That is, the Foundation Services are an excellent API for clients who wish to embed the Repository. An important point to note is that the Foundation Services are where transaction and security policies are enforced. The policies themselves are declaratively specified and enforced via the injection of a transaction and security implementation into each service. Every service of Alfresco is transactional and secure. Other forms of API are provided too, however, all public entry points eventually go through this layer.

Alfresco Repository Architecture - 31

Alfresco Repository Architecture

Part 3 - API Development

Alfresco supports a common scheme for making extensions to the Repository i.e. configuring a component, adding a new component or service, or removing capabilities. Extensions are encapsulated outside of the core Repository and plugged-in automatically. This means the core Repository can be upgraded to a newer version and extensions remain intact.

32 - Alfresco Repository Architecture

Part 3 - API Development

Alfresco Repository Architecture

Repository Foundation Services API


The heart of the Alfresco Repository is responsible for the storage and retrieval of content. This is split into nodes, content and index information. Nodes provide meta-data and structure to content. A node may support properties (e.g. author) and relate to other nodes (e.g. represent folder hierarchies or annotations). Content is the actual information being recorded e.g. a Word document or XML fragment. Meta-data and content may be structured according to the rules defined in a Content Model. For example, the Alfresco Document Management application relies on a model that describes Folders and Files. Indexing information allows the retrieval of meta-data and content via many different lookup options. Repository storage and retrieval is provided by the following Foundation Services: Node Service for managing meta-data i.e. nodes Content Service for managing content Search Service for performing queries By default, Alfresco has chosen to store meta-data in a database and content in a file system. Using a database immediately brings in the benefits of databases that have been developed over many years such as transaction support, scaling & administration capabilities. Content is stored in the file system to allow for very large content, random access, streaming and options for different storage devices. The Alfresco out-of-the-box implementations of the above services are built upon strong open source projects that already have many man-years of development effort and strong communities: Hibernate and Lucene.

Alfresco Repository Architecture - 33

Alfresco Repository Architecture

Part 3 - API Development

Apart from the strong Object/Relational mapping that Hibernate provides, it also brings pluggable caching support and SQL dialects. The first allows for tuning of the Alfresco meta-data store to provide optimum read and write performance in both single and clustered environments. The second allows for nearly any SQL database back-end by configuring just two properties; the Alfresco community has already confirmed working support for MySQL, Oracle, DB2, Sybase, SQL Server. By externalising the indexing of meta-data and content and using the Lucene engine as a basis, it is possible to perform complex queries which combine property, location, classification and full-text predicates in a single query against any content type. Multiple query languages are supported including Lucene's native language as well as XPath and a SQL-like language in the future. To ensure reliable operation, transactional support has been added to both Lucene and the content file store providing ACID operations across the complete store. Security is woven into each of the service layer ensuring illegal modifications are not permissible and hidden meta-data and content are not returned. Nearly all other Foundation services and clients rely upon these three core building blocks.

34 - Alfresco Repository Architecture

Part 3 - API Development

Alfresco Repository Architecture

Repository APIs
The Alfresco Repository actually provides three APIs. We've already seen one - the Repository Foundation Services - a set of local Java Interfaces covering all capabilities which are ideal for clients who wish to embed the Repository. The two other APIs are: JCR Web Services JCR (Content Repository API for Java Technologies) is a standard Java API (as defined by JSR-170) for accessing Content Repositories. Alfresco provides support for level 1 and level 2 giving standardised read and write access. Supporting this API provides the following benefits: No risk: The Alfresco Repository can be trialled and developed against, but swapped out with another JCR Repository if it does not fit requirements. Familiarity: Developers who know JCR, know Alfresco. Tools: Tools, Clients and other 3rd Party JCR solutions are immediately available to the Alfresco community. Alfresco JCR is implemented as a light facade on top of the Repository Foundation Services. So, although a familiar API is provided, it sits upon a fully transactional, secure and scalable Repository which supports many deployment options. Alfresco will continue investment in JCR by both broadening the compliance of the full specification as well driving forward JSR-283, the next version of the JCR. Web Services is the final API provided by the Alfresco Repository. This API supports remote access and bindings to any client environment, not just Java. For example, the Alfresco community is already using PHP, Ruby and Microsoft .NET. Numerous standards and integration efforts are focused around Web Services - SOA is now recognised as a way forward for integrating disparate systems including Content Management and building new enterprise-wide solutions. BPEL plays an important role in orchestrating all of these services. Alfresco fits neatly into this way of thinking.

Alfresco Repository Architecture - 35

Alfresco Repository Architecture

Part 3 - API Development

Once again, the Repository Foundation Services serve as the base. Both the JCR and Web Services API eventually go through this layer meaning that all encapsulated content model logic and rules are honoured.

36 - Alfresco Repository Architecture

Section 2
Developing against the Alfresco Repository

Developing against the Alfresco Repository - 37

38 - Developing against the Alfresco Repository

Part 3 - API Development

Spring Framework

Module 1
Spring Framework

Spring Framework - 39

Spring Framework

Part 3 - API Development

Introduction
The Spring Framework is a full-stack Java/JEE application framework. Spring's main aim is to make J2EE easier to use and promote good programming practise. It does this by enabling a POJO-based programming model remaining faithful to the fundamental ideas of Expert One-on-One J2EE Design and Development. Spring is portable between application servers.

40 - Spring Framework

Part 3 - API Development

Spring Framework

Inversion of Control (IoC)


Through its bean factory concept, Spring is an Inversion of Control container. Spring is most closely identified with a flavour of Inversion of Control known as Dependency Injection. The concept behind Inversion of Control is often expressed in the Hollywood Principle: Don't call me, I'll call you. IoC moves the responsibility for making things happen into the framework, and away from application code. Whereas your code calls a traditional class library, an IoC framework calls your code.

Dependency Injection
Dependency Injection is a form of IoC that removes explicit dependencies on container APIs. Ordinary Java methods are used to inject dependencies such as collaborating objects or configuration values into application object instances. The two major flavors of Dependency Injection are: Setter Injection (injection via JavaBean setters) Constructor Injection (injection via constructor arguments). Spring provides sophisticated support for both, and even allows you to mix the two when configuring the one object.

Setter Injection Example


This example shows you how the Bean Factory can automatically call setter methods to initialise property values on objects it has instantiated.

1) Writing a simple JavaBean class


This simple JavaBean supports properties. The values of the properties are set by the Spring Bean Factory when the bean is instantiated.
package ex02_setter; public class Bean1 { public void setString(String val) { m_strVal = val; } public String getString() { return m_strVal; } public void setInt(int val) { m_intVal = val; } public int getInt() { return m_intVal; } public void setList(List strings) { m_strings = strings; } public List getList() { return m_strings; } private String m_strVal; private int m_intVal; private List m_strings; }

2) Defining the Spring beans


A single bean is defined with initial values for the properties that will be initialised via the setter methods on the JavaBean:
<beans> <bean id="bean1" class="ex02_setter.Bean1"> <property name="string"> <value>a string</value> </property> <property name="int"> <value>125</value> </property> <property name="list"> <list> <value>item1</value> <value>item2</value>

Spring Framework - 41

Spring Framework

Part 3 - API Development

<value>item3</value> </list> </property> </bean> </beans>

3) Testing with a Main program


We retrieve bean1 from the Bean Factory and print out the values of the properties:
Bean1 bean1a = (Bean1) factory.getBean("bean1"); System.out.println("Retrieved Bean1: " + bean1a.toString()); String strVal = bean1a.getString(); System.out.println("String property: " + strVal); int intVal = bean1a.getInt(); System.out.println("Int property: " + intVal); List strings = bean1a.getList(); System.out.println("List property: " + strings);

The properties have automatically been initialised by the Bean Factory:


Retrieved Bean1: ex02_setter.Bean1@21b6d String property: a string Int property: 125 List property: [item1, item2, item3]

42 - Spring Framework

Part 3 - API Development

Foundation Services API

Module 2
Foundation Services API

Foundation Services API - 43

Foundation Services API

Part 3 - API Development

Introduction
The Foundation Services API is a set of services providing full access to the capabilities of the Alfresco Repository. It is an in-process API meaning that the client must run within the same process as the Repository. For example, the Alfresco Web Client uses this API and is packaged together with the Repository in a single WAR file for deployment to an application server.

44 - Foundation Services API

Part 3 - API Development

Foundation Services API

Access to Repository Foundation Services


The Foundation Services API is comprised of a set of interfaces; each interface represents a function of the Repository. A Spring Framework Bean is provided as the implementation for each interface. The list of available public services (i.e. Spring beans) can be found in: the Spring configuration file public-services-context.xml the Service Registry interface org.alfresco.service.ServiceRegistry There are three ways to access Foundation Services: 1. use Spring IoC to directly inject services into your code (If your layer is also Spring enabled); 2. use the Alfresco Service Registry; 3. manually access services via the Spring getBean() method.

Foundation Services API - 45

Foundation Services API

Part 3 - API Development

FirstFoundationClient walkthrough
The following walkthrough is a practical introduction to using Foundation Services. It is based on the FirstFoundationClient sample from the Alfresco SDK. Before getting started, you should be familiar with the Spring Framework on page 40 . The sample uses several of the key foundation services, including the ServiceRegistry, TransactionService, AuthenticationService, SearchService, NodeService and ContentService. After initialising the Spring Application Context and starting the repository in embedded mode, we will use the Spring getBean() method to access the ServiceRegistry. We will then use the ServiceRegistry to access the other foundation services. After authenticating to the repository using the AuthenticationService, we will search for the Company Home node using the SearchService. We will then create a new node with properties and add an aspect using the NodeService. Finally, we will write some content to the new node using the ContentService. The sample will be wrapped in a single user transaction with the help of the TransactionService.

1) Getting the ServiceRegistry


The Service Registry maintains a list of available foundation services and some meta-data about each. In particular, the Service Registry provides access to each service interface. The registry is a service itself and is therefore accessed using either Spring IoC or the Spring getBean() method. The static variable SERVICE_REGISTRY found on the interface org.alfresco.service.ServiceRegistry provides the Spring Bean name to lookup by.

The FirstFoundationClient sample uses the getBean() method on the Spring Application Context to retrieve the ServiceRegistry:
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);

2) Using the TransactionService to run the example in a user transaction


By default, all repository foundation services are transactional and each invocation of a service method is wrapped in its own transaction. These transactions are defined declaratively in Spring configuration files and not in your Java code. In most cases, declarative transactions are preferred to user transactions since they are less invasive. There are situations, however, when user transactions do need to be used explicitly in your code. The FirstFoundationClient uses a RetryingTransactionHelper to run the example as a unit of work inside a user transaction. The work is defined as an instance of the RetryingTransactionCallback class. The doInTransaction() method is then called to run the unit of work in a transaction. The RetryingTransactionHelper is obtained via the getRetryingTransactionHelper() method on the TransactionService.

46 - Foundation Services API

Part 3 - API Development

Foundation Services API

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface TransactionService The TransactionService and RetryingTransactionHelper are presented in more detail in the section on Transactions .

The following example runs the example work in a user transaction via the RetryingTransactionHelper:
TransactionService transactionService = serviceRegistry.getTransactionService(); RetryingTransactionCallback<Object> exampleWork = new RetryingTransactionCallback<Object>() { public Object execute() throws Exception { doExample(serviceRegistry); return null; } }; transactionService. getRetryingTransactionHelper().doInTransaction(exampleWork);

3) Using the AuthenticationService for authentication


Before making any call to the repository through the public Foundation Services API, a user must first be authenticated. This is done via the AuthenticationService by using the authenticate() method and providing a username and password. Once authenticated, a ticket can be requested using either the getNewTicket() or the getCurrentTicket() method. The ticket can then be used to re-validate the user using the validate() method. The AuthenticationService defines the API for managing authentication information against a username.

Foundation Services API - 47

Foundation Services API

Part 3 - API Development

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface AuthenticationService

In the example, the authenticate() method is used to authenticate as the admin user. The password must be passed as a character array.
AuthenticationService authenticationService = serviceRegistry.getAuthenticationService(); authenticationService.authenticate("admin", "admin".toCharArray());

4) Using the SearchService to locate the Company Home node


The SearchService provides many methods for searching the Alfresco repository using any of the available query languages: Lucene, XPath or JCR-XPath. The Lucene query language allows you to run powerful searches, including full text searches on the content and node properties. To run a Lucene search using the query() method, you must specify the StoreRef of the store you wish to search, the query language (using one of the static attributes defined on the SearchService interface - LANGUAGE_LUCENE for example) and the query as a String. The parameters can either be passed directly to the query() method, or be defined on a new SearchParameters object which is then passed to the query() method. The query results are returned as a ResultSet object.

48 - Foundation Services API

Part 3 - API Development

Foundation Services API

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface SearchService

The following example runs a Lucene query using the PATH syntax to locate the Company Home by it's absolute path. The getNodeRef(0) call is used to retrieve the first NodeRef from the ResultSet. In theory, the query should only return one result.
SearchService searchService = serviceRegistry.getSearchService(); StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); ResultSet resultSet = searchService.query( storeRef, SearchService.LANGUAGE_LUCENE, "PATH:\"/app:company_home\""); NodeRef companyHome = resultSet.getNodeRef(0);

For more information on using the SearchService and on query string syntax, see the Search page on the Alfresco Wiki.

5) Using the NodeService to create a node


The NodeService provides methods for operations on nodes and stores. Stores are created with createStore(). Nodes are created with createNode() and deleted with deleteNode(). Properties are set with either setProperty() or setProperties(). Properties are removed with removeProperty(). Aspects are applied with addAspect() and removed with removeAspect(). Associations are created and removed with createAssociation() and removeAssociation(). Associations can be navigated with getSourceAssocs() or getTargetAssocs(). Child associations can be navigated with getChildAssocs() and getParentAssoc(). Almost all NodeService methods take a NodeRef as an argument. A NodeRef is obtained either by navigation or from the results of a search. Otherwise a new NodeRef object can be created from the node's unique UUID.

Foundation Services API - 49

Foundation Services API

Part 3 - API Development

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface NodeService

5.1) Setting properties


Properties are set on nodes using either the setProperty() or setProperties() methods. setProperty() allows a single property to be set, whilst setProperties() takes a Map of properties and sets all of the node's properties at once. Each property is identified by it's QName and it's value must be Serializable.
public void setProperty( NodeRef nodeRef, QName qname, Serializable value) public void setProperties( NodeRef nodeRef, Map<QName, Serializable> properties) 50 - Foundation Services API

Part 3 - API Development

Foundation Services API

nodeRef NodeRef of the node to set the property on. qname QName of the property to set. value Value of the property. The value must be Serializable. properties Map of all the properties of the node keyed by QName. The property QNames are usually defined as a static constants on the dictionary model interfaces. For example, the cm:name property is defined by the static constant ContentModel.PROP_NAME. The following example creates a Map containing the cm:name property that will be used in the next step:
String name = "Foundation API sample (" + System.currentTimeMillis() + ")"; Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(); contentProps.put(ContentModel.PROP_NAME, name);

5.2) Creating a node


Nodes are created using the createNode() method. A node is created as a child of a parent node. The child association name and child association type have to be supplied as QName objects, as well as the QName of the type of node to create and optionally a Map of properties to set on the newly created node.
public ChildAssociationRef createNode( NodeRef parentRef, QName assocTypeQName, QName assocQName, QName nodeTypeQName, Map<QName, Serializable> properties)

parentRef NodeRef of the parent node. The created node will be one of it's children. assocTypeQName QName of the type of association to create. This is used for verification against the data dictionary. assocQName QName of the association. nodeTypeQName QName of the node type. properties Optional Map of properties to set keyed by QName. The association and node type QName objects are usually defined as a static constants on the dictionary model interfaces. For example, the cm:contains association type is defined by the static constant ContentModel.ASSOC_CONTAINS and the cm:content node type is defined by the static constant ContentModel.TYPE_CONTENT. If a constant does not exist, a QName can be created using the QName.createQName() static method as in the example below. The createNode() method returns a ChildAssociationRef to the newly created child association. The NodeRef of the newly created node is obtained by calling the getChildRef() on the ChildAssociationRef object.

Foundation Services API - 51

Foundation Services API

Part 3 - API Development

The following example creates a new node of type cm:content, using the standard cm:contains child association. The Map created in the previous step sets the cm:name property on the newly created node.
NodeService nodeService = serviceRegistry.getNodeService(); ChildAssociationRef association = nodeService.createNode(companyHome, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name), ContentModel.TYPE_CONTENT, contentProps); NodeRef content = association.getChildRef();

5.3) Adding an aspect


Aspects are applied to nodes using the addAspect() method. The node is identified by it's NodeRef and the aspect by it's QName. The property values are provided as a Map.
public void addAspect( NodeRef nodeRef, QName aspectTypeQName, Map<QName, Serializable> aspectProperties)

nodeRef NodeRef of the node to apply the aspect to. aspectTypeQName QName of the aspect to apply. aspectProperties Map containing a minimum of the mandatory properties required for the aspect. The aspect QNames are usually defined as a static constants on the dictionary model interfaces. For example, the cm:titled aspect is defined by the static constant ContentModel.ASPECT_TITLED.

The following example applies the cm:titled aspect and sets the cm:title and cm:description properties:
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(); titledProps.put(ContentModel.PROP_TITLE, name); titledProps.put(ContentModel.PROP_DESCRIPTION, name); nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps);

6) Using the ContentService to write content


The ContentService provides methods for reading, writing and transforming content. In order to read or write content from and to a node, you must first obtain a ContentReader or a ContentWriter via the getReader() and getWriter() methods respectively. Methods can then be used on the ContentReader or ContentWriter to read and write content. Both the ContentReader and the ContentWriter implement the methods defined by the ContentAccessor interface. These methods allow you to get and set information about the content, for example to set the mime type, the encoding or to get the size. The actual content is stored on the cm:content property (ContentModel.PROP_CONTENT) of each node. When requesting a ContentReader or a ContentWriter, the NodeRef needs to

52 - Foundation Services API

Part 3 - API Development

Foundation Services API

be supplied along with the ContentModel.PROP_CONTENT QName. The ContentService is also used for transforming content. A suitable transformer can be obtained for a given transformation (defined by a source and target mime type) using the getTransformer() and getImageTransformer() methods. The transformation can then be performed by calling transform directly on the content transformer. Otherwise, a transformation can be attempted from a source ContentReader object to target ContentWriter object by calling the transform() method on the ContentService. For more information, see Content Transformers on page 82 .

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface ContentService Interface ContentReader Interface ContentWriter Interface ContentAccessor

The following example gets a ContentWriter to the newly created node. The property to be updated is defined by the QName ContentModel.PROP_CONTENT. The boolean true value is to request that the content is updated atomically when the content write stream is closed. The content mime type and encoding are set before writing the content with the putContent() method.
Foundation Services API - 53

Foundation Services API

Part 3 - API Development

ContentService contentService = serviceRegistry.getContentService(); ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); String text = "The quick brown fox jumps over the lazy dog"; writer.putContent(text);

Once completed, the newly created node may be viewed via the Web client.

Note: The web client will need to be re-started after executing the sample to see the changes in effect.

54 - Foundation Services API

Part 3 - API Development

Foundation Services API

Other Foundation Services


FileFolderService
The FileFolderService provides methods specific to manipulating Alfresco defined content files and folders. The methods can be more convenient and easier to use than the equivalent NodeService and ContentService methods. Certain methods, such as create(), return a FileInfo object. A NodeRef can then be retrieved using the FileInfo.getNodeRef() method.

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface FileFolderService Interface FileInfo

Foundation Services API - 55

Foundation Services API

Part 3 - API Development

56 - Foundation Services API

Part 3 - API Development

JCR API

Module 3
JCR API

JCR API - 57

JCR API

Part 3 - API Development

Introduction
The JCR API (Java Content Repository) specifies a standard, implementation independent API to access content repositories in Java. It is defined by the Java Specification Request (JSR) 170 as part of the Java Community Process (JCP). The official JSR-170 Specification can be found on the JCP web site at the following address: http://jcp.org/en/jsr/detail?id=170 Alfresco implements the JCR API against its own scalable repository and is actively contributing to the next version of JCR defined by the Java Specification Request (JSR) 283.

58 - JCR API

Part 3 - API Development

Web Services API

Module 4
Web Services API

Web Services API - 59

Web Services API

Part 3 - API Development

Introduction
The Web Services API is an easy to understand and develop against API. Accessible from many client languages, it is designed for remote repository access. Web Services are particularly suitable for composite applications and business processes.

60 - Web Services API

Part 3 - API Development

Web Services API

Available Web Services


The following Alfresco Web Services are available: Authentication login and logout Repository query and model manipulation Content content manipulation Authoring collaborative content creation Classification apply classifications and categories Access Control roles, permissions & ownership Action manage actions and rules Administration user management, export & import Dictionary model descriptions

Web Services API - 61

Web Services API

Part 3 - API Development

62 - Web Services API

Part 3 - API Development

Separating Concerns using AOP

Module 5
Separating Concerns using AOP

Separating Concerns using AOP - 63

Separating Concerns using AOP

Part 3 - API Development

Public Services and AOP proxies


The public services defined in public-services-context.xml are in fact Spring AOP proxies. For example, the public ContentService bean defined in public-services-context.xml is an AOP proxy to the target service defined by the contentService bean found in content-services-context.xml. The AOP proxy allows cross cutting concerns such as security and transaction management to be implemented in a non-invasive, declarative way. All service method calls via the ContentService bean defined in public-services-context.xml are subject to security checks and transaction management whilst those via the contentService bean defined in content-services-context.xml are subject to none! Note: All public service Spring beans have ids that begin with an uppercase letter. Public services are subject to security checks and transaction management. Beans with equivalent names that begin with a lowercase letter are subject to none. All public services AOP proxies are defined using a Spring ProxyFactoryBean. The ContentService example below is taken from public-services-context.xml:
<bean id="ContentService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>org.alfresco.service.cmr.repository.ContentService</value> </property> <property name="target"> <ref bean="contentService"/> </property> <property name="interceptorNames"> <list> <idref local="ContentService_transaction"/> <idref local="AuditMethodInterceptor"/> <idref local="exceptionTranslator"/> <idref bean="mlContentInterceptor"/> <idref bean="ContentService_security"/> </list> </property>

The ProxyFactoryBean introduces a level of indirection so that objects referencing the ContentService bean do not see the ProxyFactoryBean but the object defined by the target property, in our case, the contentService bean. The proxyInterfaces property, defines an array of interfaces implemented by the target class and the interceptorNames property a list of advisor, interceptor or other advice names to apply. Ordering is significant, the first interceptor in the list will be the first to be able to intercept the method call. The ContentService_transaction interceptor is a reference to a local bean in public-services-context.xml that manages transactions for calls to the ContentService. The ContentService_security is a reference to a bean in public-services-security-context.xml that enforces security checks for calls to the ContentService.

64 - Separating Concerns using AOP

Section 3
Extending the Alfresco Repository

Extending the Alfresco Repository - 65

66 - Extending the Alfresco Repository

Part 3 - API Development

Repository Policies

Module 1
Repository Policies

Repository Policies - 67

Repository Policies

Part 3 - API Development

Introduction
Repository policies are similar to events. Each service defines its own set of policies. For example the Content Service defines two policies: OnContentUpdatePolicy is fired when the content is updated on a node, OnContentReadPolicy is fired when the content is read on a node. A custom method or behaviour can be registered against a policy and will be called automatically when the policy is fired. This enables tasks such as maintaining the last modified date on a node or creating a new version and incrementing the version number on a node to be automated. The event-driven processing paradigm is similar to that used in traditional user interfaces.

68 - Repository Policies

Part 3 - API Development

Repository Policies

Available Policies
The available policies are defined as interfaces for each service. The Node Service defines more than twenty policies, including BeforeCreateNodePolicy, OnUpdatePropertiesPolicy and OnAddAspectPolicy, the other services each define their own specific policies. The policies are usually defined on an interface named after the service. For example, the Node Service policies are defined on the NodeServicePolicies interface and the Content Service policies are defined on the ContentServicePolicies interface:

Classes interested in certain policies must implement the corresponding interfaces and methods. Each policy method (or behaviour) defines its own specific list of arguments. For example: A behaviour registered against the BeforeCreateNodePolicy is called before a node is created. The beforeCreateNode() method receives the NodeRef of the parent of the node being created, the QName of the association type (usually cm:contains), the QName of the new association and the node type of the node being created. A behaviour registered against the OnCreateNodePolicy is called when a node is created. The onCreateNode() method receives the ChildAssociationRef to the node created.

Repository Policies - 69

Repository Policies

Part 3 - API Development

Policy Types
Each policy extends one of three policy types: Class policy Property policy Association policy

Class policies are for events related to content types or aspects, Property policies are for events related to properties and Association policies for events related to associations. Most policies extend the Class policy interface, a few policies extend the Association policy interface and, at the time of writing, none extend the Property policy.

70 - Repository Policies

Part 3 - API Development

Repository Policies

Custom Aspect with Behaviour Howto


This aim of this Howto is to show you in a step by step way how to create a custom action with behaviour that can be packaged and deployed to the Alfresco Repository. Before starting the tutorial, you should be familiar with Alfresco Content Models and the Spring Framework on page 40 . In the tutorial we are going to define a new Content Hits aspect with behaviour that will automatically keep a running count of the number of times the content on a node has been updated and read. The example demonstrates how the counters can be incremented after the content update or read transactions have been done. The examples in this tutorial are taken from the SDK CustomAspect sample.

1) Defining the Content Hits model


The Content Hits aspect is defined in a custom model contentHitsModel.xml:
<aspect name="ch:contentHits"> <title>Content Hits</title> <properties> <property name="ch:countStartedDate"> <type>d:date</type> <mandatory>true</mandatory> </property> <property name="ch:updateCount"> <type>d:int</type> <default>0</default> </property> <property name="ch:readCount"> <type>d:int</type> <default>0</default> </property> </properties> </aspect>

The ch:countStartedDate will be set when the aspect is added to a node. The ch:updateCount and ch:readCount properties will be incremented for each content update or read respectively.

2) Implementing the aspect behaviour class


This ContentHitsAspect class contains the behaviour behind the ch:contentHits aspect.

2.1) Creating the aspect behaviour class


The Content Hits aspect behaviour class is interested in the following three events: when the Content Hits aspect is added to a Node; when the content of a Node with the Content Hits aspect is updated (written); when the content of a Node with the Content Hits aspect is read. The class needs to implement the three corresponding polices:
public class ContentHitsAspect implements ContentServicePolicies.OnContentReadPolicy, ContentServicePolicies.OnContentUpdatePolicy, NodeServicePolicies.OnAddAspectPolicy Repository Policies - 71

Repository Policies

Part 3 - API Development

2.2) Writing the constructor


The Content Hits example uses a Transaction Listener to increment the counters after the content update or read transactions have been committed.

The Transaction Listener is instantiated by the constructor:


private TransactionListener transactionListener; /** * Default constructor for bean construction */ public ContentHitsAspect() { this.transactionListener = new ContentHitsTransactionListener(); }

2.3) Bind the behaviours


A behaviour is an encapsulated piece of logic that may be bound to a policy. The logic may be expressed in either Java or JavaScript.

When creating a new JavaBehaviour instance, you must provide the following:
public JavaBehaviour(Object instance, String method, NotificationFrequency frequency)

instance the object instance holding the method method the method name

72 - Repository Policies

Part 3 - API Development

Repository Policies

frequency one of three possible values defining when the behaviour should be notified: EVERY_EVENT, FIRST_EVENT or TRANSACTION_COMMIT The supplied method implements the behaviour logic and may have dependencies on Foundation Services that can be resolved using Spring dependency injection. A behaviour is bound to a policy using the bindClassBehaviour() method on the Policy Component:
bindClassBehaviour(QName policy, QName classRef, Behaviour behaviour);

policy the policy name classRef QName of type or aspect concerned by the policy behaviour a Behaviour object (instance of JavaBehaviour or ScriptBehaviour) A behaviour is bound to a specific content type or aspect using the classRef argument. The Policy Component is also used by services to register policies and to invoke policy behaviours.

In the Content Hits example, the Spring initialise() method is used to bind the behaviours to policies:
public void initialise() { this.policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), ASPECT_CONTENT_HITS, new JavaBehaviour(this, "onAddAspect", NotificationFrequency.FIRST_EVENT)); this.policyComponent.bindClassBehaviour( ContentServicePolicies.ON_CONTENT_READ, ASPECT_CONTENT_HITS, new JavaBehaviour(this, "onContentRead", NotificationFrequency.TRANSACTION_COMMIT)); this.policyComponent.bindClassBehaviour( ContentServicePolicies.ON_CONTENT_UPDATE, ASPECT_CONTENT_HITS, new JavaBehaviour(this, "onContentUpdate", NotificationFrequency.TRANSACTION_COMMIT)); }

2.4) Writing the onAddAspect policy behaviour


The onAddAspect policy behaviour will be called when the ch:contentHits aspect is added to a node. It receives the NodeRef of the node concerned and the QName of the added aspect. In the example, the added aspect will always be ch:contentHits since the behaviour has only been registered for that specific aspect. The onAddAspect() behaviour sets the count start date/time when the ch:contentHits aspect is added:
public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName) { Repository Policies - 73

Repository Policies

Part 3 - API Development

this.nodeService.setProperty( nodeRef, PROP_COUNT_STARTED_DATE, new Date()); }

2.5) Writing the onContentRead policy behaviour


The onContentRead policy behaviour will be called when the content property of a node with the ch:contentHits aspect is read. It receives the NodeRef of the node being read. As we have seen, the example uses a Transaction Listener to increment the counters after the content update or read transactions have been committed. The Transaction Listener is bound to the current transaction using the static bindListener() method on the AlfrescoTransactionSupport class and passing the Transaction Listener created earlier. The list of nodes read is stored as a resource against the current transaction using the static bindResource() method on the AlfrescoTransactionSupport class. The nodes are stored as a Set<NodeRef> using the KEY_CONTENT_HITS_READS key. The onContentRead() behaviour adds the NodeRef of the node being read to the list of nodes that require read count increments after the transaction completes:
public void onContentRead(NodeRef nodeRef) { // Bind the listener to the transaction AlfrescoTransactionSupport.bindListener(transactionListener); // Get the set of nodes read @SuppressWarnings("unchecked") Set<NodeRef> readNodeRefs = (Set<NodeRef>) AlfrescoTransactionSupport.getResource(KEY_CONTENT_HITS_READS); if (readNodeRefs == null) { readNodeRefs = new HashSet<NodeRef>(5); AlfrescoTransactionSupport.bindResource(KEY_CONTENT_HITS_READS, readNodeRefs); } readNodeRefs.add(nodeRef); }

2.6) Writing the onContentUpdate policy behaviour.


The onContentUpdate policy behaviour will be called when the content property of a node with the ch:contentHits aspect is updates. It receives the NodeRef of the node being updated and a boolean to indicate if the content is new content or not. The list of nodes updated is stored as a resource against the current transaction using the the KEY_CONTENT_HITS_WRITES key.

The onContentUpdate() behaviour adds the NodeRef of the node being updated to the list of nodes that require write count increments after the transaction completes:
public void onContentUpdate(NodeRef nodeRef, boolean newContent) { // Bind the listener to the transaction AlfrescoTransactionSupport.bindListener(transactionListener); // Get the set of nodes written @SuppressWarnings("unchecked") 74 - Repository Policies

Part 3 - API Development

Repository Policies

Set<NodeRef> writeNodeRefs = (Set<NodeRef>) AlfrescoTransactionSupport.getResource(KEY_CONTENT_HITS_WRITES); if (writeNodeRefs == null) { writeNodeRefs = new HashSet<NodeRef>(5); AlfrescoTransactionSupport.bindResource(KEY_CONTENT_HITS_WRITES, writeNodeRefs); } writeNodeRefs.add(nodeRef); }

2.7) Writing the Transaction Listener


The Transaction Listener is bound the the current transaction by the onContentRead() or onContentUpdate() behaviour methods. The afterCommit() method is called on the Transaction Listener after the transaction has committed. In the example, the Transaction Listener is defined as an inner class. It implements the afterCommit() method.
private class ContentHitsTransactionListener extends TransactionListenerAdapter { public void afterCommit() { ... } }

The afterCommit() method retrieves the list of nodes stored as a resource on the transaction by the onContentRead() behaviour:
public void afterCommit() { Set<NodeRef> readNodeRefs = (Set<NodeRef>) AlfrescoTransactionSupport.getResource(KEY_CONTENT_HITS_READS); if (readNodeRefs != null) { for (NodeRef nodeRef : readNodeRefs) { Runnable runnable = new ContentHitsReadCountIncrementer(nodeRef); threadExecuter.execute(runnable); } } ... }

The Content Hits read count (ch:readCount) is incremented for each node in the list. The afterCommit() method retrieves the list of nodes stored as a resource on the transaction by the onContentUpdate() behaviour:
public void afterCommit() { .... Set<NodeRef> writeNodeRefs = (Set<NodeRef>) AlfrescoTransactionSupport.getResource(KEY_CONTENT_HITS_WRITES); if (writeNodeRefs != null) { for (NodeRef nodeRef : readNodeRefs) { Runnable runnable = new ContentHitsWriteCountIncrementer(nodeRef); threadExecuter.execute(runnable); } } }

The Content Hits update count (ch:updateCount) is incremented for each node in the list.
Repository Policies - 75

Repository Policies

Part 3 - API Development

2.8) Writing the Spring dependency injection setter methods


The ContentHitsAspect class uses several services that can be injected via Spring:
private private private private private PolicyComponent policyComponent; BehaviourFilter policyFilter; NodeService nodeService; TransactionService transactionService; ThreadPoolExecutor threadExecuter;

public void setPolicyComponent(PolicyComponent policyComponent) { this.policyComponent = policyComponent; } public void setPolicyFilter(BehaviourFilter policyFilter) { this.policyFilter = policyFilter; } public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } public void setTransactionService(TransactionService transactionService) { this.transactionService = transactionService; } public void setThreadExecuter(ThreadPoolExecutor threadExecuter) { this.threadExecuter = threadExecuter; }

3) Registering the content hits model


The Content Hits model is registered with the following Spring bean definition taken from contents-hits-context.xml:
<bean id="contentHits.dictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap"> <property name="models"> <list> <value>org/alfresco/sample/contentHitsModel.xml</value> </list> </property> </bean>

4) Registering the aspect behaviour


The ContentHitsAspect behaviour class is registered with the following Spring bean definition taken from contents-hits-context.xml:
<bean id="contentHitsAspect" class="org.alfresco.sample.ContentHitsAspect" init-method="initialise"> <property name="nodeService"> <ref bean="nodeService"/> </property> <property name="policyComponent"> <ref bean="policyComponent"/> </property> <property name="policyFilter"> <ref bean="policyBehaviourFilter"/> </property> <property name="transactionService"> <ref bean="transactionService"/> </property> <property name="threadExecuter"> <ref bean="threadPoolExecutor"/> </property> </bean>

The initialise() method will be called once the bean has been instantiated and the properties set.

5) Configuring the property sheet

76 - Repository Policies

Part 3 - API Development

Repository Policies

In order to see the Content Hits aspect properties in the Web Client, the property sheet has to be configured as in the example web-client-config-custom.xml:
<config evaluator="aspect-name" condition="ch:contentHits"> <property-sheet> <show-property name="ch:countStartedDate" read-only="true" show-in-edit-mode="false"/> <show-property name="ch:updateCount" read-only="true" show-in-edit-mode="false"/> <show-property name="ch:readCount" read-only="true" show-in-edit-mode="false" /> </property-sheet> </config>

6) Packaging and deploying


In order to deploy a custom aspect with behaviour to the Alfresco repository, the following files need to be packaged: the compiled custom aspect behaviour class; the Spring configuration file (contents-hits-context.xml); if required, the custom dictionary model (contentsHitModel.xml); the Web Client custom configuration file containing the aspect property sheet definition (web-client-config-custom.xml).

The compiled class needs to be exported to a JAR file. The files then need to be deployed to the following directories in the Alfresco repository: the JAR file to the WEB-INF/lib directory; all other files to the WEB-INF/classes/alfresco/extension directory. For deployment in a production environment, the files should be packaged and deployed as an Alfresco Module Package (AMP). For more details, see Alfresco Module Packages on page .

Repository Policies - 77

Repository Policies

Part 3 - API Development

78 - Repository Policies

Part 3 - API Development

Repository Actions

Module 2
Repository Actions

Repository Actions - 79

Repository Actions

Part 3 - API Development

Introduction
An action is a unit of work that is performed against a node. For example, moving a node, copying a node, checking a node in, transforming the contents of a node, etc. Many actions already exist, however it is possible to add you own custom actions in a few easy steps. An action has to implement the org.alfresco.repo.action.executer.ActionExecuter interface. The ActionExecuter interface can be implemented directly, however it is best to extend the abstract class ActionExecuterAbstractBase that has been written to provide basic services for action executer implementations. Only two methods need implementing when deriving from the abstract superclass.

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface ActionExecuter Class ActionExecuterAbstractBase

80 - Repository Actions

Part 3 - API Development

Content Transformers

Module 3
Content Transformers

Content Transformers - 81

Content Transformers

Part 3 - API Development

Introduction
A content transformer is a Java class that can transform content from one mime type to another. Many content transformers already exist, however it is possible to add you own custom content transformer in a few easy steps. A content transformer has to implement the org.alfresco.repo.content.transform.ContentTransformer interface. ContentTransformer extends the org.alfresco.repo.content.ContentWorker interface that is a common marker interface for specific worker interfaces such as content transformers and metadata extractors. An abstract base class called AbstractContentTransformer has been written to provides basic services for ContentTransformer implementations. Only two methods need implementing when deriving from the abstract superclass.

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface ContentTransformer Class AbstractContentTransformer

82 - Content Transformers

Part 3 - API Development

Metadata Extractors

Module 4
Metadata Extractors

Metadata Extractors - 83

Metadata Extractors

Part 3 - API Development

Introduction
A metadata extractor is a Java class that can extract metadata from content of a particular mime type. Many metadata extractors already exist, however it is possible to add you own custom metadata extractor in a few easy steps. A metadata extractor has to implement the org.alfresco.repo.content.metadata.MetadataExtracter interface. MetadataExtracter extends the org.alfresco.repo.content.ContentWorker interface that is a common marker interface for specific worker interfaces such as metadata extractors and content transformers. An abstract class called AbstractMappingMetadataExtracter has been written to provides basic services for MetadataExtracter implementations. Only one method needs implementing when deriving from the abstract superclass.

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface MetadataExtracter Class AbstractMappingMetadataExtracter

84 - Metadata Extractors

Part 3 - API Development

Metadata Extractors

MetadataExtracterRegistry
The MetadataExtracterRegistry holds a list of available metadata extractors and provides the most appropriate extractor for a particular mime type extraction request. Upon initialisation, metadata extractors register themselves with the MetadataExtracterRegistry via the register() method.

Note: For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Class MetadataExtracterRegistry The getExtracter() method is used by clients to get the most appropriate metadata extractor for a particular mime type. The MetadataExtracterRegistry bean is defined in the content-service-context.xml Spring configuration file:
<!-- Metadata Extraction Regisitry --> <bean id="metadataExtracterRegistry" class="org.alfresco.repo.content.metadata.MetadataExtracterRegistry" />

Metadata Extractors - 85

Metadata Extractors

Part 3 - API Development

86 - Metadata Extractors

Section 4
Extending the Alfresco Web Client

Extending the Alfresco Web Client - 87

88 - Extending the Alfresco Web Client

Part 3 - API Development

JavaServer Faces

Module 1
JavaServer Faces

JavaServer Faces - 89

JavaServer Faces

Part 3 - API Development

Introduction
JavaServer Faces (JSF) is a user interface framework for Java web applications. JSF defines an event-driven, component-based model for web application development, similar to the model that has been used successfully for standalone GUI applications for years. JSFs core architecture is designed to be independent of specific protocols and markup. However it is also aimed directly at solving many of the common problems encountered when writing applications for HTML clients that communicate via HTTP to a Java application server that supports servlets and JavaServer Pages (JSP) based applications. JSF is a specification (JSR-252) that has been developed as part of the Java Community Process. It is a standard, vendor independent specification. Several implementations exist, including the GlassFish JavaServer Faces reference implementation and Apache MyFaces . Alfresco uses the Apache Myfaces implementation. The specification defines a set of standard user interface components and an API for extending the standard components or developing new ones. As well as UI components, JSF also defines artifacts like converters, validators, events listeners, and renderers: converters perform type conversion between server-side Java objects and their representation in the user interface. A good example is a date; validators can be associated with a JSF component to perform input validation checks on local values before they are processed; event listeners are registered against events that are triggered when a user clicks a button or a link, changes a value in a field, or makes a selection in a list. The outcome of the event processing controls which page is displayed next; renderers generate the actual markup for the user interface. JSF is not limited to HTML or any other markup language and the same JSF component can be coupled with different renderers to produce different output, for example, either HTML or WML;

90 - JavaServer Faces

Part 3 - API Development

Actions Framework

Module 2
Actions Framework

Actions Framework - 91

Actions Framework

Part 3 - API Development

Introduction
The Alfresco Web Client UI actions are configured using the Actions Framework. Actions such as Edit, View Details, Update, Copy are all examples of UI Actions. Actions are grouped into

action groups. Individual actions can be reused between groups and the action groups reused across pages. Action Groups define an ordered list of actions that are displayed together, either as a serial list (for example, as a strip of icons) or grouped together in a drop-down menu. The More Actions menu is an example of an action group.

UI actions and actions groups are configured in XML. The standard UI actions and action groups are defined in the web-client-config-actions.xml configuration file. You can define your own custom UI actions and action groups in a Web Client configuration extension file. You can also extend existing action groups to add your own custom UI actions to existing menus in the Web Client.

92 - Actions Framework

Part 3 - API Development

Dialog Framework

Module 3
Dialog Framework

Dialog Framework - 93

Dialog Framework

Part 3 - API Development

Introduction
The dialog framework manages the user interface dialogs in the Alfresco Web Client. Most of the standard Web Client dialog are managed by the framework and it is possible to create your own custom dialogs using the framework. Each dialog has three main components: A <dialog/> configuration element in a web-client-config.xml file. A dialog JSP that only contains the HTML and JSF components to define the body of the dialog. A JSF managed bean that is used as a backing bean for the dialog. At the centre of the dialog framework is the Dialog Manager. When a dialog is opened, the Alfresco Navigation Handler looks up the <dialog/> configuration then calls the Dialog Manager to initialise the dialog and instantiate the managed bean before navigating to the dialog JSP page. See Dialog Manager on page for more details.

94 - Dialog Framework

Part 3 - API Development

Wizard Framework

Module 4
Wizard Framework

Wizard Framework - 95

Wizard Framework

Part 3 - API Development

Introduction
The wizard framework manages the user interface wizards in the Alfresco Web Client. Most of the standard Web Client wizards are managed by the framework and it is possible to create your own custom wizards using the framework. Each wizard has three main components: A <wizard/> configuration element in a web-client-config.xml file.performed in exactly the same A JSP for each step in the wizard that only contains the HTML and JSF components to define the body of the step. A JSF managed bean that is used as a backing bean for the wizard. At the centre of the wizard framework is the Wizard Manager. When a wizard is opened, the Alfresco Navigation Handler looks up the <wizard/> configuration then calls the Wizard Manager to initialise the wizard and instantiate the managed bean before navigating to the JSP page for the first step. See Wizard Manager on page for more details.

96 - Wizard Framework

Alfresco 3.1
Administrator Exercises

Alfresco 2.1

Administrator Exercises

Contents
MODULE 1 EXERCISES ............................................................................................................................. 1 EXERCISE 1.01 USERS & GROUPS .............................................................................................................. 1 EXERCISE 1.02 DELETE & RECOVER .......................................................................................................... 1 MODULE 2 EXERCISES ............................................................................................................................. 2 EXERCISE 2.01 EDITING THE LIST OF LOGIN LANGUAGES........................................................................... 2 EXERCISE 2.02 CUSTOMISING THE VIEW CONFIGURATION ......................................................................... 2 MODULE 3 EXERCISES ............................................................................................................................. 3 EXERCISE 3.01 CHANGING THE NAME OF THE CIFS SERVER ..................................................................... 3 EXERCISE 3.02 CREATING A NEW FILE SYSTEM ......................................................................................... 3 EXERCISE 3.03 EDITING THE FTP ROOT DIRECTORY .................................................................................. 3 MODULE 4 EXERCISES ............................................................................................................................. 4 EXERCISE 4.01 USING THE SYSTEM INFORMATION CONSOLE .................................................................... 4 EXERCISE 4.02 MODIFYING LOG4J CONFIGURATION .................................................................................. 4 MODULE 5 EXERCISES ............................................................................................................................. 5 EXERCISE 5.01 SPACES IMPORT & EXPORT ................................................................................................ 5 EXERCISE 5.01 FULL REPOSITORY IMPORT & EXPORT .............................................................................. 5 MODULE 9 EXERCISES ............................................................................................................................. 6 EXERCISE 9.01 CONFIGURING A VERTICAL CLUSTER ................................................................................ 6 EXERCISE 9.02 CONFIGURING A REPLICATING CONTENT STORE ............................................................... 6

Administrator Exercises - i

Alfresco 2.1

Administrator Exercises

Module 1 Exercises
Exercise 1.01 Users & Groups
1. Create Groups that follow the following hierarchy: Company Management Technical Developers Solutions Engineers Human Resources Partners 2. Create some users and add them into the appropriate groups. 3. Remember a user can be in more than one group.

Exercise 1.02 Delete & Recover


1. Login as a normal user and delete some content. 2. Login as another normal user and delete some content. 3. Login as Administrator and use the search facility to search for deleted content by user. 4. Test restoring some content. 5. Test permanently removing some content. 6. Login as the normal user again and try to find deleted content that has been permanently removed by admin.

Administrator Exercises - 1

Alfresco 2.1

Administrator Exercises

Module 2 Exercises
Exercise 2.01 Editing the list of login languages
1. Within <ext>/web-client-config-custom.xml, edit the list of language definitions to remove all options except English and French. 2. Ensure this overrides the <config> option completely rather than adding to it (Hint: use replace=true). 3. Restart Alfresco and navigate to the login page. 4. Review the list of languages.

Exercise 2.02 Customising the view configuration


1. Copy the <config> section for the Views condition from <config>/web-client-config.xml into <ext>/web-client-config-custom.xml. 2. Reduce the configuration to change the number of icons shown by default in the Browse view from 9 to 3. 3. Restart Alfresco and test by creating a new test space and placing 4 content items within it.

Administrator Exercises - 2

Alfresco 2.1

Administrator Exercises

Module 3 Exercises
Exercise 3.01 Changing the name of the CIFS Server
1. Copy the relevant CIFS Server configuration from <config>/file-servers.xml into <ext>/fileservers-custom.xml. 2. Update the name of the CIFS server to LegalAlfrescoXX where XX is a number unique to you. 3. Restart Alfresco and try to browse to \\LegalAlfrescoXX to test.

Exercise 3.02 Creating a new File System


1. Create a new Space called Legal within Company Home. 2. Add a new entry to into <ext>/file-servers-custom.xml to set this up as a new file system. 3. Restart Alfresco and try to browse to \\LegalAlfrescoXX to test.

Exercise 3.03 Editing the FTP root directory


1. Open ftp://localhost/ using the ftp command from an MSDOS prompt and list the directory contents using ls 2. Leave the FTP session by typing quit 3. Copy the relevant FTP Server configuration from <config>/file-servers.xml into <ext>/fileservers-custom.xml and update the FTP root directory to point to Legal 4. Restart Alfresco and Open ftp://localhost/ again to check what has changed

Administrator Exercises - 3

Alfresco 2.1

Administrator Exercises

Module 4 Exercises
Exercise 4.01 Using the System Information console
1. Log in as the admin user. 2. Navigate to the Administration Console and select System Information. 3. Check the current version of Alfresco. 4. Check the maximum amount of Java memory (heap) allocated to Alfresco in the System Properties.

Exercise 4.02 Modifying log4j configuration


Add your own custom class logger 1. In <ext>/custom-db-and-data-context.xml find the class definition tag:
<bean id="repository-properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfig urer">

2. Copy the definition and prepend log4j.logger. to the definition. 3. Set the log level to DEBUG. 4. Restart the server and view the logging information.

Administrator Exercises - 4

Alfresco 2.1

Administrator Exercises

Module 5 Exercises
Exercise 5.01 Spaces Import & Export
1. Login as administrator 2. Create an Exports space to save exports in 3. Export a users space 4. Restore the space and test 5. Check that user permissions and content rules have been imported correctly.

Exercise 5.01 Full Repository Import & Export


1. Log in as Administrator and do a full repository Export. 2. Shut down alfresco and delete (or rename) alf_data and the alfresco database. 3. Create a new alfresco database in MySQL.
rename <ext>/restore-context.xml.sample and modify as necessary

4. Restore the repository by restarting the alfresco server. 5. What happens on subsequent alfresco startups if you do leave restore-context.xml as is. 6. Which method of backup and restore is better to use and why?

Administrator Exercises - 5

Alfresco 2.1

Administrator Exercises

Module 9 Exercises
Exercise 9.01 Configuring a Vertical Cluster
7. Create a copy of your Alfresco installation directory called Alfresco2 8. Ensure that the Lucene indexes are configured in different locations for each install. The content store however should point to the same directory. 9. Configure both installations to automatically rebuild its indexes as required (Hint: Use AUTO setting). 10. Enable cache replication in both installations. 11. Restart the primary instance. 12. Start up the second instance.

Exercise 9.02 Configuring a Replicating Content Store


1. Improve the configuration above by configuring different content store locations with a replicating content store pushing content items to a common location.

Administrator Exercises - 6

You might also like