alfresco exercises

133
Alfresco 3.1 Configuration and Customisation Exercises

Upload: truesansha

Post on 03-Nov-2014

245 views

Category:

Documents


1 download

DESCRIPTION

Alfresco

TRANSCRIPT

Page 1: Alfresco Exercises

Alfresco 3.1 Configuration and Customisation Exercises

Page 2: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - i

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

Page 3: Alfresco Exercises

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 node’s 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”).

Page 4: Alfresco Exercises

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.

Page 5: Alfresco Exercises

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 user’s 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.

Page 6: Alfresco Exercises

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?

Page 7: Alfresco Exercises

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 it’s

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 it’s node.

Hint 2 You can use a node’s ‘content’ property to read or set it’s 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 file’s 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 set’s it’s ‘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.

Page 8: Alfresco Exercises

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 user’s 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.

Page 9: Alfresco Exercises

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.

Page 10: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Page 11: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - i

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

Page 12: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 1

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.

Page 13: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 2

Module 2 Exercises

Exercise 2.01 – User Options 1. Log in as admin:

username = admin password = admin

2. Modify the user’s properties:

g. Change the user’s first name to your first name. h. Change the user’s last name to your last name.

i. Change the user’s 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 user’s 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

Page 14: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 3

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.

Page 15: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 4

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

Page 16: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 5

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).

Page 17: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 6

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

Note Click ‘Go Up’ to navigate to parent spaces/

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.

Page 18: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 7

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. Select Using a Template.

j. Choose the ‘Software Engineering Project’ template.

k. 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.

Page 19: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 8

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.

Page 20: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 9

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 user’s 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.

Page 21: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 10

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.

Page 22: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 11

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.

Page 23: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 12

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.

Page 24: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 13

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.

Page 25: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 14

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.

Page 26: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 15

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’.

Page 27: Alfresco Exercises

Alfresco 3.1 Installing and Using Alfresco Exercises

Installing and Using Alfresco Exercises - 16

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?

Page 28: Alfresco Exercises

Alfresco 2.1 Partner Bootcamp

Part 3 - API Development

Page 29: Alfresco Exercises
Page 30: Alfresco Exercises

ContentsGetting Started ..........................................................................................................................

Alfresco SDK ................................................................................................................5Introduction.............................................................................................................. 6Downloading and Unpacking the Alfresco SDK...................................................... 7Importing the Alfresco SDK projects into Eclipse.................................................... 9Associating Source Code and Javadocs with the Alfresco Libraries..................... 12SDK samples......................................................................................................... 15SVN Repository..................................................................................................... 19SDK Reference..................................................................................................... 20

Best Practices ............................................................................................................ 23Coding Standards.................................................................................................. 24Alfresco Module Packages (AMP)......................................................................... 25

Alfresco Repository Architecture ............................................................................ 27Out of the Box....................................................................................................... 28Service & Component Architecture....................................................................... 30Repository Foundation Services API..................................................................... 33Repository APIs..................................................................................................... 35

Developing against the Alfresco Repository .........................................................................Spring Framework ..................................................................................................... 39

Introduction............................................................................................................ 40Inversion of Control (IoC)...................................................................................... 41

Foundation Services API .......................................................................................... 43Introduction............................................................................................................ 44Access to Repository Foundation Services........................................................... 45FirstFoundationClientwalkthrough......................................................................... 46Other Foundation Services.................................................................................... 55

JCR API .......................................................................................................................57Introduction............................................................................................................ 58

Web Services API ...................................................................................................... 59Introduction............................................................................................................ 60Available Web Services......................................................................................... 61

Separating Concerns using AOP ............................................................................. 63Public Services and AOP proxies.......................................................................... 64

Extending the Alfresco Repository .........................................................................................Repository Policies ................................................................................................... 67

Introduction............................................................................................................ 68Available Policies.................................................................................................. 69Policy Types.......................................................................................................... 70Custom Aspect with Behaviour Howto.................................................................. 71

Repository Actions ....................................................................................................79Introduction............................................................................................................ 80

Content Transformers ............................................................................................... 81Introduction............................................................................................................ 82

Metadata Extractors .................................................................................................. 83Introduction............................................................................................................ 84MetadataExtracterRegistry.................................................................................... 85

Extending the Alfresco Web Client .........................................................................................JavaServer Faces ...................................................................................................... 89

Introduction............................................................................................................ 90Actions Framework ................................................................................................... 91

Introduction............................................................................................................ 92Dialog Framework ......................................................................................................93

Introduction............................................................................................................ 94Wizard Framework .....................................................................................................95

Page 31: Alfresco Exercises

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

Page 32: Alfresco Exercises

Section 1

Getting Started

Getting Started - 3

Page 33: Alfresco Exercises

4 - Getting Started

Page 34: Alfresco Exercises

Module 1

Alfresco SDK

Part 3 - API Development Alfresco SDK

Alfresco SDK - 5

Page 35: Alfresco Exercises

Introduction

The Alfresco SDK provides support for developers who wish to extend or customise the Alfrescoplatform. It has been designed for the developer to get developing with minimal fuss for the followingdevelopment 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 ofthe 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 andartifacts. If you wish to develop bug fixes or extend the core functionality of the Alfresco platform, youshould use the full Alfresco development environment provided in the Alfresco SVN Repository. Formore information, see SVN Repository on page 19 .

Alfresco SDK Part 3 - API Development

6 - Alfresco SDK

Page 36: Alfresco Exercises

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 andCommunity Networks.

1) Downloading the Alfresco SDK

The Enterprise SDK is only available to Enterprise clients and partners. The Community SDK isfreely available and can be downloaded from the Download Alfresco Community Network pageon 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 yourchoice.

Part 3 - API Development Alfresco SDK

Alfresco SDK - 7

Page 37: Alfresco Exercises

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

Alfresco SDK Part 3 - API Development

8 - Alfresco SDK

Page 38: Alfresco Exercises

Importing the Alfresco SDK projects into Eclipse

When using the Alfresco SDK, the Eclipse IDE is highly recommended. The SDK contains severalpre-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 configuredappropriately 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 orabove:

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 Workspaceimport 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 SDKand click OK. The Alfresco SDK projects are now listed under Projects.

Part 3 - API Development Alfresco SDK

Alfresco SDK - 9

Page 39: Alfresco Exercises

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

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

Alfresco SDK Part 3 - API Development

10 - Alfresco SDK

Page 40: Alfresco Exercises

2.5) Once you have selected the projects you wish to import, click Finish.

The imported projects are displayed in the Package Explorer:

Part 3 - API Development Alfresco SDK

Alfresco SDK - 11

Page 41: Alfresco Exercises

Associating Source Code and Javadocs with theAlfresco Libraries

Once the Alfresco SDK projects have been imported into Eclipse, it is useful to have access toAlfresco's source code and Java documentation. The following procedure explains how to do this byassociating 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 fromthe 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 SourceAttachment 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 inthe 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.

Alfresco SDK Part 3 - API Development

12 - Alfresco SDK

Page 42: Alfresco Exercises

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

4.5) Click Validate... to validate the Javadoc location, then click either OK to viewthe 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 iconchanges to include a small document:

Part 3 - API Development Alfresco SDK

Alfresco SDK - 13

Page 43: Alfresco Exercises

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)

Alfresco SDK Part 3 - API Development

14 - Alfresco SDK

Page 44: Alfresco Exercises

SDK samples

FirstFoundationClient and JCR Samples

The SDK FirstFoundationClient, SDK FirstJCRClient and SDK JCRSamples sampleprojects demonstrate how to access an embedded Alfresco repository via the Foundation ServicesAPI and the standards-compliant JCR API. These samples can be tested directly from within Eclipseand will automatically start an Alfresco repository in embedded mode.

Before starting, the embedded repository needs to be configured. By default, the sample projects areconfigured 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 thesource/alfresco/extension directory of each project. It is good practice to define an absolutepath for the data directory (dir.root parameter) and to configure all of the SDK projects to share thesame 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 requiresmysql-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 theextras/databases/mysql directory of the unpacked Alfresco SDK. To create the database fromthe command line:

C:\alfresco-enterprise-sdk\extras\databases\mysql>mysql -u root -p < db_setup.sqlEnter password: ********

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

Part 3 - API Development Alfresco SDK

Alfresco SDK - 15

Page 45: Alfresco Exercises

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

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

Web Services Samples

The SDK FirstWebServiceClient and SDK WebServiceSamples sample projects demonstratehow to access a remote Alfresco repository via the Web Services API. A remote Alfresco repositoryneeds 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 andconfigured. The easiest solution for development purposes is to install Alfresco on the local machineand configure it to use the same alfresco MySQL database and the same C:/alf_dir datadirectory as the embedded repository used for the other samples.

Alfresco SDK Part 3 - API Development

16 - Alfresco SDK

Page 46: Alfresco Exercises

The location of the remote repository is configured in the webserviceclient.properties file inthe source/alfresco/extension directory of each Web Services project. If the remote repositoryis installed on the same machine and configured to use the default 8080 port, you will not have tomodify the default value.

Example webserviceclient.properties file:

## Set the following property to reference the Alfresco server that you would likeweb service client# to communicate withrepository.location=http://localhost:8080/alfresco/api

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

Custom Repository Samples

The SDK CustomAction and SDK CustomAspect sample projects demonstrate how to developcustom modules that may be deployed to an Alfresco repository. Initially, custom repository modulescan be developed and tested using unit tests and an embedded Alfresco repository. The SDKCustomAspect project has a sample unit test that does this.

An Ant build.xml file is provided for packaging the repository samples. The package targetpackages the compiled classes and extension files into a JAR file. To deploy the samples, copy theJAR file to the WEB-INF/lib folder of an existing Alfresco installation and restart the applicationserver.

For deployment in a production environment, a custom repository module should be packaged as anAlfresco 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 withBehaviour Howto on page 71 .

Custom Web Client Samples

The SDK CustomDialog, SDK CustomJSP, SDK CustomLogin, SDK CustomWizard, and SDKTaggingSample sample projects demonstrate how to develop custom modules for the Alfresco WebClient. 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 targetpackages the compiled classes and extension files into a JAR file. The package-extension targetthen packages the JAR file along with the JSPs into a ZIP file. The optional integrate-extensiontarget can be used to integrate the packaged ZIP file into an Alfresco Web Client WAR file. Thealfresco.war file must be copied to the same directory as the build.xml file before running the

Part 3 - API Development Alfresco SDK

Alfresco SDK - 17

Page 47: Alfresco Exercises

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 anAlfresco Module Package (AMP).

The SDK CustomDialog and SDK CustomWizard are presented in detail in the Custom Dialog Howtoon page and the Custom Wizard Howto on page . The SDK TaggingSample sample ispresented 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 arrangeclasses and configuration files to generate an Alfresco Module Package (AMP). For more informationsee Alfresco Module Packages on page .

Alfresco SDK Part 3 - API Development

18 - Alfresco SDK

Page 48: Alfresco Exercises

SVN Repository

The Alfresco Subversion repository gives you access to all of the Alfresco source code and buildartifacts. It provides the latest work-in-progress developments. It should only be used if you wish toextend the Alfresco core framework or work on Alfresco bug fixes as it allows you to perform fullre-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

Part 3 - API Development Alfresco SDK

Alfresco SDK - 19

Page 49: Alfresco Exercises

SDK Reference

SDK Contents

An expanded Alfresco SDK contains the following directories and top-level files:

binSupporting dll's, exe's.

docZipped Javadoc's for all pre-built libraries.

extrasAdditional files - database setup and migration scripts.

libAlfresco pre-built libraries (JAR files).

lib/deploymentAlfresco libraries required for WCM deployment to a remote server.

lib/remoteAlfresco libraries required for access to a remote Alfresco repository via web services.

lib/serverAlfresco libraries required for embedding an Alfresco repository.

licensesLicense files.

samplesSample Eclipse projects for common development scenarios (see SDK Eclipse Projects on page 20).

srcZipped source code for all pre-built libraries.

license.txtAlfresco licence file.

notice.txtNotices

readme.txtAlfresco SDK readme.

SDK Eclipse Projects

The Alfresco SDK contains the following pre-configured Eclipse projects:

SDK AlfrescoEmbeddedProject containing all of the Alfresco libraries needed to build a custom module that will beembedded into the Alfresco repository or Web Client.

SDK AlfrescoRemoteProject containing all of the Alfresco libraries needed to build a custom Web Services client.

SDK Basic AMPSample project demonstrating how to build an AMP (Alfresco Module Package) file.

SDK CustomActionSample project demonstrating how to develop a custom Action that may be deployed to an Alfrescorepository.

SDK CustomAspectSample project demonstrating how to develop a custom Aspect with behaviour that may bedeployed to an Alfresco repository.

SDK CustomDialogSample project demonstrating how to develop and configure a custom Dialog for the Alfresco WebClient.

SDK CustomJSP

Alfresco SDK Part 3 - API Development

20 - Alfresco SDK

Page 50: Alfresco Exercises

Sample project demonstrating how to develop and configure a custom JSP for the Alfresco WebClient.

SDK CustomLoginSample project demonstrating how to override the Login page of the Alfresco Web Client.

SDK CustomWizardSample project demonstrating how to develop and configure a custom Wizard for the Alfresco WebClient.

SDK FirstFoundationClientSample project demonstrating how to access an Alfresco (embedded) repository via theFoundation Services API.

SDK FirstJCRClientSample project demonstrating how to access an Alfresco (embedded) repository via thestandards-compliant JCR API.

SDK FirstWebServiceClientSample project demonstrating how to access a remote Alfresco repository via the Web ServicesAPI.

SDK JCRSamplesMore sample projects demonstrating how to access an Alfresco (embedded) repository via thestandards-compliant JCR API.

SDK TaggingSampleAdvanced sample project demonstrating how to develop a custom Action that takes parameters.

SDK WebServiceSamplesMore sample projects demonstrating how to access a remote Alfresco repository via the WebServices API.

Part 3 - API Development Alfresco SDK

Alfresco SDK - 21

Page 51: Alfresco Exercises

Alfresco SDK Part 3 - API Development

22 - Alfresco SDK

Page 52: Alfresco Exercises

Module 2

Best Practices

Part 3 - API Development Best Practices

Best Practices - 23

Page 53: Alfresco Exercises

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)

Best Practices Part 3 - API Development

24 - Best Practices

Page 54: Alfresco Exercises

Alfresco Module Packages (AMP)

An Alfresco Module Package (AMP) is a collection of code, XML, images, CSS, etc. that collectivelyextend the functionality or data provided by the standard Alfresco Repository. An AMP file can containas little as a set of custom templates or a new category. It can contain a custom model and associatedUI customisations. It could contain a complete new set of functionality, for example recordsmanagement. As a general rule of thumb, anything that is considered to be an “installable” extension tothe 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 hasa standard format that can be customised if required.

Once the contents of the AMP file has been mapped into an Alfresco WAR using the ModuleManagement Tool, the WAR can be deployed to the application server. When the repository is nextstarted, the installed module configuration will be detected, and the repository will be bootstrapped toinclude 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 longas 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 andresources (config) is org.alfresco.module.<moduleid>, where moduleid is the unique

Part 3 - API Development Best Practices

Best Practices - 25

Page 55: Alfresco Exercises

module id of the module.

Alfresco Module Packages are presented in more detail later on in the course. For more details, seeAlfresco Module Packages on page .

Best Practices Part 3 - API Development

26 - Best Practices

Page 56: Alfresco Exercises

Module 3

Alfresco Repository Architecture

Part 3 - API Development Alfresco Repository Architecture

Alfresco Repository Architecture - 27

Page 57: Alfresco Exercises

Out of the Box

Out-of-the-box, Alfresco's simple installation procedure provides a pre-configured deployment aimed atreaching 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 userinterface and domain. Storage of data and content is provided by persistent back-ends such as adatabase or file system. Any number of web browsers can connect to the application without priorclient installation costs.

In this particular case, the application server houses both the Alfresco Application and the AlfrescoRepository. An Alfresco Application provides a complete solution tailored for a specific area of ContentManagement such as Document Management (DM), Web Content Management (WCM) and RecordsManagement (RM). The Alfresco Repository provides a set of reusable cross-cutting ContentManagement services such as content storage, query, versioning and transformation which may beutilised by one or more applications.

Although this is the default installed deployment, it is only one of many ways of utilising the capabilitiesand components of Alfresco. When we first set out to design Alfresco, we wanted to break away from

Alfresco Repository Architecture Part 3 - API Development

28 - Alfresco Repository Architecture

Page 58: Alfresco Exercises

the mould of typical Content Management architectures which are monolithic and closed. The result isthat Alfresco can neatly fit into existing environments and each of its components may be used inisolation 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 goodunderstanding of the concepts and capabilities and how it achieves openness, scalability and flexibility.

Part 3 - API Development Alfresco Repository Architecture

Alfresco Repository Architecture - 29

Page 59: Alfresco Exercises

Service & Component Architecture

Every part of the Alfresco Repository is either a component or a service. A component is animplementation black box that provides a specific feature or capability. A service is an interface entrypoint for a client to bind to and use. This fundamental approach allows for existing components to beswitched with new implementations, new components to be added with ease and for clients to connectand 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 fasterAlfresco. If there's a feature you wish to re-implement, you can replace it, either by providing a betterimplementation, or integrating with your existing environment.

Implementation of this approach is simplified by using the open source project Spring Frameworkwhich 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 programmingallows the weaving of infrastructure concerns such as Transactions and Security into componentswithout polluting their implementation. Environment touch points are abstracted such as resource (e.g.database) connections.

The Alfresco Repository structure looks like this:

Alfresco Repository Architecture Part 3 - API Development

30 - Alfresco Repository Architecture

Page 60: Alfresco Exercises

The public interface point is the Alfresco Repository Foundation Services. Each service is exposed asa Java Interface to which a Repository client can bind and invoke without knowledge of its underlyingimplementation. A Service Registry lists the available services. Behind services are the implementationblack boxes i.e. components. Each service and component is configured via the Spring framework inXML “context” files.

Note: The Spring context file public-service-context.xml provides the configuration andbinding of the Alfresco Repository Foundation Services.

The Repository Foundation Services are the lowest level of public interface providing access to allRepository capabilities. Binding to this interface is possible via the Repository Service Registry, or viaSpring dependency injection if the client is also Spring aware. Access to Foundation Services is limitedto Repository clients who reside in the same process as the Repository. That is, the FoundationServices 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 policiesare enforced. The policies themselves are declaratively specified and enforced via the injection of atransaction and security implementation into each service. Every service of Alfresco is transactionaland secure.

Other forms of API are provided too, however, all public entry points eventually go through this layer.

Part 3 - API Development Alfresco Repository Architecture

Alfresco Repository Architecture - 31

Page 61: Alfresco Exercises

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

Alfresco Repository Architecture Part 3 - API Development

32 - Alfresco Repository Architecture

Page 62: Alfresco Exercises

Repository Foundation Services API

The heart of the Alfresco Repository is responsible for the storage and retrieval of content. This is splitinto nodes, content and index information. Nodes provide meta-data and structure to content. A nodemay support properties (e.g. author) and relate to other nodes (e.g. represent folder hierarchies orannotations). 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. Forexample, the Alfresco Document Management application relies on a model that describes Folders andFiles. Indexing information allows the retrieval of meta-data and content via many different lookupoptions.

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 adatabase immediately brings in the benefits of databases that have been developed over many yearssuch as transaction support, scaling & administration capabilities. Content is stored in the file system toallow 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 sourceprojects that already have many man-years of development effort and strong communities: Hibernateand Lucene.

Part 3 - API Development Alfresco Repository Architecture

Alfresco Repository Architecture - 33

Page 63: Alfresco Exercises

Apart from the strong Object/Relational mapping that Hibernate provides, it also brings pluggablecaching support and SQL dialects. The first allows for tuning of the Alfresco meta-data store to provideoptimum read and write performance in both single and clustered environments. The second allows fornearly any SQL database back-end by configuring just two properties; the Alfresco community hasalready 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 ispossible to perform complex queries which combine property, location, classification and full-textpredicates in a single query against any content type. Multiple query languages are supportedincluding Lucene's native language as well as XPath and a SQL-like language in the future. To ensurereliable operation, transactional support has been added to both Lucene and the content file storeproviding ACID operations across the complete store. Security is woven into each of the service layerensuring 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.

Alfresco Repository Architecture Part 3 - API Development

34 - Alfresco Repository Architecture

Page 64: Alfresco Exercises

Repository APIs

The Alfresco Repository actually provides three APIs. We've already seen one - the RepositoryFoundation Services - a set of local Java Interfaces covering all capabilities which are ideal for clientswho 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 givingstandardised 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 withanother 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 Repositorywhich supports many deployment options. Alfresco will continue investment in JCR by both broadeningthe 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 accessand bindings to any client environment, not just Java. For example, the Alfresco community is alreadyusing PHP, Ruby and Microsoft .NET. Numerous standards and integration efforts are focused aroundWeb Services - SOA is now recognised as a way forward for integrating disparate systems includingContent Management and building new enterprise-wide solutions. BPEL plays an important role inorchestrating all of these services. Alfresco fits neatly into this way of thinking.

Part 3 - API Development Alfresco Repository Architecture

Alfresco Repository Architecture - 35

Page 65: Alfresco Exercises

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

Alfresco Repository Architecture Part 3 - API Development

36 - Alfresco Repository Architecture

Page 66: Alfresco Exercises

Section 2

Developing against the Alfresco Repository

Developing against the Alfresco Repository - 37

Page 67: Alfresco Exercises

38 - Developing against the Alfresco Repository

Page 68: Alfresco Exercises

Module 1

Spring Framework

Part 3 - API Development Spring Framework

Spring Framework - 39

Page 69: Alfresco Exercises

Introduction

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

Spring Framework Part 3 - API Development

40 - Spring Framework

Page 70: Alfresco Exercises

Inversion of Control (IoC)

Through its bean factory concept, Spring is an Inversion of Control container. Spring is most closelyidentified with a flavour of Inversion of Control known as Dependency Injection. The concept behindInversion of Control is often expressed in the Hollywood Principle: “Don't call me, I'll call you.” IoCmoves 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 InjectionDependency Injection is a form of IoC that removes explicit dependencies on container APIs. OrdinaryJava methods are used to inject dependencies such as collaborating objects or configuration valuesinto 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 configuringthe one object.

Setter Injection Example

This example shows you how the Bean Factory can automatically call “setter” methods to initialiseproperty 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 SpringBean 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>

Part 3 - API Development Spring Framework

Spring Framework - 41

Page 71: Alfresco Exercises

<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@21b6dString property: a stringInt property: 125List property: [item1, item2, item3]

Spring Framework Part 3 - API Development

42 - Spring Framework

Page 72: Alfresco Exercises

Module 2

Foundation Services API

Part 3 - API Development Foundation Services API

Foundation Services API - 43

Page 73: Alfresco Exercises

Introduction

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

Foundation Services API Part 3 - API Development

44 - Foundation Services API

Page 74: Alfresco Exercises

Access to Repository Foundation Services

The Foundation Services API is comprised of a set of interfaces; each interface represents a functionof 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.

Part 3 - API Development Foundation Services API

Foundation Services API - 45

Page 75: Alfresco Exercises

FirstFoundationClient walkthrough

The following walkthrough is a practical introduction to using Foundation Services. It is based on theFirstFoundationClient 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 andContentService. After initialising the Spring Application Context and starting the repository inembedded mode, we will use the Spring getBean() method to access the ServiceRegistry. Wewill 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 propertiesand add an aspect using the NodeService. Finally, we will write some content to the new node usingthe ContentService. The sample will be wrapped in a single user transaction with the help of theTransactionService.

1) Getting the ServiceRegistry

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

The FirstFoundationClient sample uses the getBean() method on the Spring ApplicationContext 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 servicemethod is wrapped in its own transaction. These transactions are defined declaratively in Springconfiguration files and not in your Java code. In most cases, declarative transactions arepreferred to user transactions since they are less invasive. There are situations, however, whenuser transactions do need to be used explicitly in your code.

The FirstFoundationClient uses a RetryingTransactionHelper to run the example asa unit of work inside a user transaction. The work is defined as an instance of theRetryingTransactionCallback class. The doInTransaction() method is then called torun the unit of work in a transaction.

The RetryingTransactionHelper is obtained via thegetRetryingTransactionHelper() method on the TransactionService.

Foundation Services API Part 3 - API Development

46 - Foundation Services API

Page 76: Alfresco Exercises

Note: For clarity, not all of the available methods are shown. For a complete description, pleaseconsult the Javadocs: Interface TransactionService

The TransactionService and RetryingTransactionHelper are presented in more detailin the section on Transactions .

The following example runs the example work in a user transaction via theRetryingTransactionHelper:

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 mustfirst be authenticated. This is done via the AuthenticationService by using theauthenticate() method and providing a username and password. Once authenticated, aticket 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 againsta username.

Part 3 - API Development Foundation Services API

Foundation Services API - 47

Page 77: Alfresco Exercises

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

In the example, the authenticate() method is used to authenticate as the “admin” user. Thepassword 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 ofthe available query languages: Lucene, XPath or JCR-XPath. The Lucene query language allowsyou 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 storeyou wish to search, the query language (using one of the static attributes defined on theSearchService interface - LANGUAGE_LUCENE for example) and the query as a String. Theparameters can either be passed directly to the query() method, or be defined on a newSearchParameters object which is then passed to the query() method. The query results arereturned as a ResultSet object.

Foundation Services API Part 3 - API Development

48 - Foundation Services API

Page 78: Alfresco Exercises

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

The following example runs a Lucene query using the PATH syntax to locate the “CompanyHome” by it's absolute path. The getNodeRef(0) call is used to retrieve the first NodeRef fromthe 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 Searchpage 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 setwith either setProperty() or setProperties(). Properties are removed withremoveProperty(). Aspects are applied with addAspect() and removed withremoveAspect().

Associations are created and removed with createAssociation() andremoveAssociation(). Associations can be navigated with getSourceAssocs() orgetTargetAssocs(). Child associations can be navigated with getChildAssocs() andgetParentAssoc().

Almost all NodeService methods take a NodeRef as an argument. A NodeRef is obtainedeither by navigation or from the results of a search. Otherwise a new NodeRef object can becreated from the node's unique UUID.

Part 3 - API Development Foundation Services API

Foundation Services API - 49

Page 79: Alfresco Exercises

Note: For clarity, not all of the available methods are shown. For a complete description, pleaseconsult 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 isidentified 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)

Foundation Services API Part 3 - API Development

50 - Foundation Services API

Page 80: Alfresco Exercises

nodeRefNodeRef of the node to set the property on.qnameQName of the property to set.valueValue of the property. The value must be Serializable.propertiesMap of all the properties of the node keyed by QName.

The property QNames are usually defined as a static constants on the dictionary modelinterfaces. For example, the cm:name property is defined by the static constantContentModel.PROP_NAME.

The following example creates a Map containing the cm:name property that will be used inthe 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 aparent node. The child association name and child association type have to be supplied asQName objects, as well as the QName of the type of node to create and optionally a Map ofproperties to set on the newly created node.

public ChildAssociationRef createNode(NodeRef parentRef,QName assocTypeQName,QName assocQName,QName nodeTypeQName,Map<QName, Serializable> properties)

parentRefNodeRef of the parent node. The created node will be one of it's children.assocTypeQNameQName of the type of association to create. This is used for verification against the datadictionary.assocQNameQName of the association.nodeTypeQNameQName of the node type.propertiesOptional Map of properties to set keyed by QName.

The association and node type QName objects are usually defined as a static constants onthe dictionary model interfaces. For example, the cm:contains association type is definedby the static constant ContentModel.ASSOC_CONTAINS and the cm:content node typeis defined by the static constant ContentModel.TYPE_CONTENT. If a constant does notexist, a QName can be created using the QName.createQName() static method as in theexample below.

The createNode() method returns a ChildAssociationRef to the newly created childassociation. The NodeRef of the newly created node is obtained by calling thegetChildRef() on the ChildAssociationRef object.

Part 3 - API Development Foundation Services API

Foundation Services API - 51

Page 81: Alfresco Exercises

The following example creates a new node of type cm:content, using the standardcm:contains child association. The Map created in the previous step sets the cm:nameproperty 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'sNodeRef 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)

nodeRefNodeRef of the node to apply the aspect to.aspectTypeQNameQName of the aspect to apply.aspectPropertiesMap containing a minimum of the mandatory properties required for the aspect.

The aspect QNames are usually defined as a static constants on the dictionary modelinterfaces. For example, the cm:titled aspect is defined by the static constantContentModel.ASPECT_TITLED.

The following example applies the cm:titled aspect and sets the cm:title andcm: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 aContentWriter via the getReader() and getWriter() methods respectively. Methods canthen be used on the ContentReader or ContentWriter to read and write content. Both theContentReader and the ContentWriter implement the methods defined by theContentAccessor interface. These methods allow you to get and set information about thecontent, 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) ofeach node. When requesting a ContentReader or a ContentWriter, the NodeRef needs to

Foundation Services API Part 3 - API Development

52 - Foundation Services API

Page 82: Alfresco Exercises

be supplied along with the ContentModel.PROP_CONTENT QName.

The ContentService is also used for transforming content. A suitable transformer can beobtained for a given transformation (defined by a source and target mime type) using thegetTransformer() and getImageTransformer() methods. The transformation can then beperformed by calling transform directly on the content transformer. Otherwise, a transformationcan be attempted from a source ContentReader object to target ContentWriter object bycalling 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, pleaseconsult the Javadocs:

• Interface ContentService• Interface ContentReader• Interface ContentWriter• Interface ContentAccessor

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

Part 3 - API Development Foundation Services API

Foundation Services API - 53

Page 83: Alfresco Exercises

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.

Foundation Services API Part 3 - API Development

54 - Foundation Services API

Page 84: Alfresco Exercises

Other Foundation Services

FileFolderService

The FileFolderService provides methods specific to manipulating Alfresco defined content filesand folders. The methods can be more convenient and easier to use than the equivalentNodeService and ContentService methods. Certain methods, such as create(), return aFileInfo 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, pleaseconsult the Javadocs:

• Interface FileFolderService• Interface FileInfo

Part 3 - API Development Foundation Services API

Foundation Services API - 55

Page 85: Alfresco Exercises

Foundation Services API Part 3 - API Development

56 - Foundation Services API

Page 86: Alfresco Exercises

Module 3

JCR API

Part 3 - API Development JCR API

JCR API - 57

Page 87: Alfresco Exercises

Introduction

The JCR API (Java Content Repository) specifies a standard, implementation independent API toaccess content repositories in Java. It is defined by the Java Specification Request (JSR) 170 as partof the Java Community Process (JCP). The official JSR-170 Specification can be found on the JCPweb 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 thenext version of JCR defined by the Java Specification Request (JSR) 283.

JCR API Part 3 - API Development

58 - JCR API

Page 88: Alfresco Exercises

Module 4

Web Services API

Part 3 - API Development Web Services API

Web Services API - 59

Page 89: Alfresco Exercises

Introduction

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

Web Services API Part 3 - API Development

60 - Web Services API

Page 90: Alfresco Exercises

Available Web ServicesThe following Alfresco Web Services are available:Authentication

login and logoutRepository

query and model manipulationContent

content manipulationAuthoring

collaborative content creationClassification

apply classifications and categoriesAccess Control

roles, permissions & ownershipAction

manage actions and rulesAdministration

user management, export & importDictionary

model descriptions

Part 3 - API Development Web Services API

Web Services API - 61

Page 91: Alfresco Exercises

Web Services API Part 3 - API Development

62 - Web Services API

Page 92: Alfresco Exercises

Module 5

Separating Concerns using AOP

Part 3 - API Development Separating Concerns using AOP

Separating Concerns using AOP - 63

Page 93: Alfresco Exercises

Public Services and AOP proxies

The public services defined in public-services-context.xml are in fact Spring AOP proxies. Forexample, the public ContentService bean defined in public-services-context.xml is anAOP proxy to the “target” service defined by the contentService bean found incontent-services-context.xml. The AOP proxy allows cross cutting concerns such as securityand transaction management to be implemented in a non-invasive, declarative way. All service methodcalls via the ContentService bean defined in public-services-context.xml are subject tosecurity checks and transaction management whilst those via the contentService bean defined incontent-services-context.xml are subject to none!

Note: All public service Spring beans have ids that begin with an uppercase letter. Public services aresubject to security checks and transaction management. Beans with equivalent names that begin witha lowercase letter are subject to none.

All public services AOP proxies are defined using a Spring ProxyFactoryBean. The ContentServiceexample 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 theContentService bean do not see the ProxyFactoryBean but the object defined by the targetproperty, in our case, the contentService bean. The proxyInterfaces property, defines an arrayof 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 bethe first to be able to intercept the method call.

The ContentService_transaction interceptor is a reference to a local bean inpublic-services-context.xml that manages transactions for calls to the ContentService.The ContentService_security is a reference to a bean inpublic-services-security-context.xml that enforces security checks for calls to theContentService.

Separating Concerns using AOP Part 3 - API Development

64 - Separating Concerns using AOP

Page 94: Alfresco Exercises

Section 3

Extending the Alfresco Repository

Extending the Alfresco Repository - 65

Page 95: Alfresco Exercises

66 - Extending the Alfresco Repository

Page 96: Alfresco Exercises

Module 1

Repository Policies

Part 3 - API Development Repository Policies

Repository Policies - 67

Page 97: Alfresco Exercises

IntroductionRepository policies are similar to events. Each service defines its own set of policies. For example theContent 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 automaticallywhen the policy is fired. This enables tasks such as maintaining the last modified date on a node orcreating 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.

Repository Policies Part 3 - API Development

68 - Repository Policies

Page 98: Alfresco Exercises

Available Policies

The available policies are defined as interfaces for each service. The Node Service defines more thantwenty policies, including BeforeCreateNodePolicy, OnUpdatePropertiesPolicy andOnAddAspectPolicy, the other services each define their own specific policies. The policies areusually defined on an interface named after the service. For example, the Node Service policies aredefined on the NodeServicePolicies interface and the Content Service policies are defined on theContentServicePolicies interface:

Classes interested in certain policies must implement the corresponding interfaces and methods. Eachpolicy method (or behaviour) defines its own specific list of arguments. For example:

• A behaviour registered against the BeforeCreateNodePolicy is called before a node iscreated. The beforeCreateNode() method receives the NodeRef of the parent of the nodebeing created, the QName of the association type (usually cm:contains), the QName of the newassociation and the node type of the node being created.

• A behaviour registered against the OnCreateNodePolicy is called when a node is created. TheonCreateNode() method receives the ChildAssociationRef to the node created.

Part 3 - API Development Repository Policies

Repository Policies - 69

Page 99: Alfresco Exercises

Policy TypesEach 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 eventsrelated to properties and Association policies for events related to associations. Most policies extendthe Class policy interface, a few policies extend the Association policy interface and, at the time ofwriting, none extend the Property policy.

Repository Policies Part 3 - API Development

70 - Repository Policies

Page 100: Alfresco Exercises

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 withbehaviour that can be packaged and deployed to the Alfresco Repository.

Before starting the tutorial, you should be familiar with Alfresco Content Models and the SpringFramework on page 40 .

In the tutorial we are going to define a new Content Hits aspect with behaviour that will automaticallykeep a running count of the number of times the content on a node has been updated and read. Theexample demonstrates how the counters can be incremented after the content update or readtransactions 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. Thech:updateCount and ch:readCount properties will be incremented for each content updateor 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 implementsContentServicePolicies.OnContentReadPolicy,ContentServicePolicies.OnContentUpdatePolicy,NodeServicePolicies.OnAddAspectPolicy

Part 3 - API Development Repository Policies

Repository Policies - 71

Page 101: Alfresco Exercises

2.2) Writing the constructor

The Content Hits example uses a Transaction Listener to increment the counters after thecontent 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 maybe 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)

instancethe object instance holding the methodmethodthe method name

Repository Policies Part 3 - API Development

72 - Repository Policies

Page 102: Alfresco Exercises

frequencyone 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 onFoundation Services that can be resolved using Spring dependency injection.

A behaviour is bound to a policy using the bindClassBehaviour() method on the PolicyComponent:

bindClassBehaviour(QName policy,QName classRef,Behaviour behaviour);

policythe policy nameclassRefQName of type or aspect concerned by the policybehavioura 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 policybehaviours.

In the Content Hits example, the Spring initialise() method is used to bind thebehaviours 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 isadded to a node. It receives the NodeRef of the node concerned and the QName of theadded aspect. In the example, the added aspect will always be ch:contentHits since thebehaviour has only been registered for that specific aspect.

The onAddAspect() behaviour sets the count start date/time when the ch:contentHitsaspect is added:

public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName){

Part 3 - API Development Repository Policies

Repository Policies - 73

Page 103: Alfresco Exercises

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 nodewith 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 afterthe content update or read transactions have been committed. The Transaction Listener isbound to the current transaction using the static bindListener() method on theAlfrescoTransactionSupport class and passing the Transaction Listener createdearlier.

The list of nodes read is stored as a resource against the current transaction using the staticbindResource() method on the AlfrescoTransactionSupport class. The nodes arestored 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 ofnodes that require read count increments after the transaction completes:

public void onContentRead(NodeRef nodeRef){

// Bind the listener to the transactionAlfrescoTransactionSupport.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 nodewith the ch:contentHits aspect is updates. It receives the NodeRef of the node beingupdated 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 thethe KEY_CONTENT_HITS_WRITES key.

The onContentUpdate() behaviour adds the NodeRef of the node being updated to thelist of nodes that require write count increments after the transaction completes:

public void onContentUpdate(NodeRef nodeRef, boolean newContent){

// Bind the listener to the transactionAlfrescoTransactionSupport.bindListener(transactionListener);// Get the set of nodes written@SuppressWarnings("unchecked")

Repository Policies Part 3 - API Development

74 - Repository Policies

Page 104: Alfresco Exercises

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() oronContentUpdate() behaviour methods. The afterCommit() method is called on theTransaction Listener after the transaction has committed.

In the example, the Transaction Listener is defined as an inner class. It implements theafterCommit() method.

private class ContentHitsTransactionListener extendsTransactionListenerAdapter{

public void afterCommit(){

...}

}

The afterCommit() method retrieves the list of nodes stored as a resource on thetransaction 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 = newContentHitsReadCountIncrementer(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 thetransaction 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 = newContentHitsWriteCountIncrementer(nodeRef);

threadExecuter.execute(runnable);}

}}

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

Part 3 - API Development Repository Policies

Repository Policies - 75

Page 105: Alfresco Exercises

2.8) Writing the Spring dependency injection setter methods

The ContentHitsAspect class uses several services that can be injected via Spring:

private PolicyComponent policyComponent;private BehaviourFilter policyFilter;private NodeService nodeService;private TransactionService transactionService;private 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 fromcontents-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 definitiontaken 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 theproperties set.

5) Configuring the property sheet

Repository Policies Part 3 - API Development

76 - Repository Policies

Page 106: Alfresco Exercises

In order to see the Content Hits aspect properties in the Web Client, the property sheet has to beconfigured 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 filesneed 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 thefollowing 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 anAlfresco Module Package (AMP). For more details, see Alfresco Module Packages on page .

Part 3 - API Development Repository Policies

Repository Policies - 77

Page 107: Alfresco Exercises

Repository Policies Part 3 - API Development

78 - Repository Policies

Page 108: Alfresco Exercises

Module 2

Repository Actions

Part 3 - API Development Repository Actions

Repository Actions - 79

Page 109: Alfresco Exercises

Introduction

An action is a unit of work that is performed against a node. For example, moving a node, copying anode, 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.ActionExecuterinterface. The ActionExecuter interface can be implemented directly, however it is best to extendthe abstract class ActionExecuterAbstractBase that has been written to provide basic servicesfor action executer implementations. Only two methods need implementing when deriving from theabstract superclass.

Note: For clarity, not all of the available methods are shown. For a complete description, pleaseconsult the Javadocs:

• Interface ActionExecuter• Class ActionExecuterAbstractBase

Repository Actions Part 3 - API Development

80 - Repository Actions

Page 110: Alfresco Exercises

Module 3

Content Transformers

Part 3 - API Development Content Transformers

Content Transformers - 81

Page 111: Alfresco Exercises

Introduction

A content transformer is a Java class that can transform content from one mime type to another. Manycontent transformers already exist, however it is possible to add you own custom content transformerin a few easy steps.

A content transformer has to implement theorg.alfresco.repo.content.transform.ContentTransformer interface.ContentTransformer extends the org.alfresco.repo.content.ContentWorker interfacethat is a common marker interface for specific “worker” interfaces such as content transformers andmetadata extractors.

An abstract base class called AbstractContentTransformer has been written to provides basicservices for ContentTransformer implementations. Only two methods need implementing whenderiving from the abstract superclass.

Note: For clarity, not all of the available methods are shown. For a complete description, pleaseconsult the Javadocs:

• Interface ContentTransformer• Class AbstractContentTransformer

Content Transformers Part 3 - API Development

82 - Content Transformers

Page 112: Alfresco Exercises

Module 4

Metadata Extractors

Part 3 - API Development Metadata Extractors

Metadata Extractors - 83

Page 113: Alfresco Exercises

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 metadataextractor in a few easy steps.

A metadata extractor has to implement theorg.alfresco.repo.content.metadata.MetadataExtracter interface.MetadataExtracter extends the org.alfresco.repo.content.ContentWorker interface thatis a common marker interface for specific “worker” interfaces such as metadata extractors and contenttransformers.

An abstract class called AbstractMappingMetadataExtracter has been written to provides basicservices for MetadataExtracter implementations. Only one method needs implementing whenderiving from the abstract superclass.

Note: For clarity, not all of the available methods are shown. For a complete description, pleaseconsult the Javadocs:

• Interface MetadataExtracter• Class AbstractMappingMetadataExtracter

Metadata Extractors Part 3 - API Development

84 - Metadata Extractors

Page 114: Alfresco Exercises

MetadataExtracterRegistry

The MetadataExtracterRegistry holds a list of available metadata extractors and provides themost appropriate extractor for a particular mime type extraction request.

Upon initialisation, metadata extractors register themselves with the MetadataExtracterRegistryvia the register() method.

Note: For clarity, not all of the available methods are shown. For a complete description, pleaseconsult the Javadocs: Class MetadataExtracterRegistry

The getExtracter() method is used by clients to get the most appropriate metadata extractor for aparticular mime type.

The MetadataExtracterRegistry bean is defined in the content-service-context.xmlSpring configuration file:

<!-- Metadata Extraction Regisitry --><bean id="metadataExtracterRegistry"class="org.alfresco.repo.content.metadata.MetadataExtracterRegistry" />

Part 3 - API Development Metadata Extractors

Metadata Extractors - 85

Page 115: Alfresco Exercises

Metadata Extractors Part 3 - API Development

86 - Metadata Extractors

Page 116: Alfresco Exercises

Section 4

Extending the Alfresco Web Client

Extending the Alfresco Web Client - 87

Page 117: Alfresco Exercises

88 - Extending the Alfresco Web Client

Page 118: Alfresco Exercises

Module 1

JavaServer Faces

Part 3 - API Development JavaServer Faces

JavaServer Faces - 89

Page 119: Alfresco Exercises

Introduction

JavaServer Faces (JSF) is a user interface framework for Java web applications. JSF defines anevent-driven, component-based model for web application development, similar to the model that hasbeen used successfully for standalone GUI applications for years. JSF’s core architecture is designedto be independent of specific protocols and markup. However it is also aimed directly at solving manyof the common problems encountered when writing applications for HTML clients that communicate viaHTTP to a Java application server that supports servlets and JavaServer Pages (JSP) basedapplications.

JSF is a specification (JSR-252) that has been developed as part of the Java Community Process. It isa standard, vendor independent specification. Several implementations exist, including the GlassFishJavaServer Faces reference implementation and Apache MyFaces . Alfresco uses the ApacheMyfaces implementation.

The specification defines a set of standard user interface components and an API for extending thestandard components or developing new ones.

As well as UI components, JSF also defines artifacts like converters, validators, events listeners, andrenderers:

• converters perform type conversion between server-side Java objects and their representation inthe user interface. A good example is a date;

• validators can be associated with a JSF component to perform input validation checks on localvalues before they are processed;

• event listeners are registered against events that are triggered when a user clicks a button or alink, changes a value in a field, or makes a selection in a list. The outcome of the eventprocessing controls which page is displayed next;

• renderers generate the actual markup for the user interface. JSF is not limited to HTML or anyother markup language and the same JSF component can be coupled with different renderers toproduce different output, for example, either HTML or WML;

JavaServer Faces Part 3 - API Development

90 - JavaServer Faces

Page 120: Alfresco Exercises

Module 2

Actions Framework

Part 3 - API Development Actions Framework

Actions Framework - 91

Page 121: Alfresco Exercises

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 acrosspages. 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 aredefined in the web-client-config-actions.xml configuration file. You can define your owncustom UI actions and action groups in a Web Client configuration extension file. You can also extendexisting action groups to add your own custom UI actions to existing menus in the Web Client.

Actions Framework Part 3 - API Development

92 - Actions Framework

Page 122: Alfresco Exercises

Module 3

Dialog Framework

Part 3 - API Development Dialog Framework

Dialog Framework - 93

Page 123: Alfresco Exercises

Introduction

The dialog framework manages the user interface dialogs in the Alfresco Web Client. Most of thestandard Web Client dialog are managed by the framework and it is possible to create your owncustom 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 AlfrescoNavigation Handler looks up the <dialog/> configuration then calls the Dialog Manager to initialisethe dialog and instantiate the managed bean before navigating to the dialog JSP page.

See Dialog Manager on page for more details.

Dialog Framework Part 3 - API Development

94 - Dialog Framework

Page 124: Alfresco Exercises

Module 4

Wizard Framework

Part 3 - API Development Wizard Framework

Wizard Framework - 95

Page 125: Alfresco Exercises

Introduction

The wizard framework manages the user interface wizards in the Alfresco Web Client. Most of thestandard Web Client wizards are managed by the framework and it is possible to create your owncustom wizards using the framework.

Each wizard has three main components:

• A <wizard/> configuration element in a web-client-config.xml file.performed in exactlythe 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 AlfrescoNavigation Handler looks up the <wizard/> configuration then calls the Wizard Manager to initialisethe wizard and instantiate the managed bean before navigating to the JSP page for the first step.

See Wizard Manager on page for more details.

Wizard Framework Part 3 - API Development

96 - Wizard Framework

Page 126: Alfresco Exercises

Alfresco 3.1 Administrator Exercises

Page 127: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - i

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

Page 128: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - 1

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.

Page 129: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - 2

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.

Page 130: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - 3

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>/file-

servers-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>/file-servers-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

Page 131: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - 4

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.PropertyPlaceholderConfigurer">

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.

Page 132: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - 5

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?

Page 133: Alfresco Exercises

Alfresco 2.1 Administrator Exercises

Administrator Exercises - 6

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 it’s 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.