Tuesday, May 10, 2005

globalful

Given the sparse contributions to this blog, it's pretty obvious that I need some significant motivation/inspiration to set finger to keyboard. Today I found it in globalful which is a cracking example of a stream-of-consciousness blog. I got the link from
Robin Wilton's blog - he had just come up to Edinburgh to do a guest lecture spot for me on identity management - thanks Robin!

Thursday, February 24, 2005

Plone days

As promised, my notes so far on setting up, configuring and using Plone. These notes were compiled over the space of several weeks, so they do not necessarily read smoothly. Should be quite useful in the future though:

Plone


Zope/Plone installed with absolutely no hitches under Windows XP. Likewise the SimpleBlog add-in product. Quite a different story from the various J2EE products that I have been trying under Linux. I will try Plone under Linux later.
Currently, I have one additional user (test) set up apart from the site owner. When test logs in, there is a 'recently created' link to velociter's blog entry. But no way to navigate to velociter's home page - the links don't show up on the 'members' menu.
Created a directory under the site root, and now the navigation portlet on the home page shows each entry twice:
Don't know what's going on there - it doesn't happen on other pages, but it does happen for my test user. Could be something to do with something that happened earlier: I created a customised default page for the site root, and the title did not show up as expected. Using a property other than 'title' resolved the problem, but that's not very neat. So, I tried deleting and re-creating the title property (as per the warning comment). I could delete it OK, but when I came to re-create it, I got an error saying that there were duplicate property names. Somehow the title property still existed, but was not visible. I moved on to more urgent things, but perhaps the new issue is related? We'll see…
I had followed the how-to instructions to create a default page, and when I got to step 4, I used 'custom/index_html' . This caused the TAL macros to fail, the 'custom' folder to appear in the navigation tree, and all other navigation items to appear twice. Posted this as a comment on Plone.org.

Changing the entry page


By default, this has a main central section and items in the left and right slots. This needs to be changed to a single portlet that provides minimal information and the option to log in. I'm not sure at this stage whether I will be able to get external authentication working, so I'm going to leave the 'join' option in the toolbar until later. UPDATE _ Actually disabled the join link by changing the action setting at /portal_registration in the ZMI. I am going to import all user details, so there is no need for the link.
The standard login form has most of the features I need, so I'm going to use a customised version as my entry page.
To redirect anonymous users to the login page, follow the how-to instructions. Use the version at the bottom of the page.

  • Created customised version of 'login_form'

  • Altered default portlets so they are not displayed for anonymous users by adding the following macro to the first DIV tag:

  • &nbs;&nbs;tal:condition="python: not isAnon"

  • Suppress tabs for anonymous users by adding same condition to plone_templates/global_sections

  • Suppress seach box in the same way by altering plone_templates/global_searchbox



Advanced search


Very easy - just follow the how-to instructions. I didn't have a search tab in my default installation, so I just ignored the first bit.

Blog


Used the SimpleBlog product from http://plone.org/newsitems/News_Item.2003-11-06.2538
Worked out of the box.
Had a bit of a problem when I upgraded Archetypes to install CMFMember. For some reason the portal_transforms tool got lost. This caused an attribute error when looking for the portal_transforms tool. Easily fixed by re-installing portal_trandforms.
Fixed the general document and discussion bylines to show the full name not the username, and to link to the user's profile by creating custom versions of

  • CMFPlone/skins/Plone content/document_byline.pt

  • CMFPlone/skins/plone_templates/viewThreadsAtBottom.pt

  • CMFPlone/skins/plone_content/discussionitem_view.pt


Changed the mode of the id field in Blog.py to “r”. This prevent students from changing the short name from MyBlog. This is important to ensure that the link from students' profiles works correctly.
Had a weird permissions problem when people were trying to make a blog entry. If they tried to set the short name (id), they got a message saying they had insufficient privileges. If they left the short name field blank, a default id was generated, and the entry was created with no problem. Didn't have time to work out exactly what was going on, so I just set the id field to be read only in BlogEntry.py.

Allow ordinary users to add keywords


In the early stages of the module, I want a free-for-all so that we end up with a disorganised set of subject keywords. Later, an exercise will be to sort this out and start to use controlled vocabularies.
The setting to assign roles the ability to add new keywords is in the portal_properties tool under site-wide properties.

Default objects/layout for new user


Using notifyMemberAreaCreated - http://www.mxm.dk/products/public/dmcs/
notifyMemberAreaCreated.py/view

And also the how-to on creating a pre-populated folder - http://plone.org/documentation/howto/pre-populated-folder
Current problem: How to set the value of a field in a newly-created object. Time to ask for help? I think so. Posted a question to Gmane.
… and got a response within about 12 hours ! Pretty good
The suggestion did not work straight off, but that is due to a number of other errors in the code. I am finding it a bit frustrating that the error reporting is so sketchy. I have installed the add-on product VerboseSecurity, but I'm not sure that it is adding much to the standard Plone error reporting.The problem is that a number of errors produce no feedback at all. You are left wondering why nothing happened, and all you can do is try to work out by a process of elimination which line of your file is causing the error. If there is more than one error, even this approach is not foolproof.
Anyway, I did get the suggested method working eventually, and will send off a message to the author. Again, it does not work 100% because there are certain attributes of certain type of object that cannot be set; however, I have no time right now to get to the bottom of it - one to come back to later?
Had a major crisis over this - it turned out that objects created in a new user account appeared to be owned by the manager account that had created them - see the importing users notes below.

Notification of tasks, etc


Not a problem - tasks are implemented as content types, and appear in the review portlet automatically.

Workflows for practical exercises


The default role and permission handling is pretty slick. When a document is waiting to be reviewed, a special portlet appears in the interface of those users who have reviewer privileges. Transitioning the object to a new status is a two-click operation.
The information in The Plone Book (online at http://www.the-forgotten.org/documents/PloneBook/) is a little out of date, and I had to look for equivalent functionality in the version of Plone that I am using. This was fairly straightforward however, and I expect that printed material is more recent.
This page is a good overview with simple steps that are easy to follow: http://www.zope.org/Members/mitchtrachtenberg/workflowhowto/
For the module, I want users in a particular role to raise a request, for users in another role to pick up that request, and eventually for the document to be either published or rejected.
Make sure that researchers are allowed to create objects in the exercise folders by setting add_portal_content permission.
Steps:

  1. Design the new workflow as a state diagram

  2. Create a copy of the default Plone workflow in the ZMI

  3. Alter the states to match the diagram

  4. Alter the transitions to match the diagram

  5. For each state, set the appropriate permissions - we rely on folder permissions to restrict access by team

  6. Assign the workflow to a type of content

  7. Set up the KB and Researcher worklists


Groups and/or roles


Requirements:
There are three tutorial groups, which are further split into three teams each. Every team needs access to their own folders, but sometimes an exercise requires a whole tutorial group to work together, and occasionally, the whole year group. I am going for a post-combination strategy whereby I define roles and groups of the smallest size - ie to represent the groupings at team level. Where more than one of these groups needs access to a folder, I will add permissions for all the required groups.
In addition, within a team, different members will have different roles in the workflows. This should be independent of the access permissions. In theory, I should be able to assign researcher and knowledge broker roles within team A, for example, and for those items accessible to the team A KB to be inaccessible to a KB in team B, say. This should be taken care of by the situated nature of the documents - that is, a KB document will be created in a particular folder and will therefore only be accessible to the team owning the folder. It may be that I have to do something clever to prevent a lot of inaccessible documents showing up in search results.
Re above. Got this patch from the German Zope site, http://www.dzug.org/mailinglisten/zope/archive/2003/2003-08/1059728134640 - thanks to Marian Saeger.
In CMFCore/CatalogTool.py, alter the function allowedRolesAndUsers replacing the two lines
for r in rolesForPermissionOn('View', ob):
allowed[r] = 1

with these four lines

aci_roles = rolesForPermissionOn('Access contents information', ob.aq_parent)
for r in rolesForPermissionOn('View',ob):
if r in aci_roles:
allowed[r] = 1

ie - check that the user has view permission on the containing folder as well as on the object itself.
This change makes the systems very sensitive - you have to get the permissions matching exactly. Don't forget that we are matching up view permissions on the object and contents permissions on the folder…
This patch affects how the allowedUsersAndRoles index is built - if any changes are made, you have to reindex.
Also, need to check whether I need to add a script to reindex the object as it transitions from state to state in the workflow. - Doesn't seem to be necessary.
Left some debug entries in catalogTool.py, but commented them out because they are very noisy.
See course docs at http://www.upfrontsystems.co.za/courses/plone/
ch01.html#id2528990

Also, some useful notes at http://tomster.org/geek/plonezope/limitedaccess
One important thing - don't give the role the same name as the group. This causes all sorts of strange behaviour.
For each set of users that requires a different presentation, set up a role using the ZMI, and a group using the plone setup interface.
To restrict access to a particular folder - go to that folder in the ZMI and change the security settings for 'Access contents information' and 'View'. Uncheck the acquire box, and check the manager box, and the box for the appropriate role. Go to that folder in the Plone interface and add the appropriate group to the sharing permissions.

To allow members of a group to access on of the protected folders, create a local role on the folder. To grant access to A_group on a folder restricted to RoleA, for example, set A_group to have local role RoleA..
Restricting access by group/role is very sensitive. To ensure that a search operation returns restricted documents, the containing folder must have the view contents permission explicitly set for the allowed role.
Creating static documents using DreamWeaver
I'm just creating standard DW pages with no header and uploading them using the standard Plone edit dialogue. There is a way to get Webdav working, but I decided not to attempt this. There were a number of comments from people who had experienced problems, and some additional add-on products, so there was a risk that I would use up more time getting Webdav working than I would save. One to come back to…?
Creating DW pages is a dawdle. Images can be included by creating an images folder and uploading the images files there. Relative paths work with no problem.
To include inline hyperlinks, use the following:




Link typeDW link text
Document in same folder<document name, no extension>/document_view
Document in other folder
This folder view. (single dot - Plone replaces with current location)
Another folder view


Alternatively, to display a button to perform a navigation operation, use the following code, replacing the red text with appropriate values:

<form name="contents" action="http://localhost/Practicals/W2-sense/" method="post">
<input class="standalone" type="submit" value="Return to contents">
</form>

Notice that this method requires an absolute URL.

Discussion as a new document type


Creating a static discussion is easy. Just set up a document with an empty body, or just some introductory text, and allow discussions on it. Could also add a welcome message.
Allowing users to create new discussion is also easy as long as they are related to a document. Stand-alone discussion are more tricky because users would have to create them as a document first, which is confusing.
I tried out various versions of CMFBoard, but once I found a working version (2.1.2) I found the interface very complex. The authors were clearly trying to make it feature-rich, and had included support for fancy text formats and visual smileys. However, I don't want my students to be distracted by unnecessary clutter, so I have decided to go with the default discussion functionality, and to set up discussion where I think they need to be. Students will be able to start new threads within each one, so not being able to create a whole new discussion should not be a problem.

LDAP authentication


Blogroll portlet


Instant message


Used CMFMessage downloaded from http://prdownloads.sourceforge.net/collective/CMFMessage-1_1.tgz?download
This is a simple IM tool that maintains a list of active users and allows you to send one message at a time. There are other products available such as PloneIM (http://www.gocept.com/angebot/opensource/PloneIM/) but not only is that product less mature, there is also a performance warning that more than 10 users at a time can be a problem.
I altered the behaviour of the default installation of CMFMessage so that the full name of active users is displayed rather than the username, and I removed the 'New message' button from the messages portlet. There is link next to each active user to send them a message, and this is all that is required. With the 'New Message' button, the user has to know the username of the person they are sending to. I also restricted the list of displayed names to the user's team members.
When CMFMessage is added, users automatically have the privilege to add messages throughout the site, so all pages appear with a border and the option to add a message. I did not want this to be the case for the static pages, so I altered the security setting on the site root to disallow 'add portal messages', and allowed 'add portal messages' on the Members folder.

Shortcuts in the navigation tree


RSS feeds


Search and metadata (plone/portal_catalog)


User profiles


Requirements: Users must be able to store information about their own skills/interests, and other users must be able to search on these.
/Plone/portal_skins/plone_forms/member_search_results
Attempt 1-----
Add new property into Plone/memberdata
Add corresponding field to Plone/plone_skins/plone_forms/personalize_form

Created new version of member_search_results that calls new member_profile form instead of just the member's home page
Member_profile combines portrait, skills, homepage and blog link.
… stopped this tack to try…
Attempt 2 -------
Found an add-on product called CMFMember with uses the Archetypes framework to turn members into ordinary portal objects. This should make it much easier to provide the kind of profile and search functionality that I want.
The steps are quite involved:

  1. Upgrade Archetypes to 1.3.0

  2. Install and run ZopeTestCase from http://zope.org/Members/shh/ZopeTestCase

  3. Install CMFMember product

  4. Migrate existing users to new model


Actually, you don't do things in this order even though it looks logical. CMFMember triggers an installation of Archetypes, and if you install Archetypes first, you get an error. If any installed products depend on Archetypes, the resolution is to uninstall them, and start again with CMFMember. Once you get things in the right order, everything goes smoothly.
Create new form, member_profile, in Plone_skins/custom
Change view action on new Member type to use this form
To get the new fields in the member object, the schema needs to be altered. I'm using the documentation from these two links:
http://plone.org/documentation/archetypes/
wiki/UpdatedContentTypesHelp

http://plone.org/documentation/archetypes/
wiki/SubclassCMFMember/view

Way too difficult. I followed the instructions to the letter but when there were errors, there was no obvious way to get feedback on them. Wasted a whole day trying to do this, so I'm going to try a different approach. Kept CMFMember though - it does make it easier to administer users, roles and groups.
Attempt 3 ----
This time I'm starting by building my own archetype from scratch - well, perhaps not quite from scratch. I am using a number of existing files from other products as templates, but it's mostly my own work…
I have set up a profile object which contains the additional fields I wanted on the membership record, and the plan is to use the standard subject metadata field to store the person's expertise. The portrait will be pulled into the view form, and everything will look just right.
So far I have got the archetype set up, I have produced a view form that shows the main fields and the portrait, and now I am trying to get a custom edit form working. The base_edit form from the Archetypes product was too opaque - couldn't make out where all the macros came from or how they related to each other. I ended up copying the standard document_edit form and I am customising the contents. When I first ran it I got a number of errors including:
Keyerror: 'state'
The state object is the one that maintains the current state of the form all the way through the updating process. It traps errors and triggers the final actions once all validation has succeeded. The error message suggests that the state object doesn't exist. It turns out that I was using the wrong file extension. Where I was using .pt I should have used .cpt. This indicates to Plone that the form is a controller form, and that is what instantiates a state object.
Now I have the form working properly apart from one small detail - I discovered along the way that I needed to create a metadata file too. This holds some configuration details which tell the form which scripts to use to validate the contents, and what actions to perform afterwards. The missing detail, of course, is that changes to the form contents are not stored. Whatever changes I make in the edit form, the old contents pop back up in the viewer. More Googling…
OK - got this working as well. The main information came from the Definitive Plone Book at http://docs.neuroinf.de/PloneBook/ch6.rst
The trick is to chain together the form and an action script that does the saving, plus and validation scripts that may be required in between. The chaining is take care of by a .metadata file for each object in the chain. There appears to be no limit to the number of scripts that can be chained in this way.
To handle the storage of new form values, it is possible to refer to existing Archetypes scripts. The main one is content_edit. This has onward links to a series of other scripts, but eventually control is returned to either the view form or the edit form for the object being updated. Pretty neat actually.
Another neat thing: I can access a pre-defined Archetypes widget with one line of code. This line renders a LinesWidget for the field 'interests' as defined in the Profile schema:

My profile form combines content and metadata so that users can search for people with particular skills using the subject metadata field. I had to do some hacking to create a single form to update both types of data. It was not made easy by the fact that updating content and metadata are done in different ways. In the end, I copied the metadata_edit.py script from CMFDefault and renamed it profile_subject_edit.cpy. I stripped it down so that it only updated the subject field based on the two request fields subject_keywords and subject_exisitng_keywords. I am sure there is a more elegant way to do this, but hey - it works!
To fix permissions so that only a manager can create or delete a profile, go to the security tab at the site root, and restrict IDProfile: Add content permission to the manager role.
Added code to allow the user to change their portrait by copying from CMFPlone/plone_pref/personalize_form.cpt. Also changed the processing script profile_subject_edit.cpy. This was a little trickier though because I am using Archetypes, and there was very little information on how to handle image fields. Eventually I used the following lines to set and unset the portrait:
if (portrait and portrait.filename):
member.setPortrait(portrait)

delete_portrait = context.REQUEST.get('delete_portrait', None)
if delete_portrait:
member.setPortrait("DELETE_IMAGE")
I also disabled the my preferences link in the personal bar, and added a direct link to the change password field. This is done by changing the actions at /portal_membership in the ZMI.

Importing users


Use the form Plone/acl_users in the ZMI. Paste all the usernames (matric numbers) into the 'Create users' field, specify a default password in the eponymous field, and click 'Create'
Actually, on second thought, don't use matric numbers - use firstname_surname. Longer to type in, but it will make sure that the bylines are comprehensible. (or fix the byline so that it displays the full name…).
Select all new users and assign role 'Member'
PROBLEM: When users are created using this method, or using the csv import facility, the default objects appear to be created by the manager account, not the new user account. This is a problem for the way my profile_view form works. I either have to fix the notifyMemberAreaCreated script, or find a way to update all created objects afterwards.
There is also a weird thing going on with the titles of the new objects. I set the title of the index_html file in the notify… script to be , but the function “getFullName” does not work in that context - perhaps the record has not been saved yet?
This problem is a bitch. I have spent a good two days now trying to get this to work. The last approach was to create an external method to do the ownership change, because EMs are not subject to the same security restrictions as ordinary scripts. I have a second script which calls the EM, and the feedback shows that the operation has been successful - except it hasn't. If I look at the object or run the script a second time, the original owner is still there. I've posted a call for help on the Plone users newsgroup.
I think I may have cracked it - the standard function, manage_fixupOwnershipAfterAdd which was in the original script I was using as a model does appear to work, but only if the objects created are first accessed by their rightful owner. It's a bit like the magic potion in A Midsummer Night's Dream, which attaches the object to the next person it comes across…
When I came to do the real import, this all fell apart. The automatically created objects all ended up being owned by the Manager role that created them. In the end, I had to do each one individually through the Plone interface to be sure they got created properly. Very tedious. The same was true of role assignments. It is possible to select any number of users in the Zope interface, and assign a role to all of them at once. The role is displayed against each account, so everything appears correct. Whe viewed through the Plone interface, however, the role assignments do not appear. Again, I was obliged to go through each user individually to assign roles.

Team members page


I wanted to give my students a link where they could see who was in their team (Plone group) in the same format as the members' search results. I had to implement it as a portal tab because I needed to use a template. This was so that I didn't have to recode anything every time someone switched teams.
I ran into a problem because I needed to use portal_groups.getGroupById() which is a restricted function. I found some references to being able to call the template from a script with the Manager proxy role; however, I couldn't find out how to call a template from a script.
I eventually solved the problem by creating the following external method:
def main(self, groupname):
gtool = getattr(self, 'portal_groups')
group = gtool.getGroupById(groupname)
usernames = group.getGroupMembers()
return usernames
This script returns a list of the group members, and this is what I used for the tal:repeat loop in the template.

Problem


This reproduced from sourceforge.net forum:
=> >>When logged in as manager the template can be called without
=> any problem.
=> >>
=> >>However, if logged in as member I get an "insufficient
=> privilege" error.
=> >
=> > This is due to the protection of "getMemberById" (there are
=> > valid reasons to protect it).
=> >
=> > Whenever, you feel that permissions are too strict for your
=> > application, use a Python Script with proxy role (--> Zope Book,
=> > 2.6 edition, online on Zope.org).
=>
=>
=> This case with getting Full name, email and web address is coming up so
=> often that there ought to be a better solution.
=>
=> We should be able to set the state on individual member attributes, so
=> that we could allways get the member object, but only get at those
=> attributes that are visible to us.

I agree, I am continually frustrated by the extremely simplistic nature of member management in CMF.

It is absurd that you have to have manager role over the memberdata tool to get access to member information. This leads to the situation that you must be a manager of the entire portal to see member data. It also means that you cant delegate the management of users to non managers. Also you cant group members and then delegate management of groups to different users.

These are all tasks that I need in portals over and over again. The GRUF does create groups but there is no way to delegate management over these groups.

CMFMember is a step in the right direction, making members objects should then allow us to specify permissions over those objects, but its not really sorted out yet.

I ran into this problem when creating the customised member_search_results form. I spent ages getting it working (as a manager), then found that it didn't work with any other user and eventually tracked the problem down to this known issue. Resolved by adding the following function to Products/CMFPlone/MembershipTool.py as per http://sourceforge.net/mailarchive/forum.php?forum_id=12349&style=flat&viewday=8&viewmonth=200304 : def getFullName(self,member_id=None): member=self.portal_memberdata.getMemberById(member_id) if member: fullname = getattr(member, "fullname", member_id) if fullname and fullname > " ": return fullname return member_id
You have to be careful to get the indentation just right or the function is not picked up by the compiler properly.

TechSpecs


Zope Version (unreleased version, python 2.3.3, win32)
2.7.0 from version.txt
Python Version 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)]
System Platform win32
SOFTWARE_HOME C:\Program Files\Plone 2\Zope\lib\python
ZOPE_HOME C:\Program Files\Plone 2\Zope
INSTANCE_HOME C:\Program Files\Plone 2\Data
CLIENT_HOME C:\Program Files\Plone 2\Data\var
Network Services ZServer.HTTPServer.zhttp_server (Port: 80)ZServer.HTTPServer.zhttp_server (Port: 8080)

Product Version at Install time Product version
CMFCalendar CMF-1.4.7
GroupUserFolder 2.0.1 2.0.1
CMFActionIcons 0.9
CMFFormController 1.0.4 1.0.4
Epoz 0.8.5 0.8.5
PortalTransforms 1.3.2-7 1.3.2-7
Archetypes 1.3.1-final 1.3.1-final
SimpleBlog 1.2.1 1.2.1
IDSkin 1.0 1.0
PloneErrorReporting 0.11 0.11
MimetypesRegistry 1.3.2-7 1.3.2-7
CMFMember 1.0 beta5 1.0 beta5
IDProfile 1.0 1.0

Install steps


1. Install Zope/Plone
2. Fix CMFPlone/MembershipTool.py
3. Fix CMFCore/CatalogTool.py
4. Copy additional/updated products into the Products directory, and install using QuickInstaller
a. These first:
i. Generator
ii. MimeTypesRegistry
iii. PortalTransforms
iv. Validation
v. PloneErrorReporting
vi. VerboseSecurity
vii. DocFinderTab
b. Then these:
i. CMFMember
ii. Archetypes (installs automatically with CMFMember
c. Then these:
i. SimpleBlog
ii. IDProfile
iii. IDSkin
iv. CMFUserTrackTool
v. CMFMessage
5. Replace database file
6. Install external method findGroupMembers.py

To do



  • Fix layout so that the profile only takes up the main page slot

  • Don't know why the profile_view form extends over to the right and displaces the right_slot portlets. Temporarily fixed this by disabling the right_slots under the Members folder.
  • Remove some of the naughty formatting code to a css, and work out how to position the 'View Blog' link correctly

  • Find out why folders are not returned by a search on titleDisable border when viewing static pages

Saturday, January 08, 2005

Moulding Plone

Well, Plone is turning out to be very easy to use. I am keeping notes as I go along, and I'll post them here when they are at a reasonably complete stage. In the space of a couple of days I have managed to get far more customisation done that with any of the J2EE portals I have tried so far. There is even a blog add-in available that installs as smoothly as eels through seagrass. I think I will have to create a blogroll portlet from scratch, but having had a go at a bit of customisation, I am not daunted. The documentation available is also very useful. A lot of the tweaks I have made so far have been done following the instructions on the Plone site.

Obviously, Plone being built using Python and not Java, it is not JSR168-compliant, but I think for demonstration purposes, it will do just fine. It's a relief to get to this stage - I can now concentrate on the customisation rather than the evaluation.

Wednesday, January 05, 2005

eXo build notes

Here are my notes from my experiments with eXo. They contain some solutions to problems that came up, especially the unsatisfied dependencies. The last couple of sections were issues with the way the system appeared to work. I posted the file manager questions on the eXo support forum - no reply yet...
----------------------------

Build

All directories are created under /opt
Add the following lines to /etc/profile:

#### Start of Java/portal entries ####

pathmunge /opt/SUNWappserver/jdk/bin/ after
JAVA_HOME=/opt/SUNWappserver/jdk/
J2EE_CLASSPATH=

MAVEN_HOME=/opt/maven-1.0.2
pathmunge /opt/maven-1.0.2/bin

export MAVEN_HOME JAVA_HOME J2EE_CLASSPATH

#### End of Java/portal entries ####


Download maven from http://maven.apache.org/start/download.html
Install maven – instructions at http://maven.apache.org/start/install.html
Update /etc/profile entry if version number is different
Refresh profile (. /etc/profile)
Initialise maven by running with no arguments

Download latest exo SVN project ( SVN = Subversion source repository tool) from http://forge.objectweb.org/plugins/scmsvn/index.php?group_id=151
Create directory /opt/projects
Untar SVN hierarchy under here
Follow build instructions at http://www.exoplatform.com
Download exo src tree from http://www.exoplatform.org/
Update build.properties file to include this line:
maven.repo.remote=http://www.ibiblio.org/maven/,
file:/home/Brian/exoplatform/lib,
file:${base.directory}/exoplatform/lib
Change path of src distribution if necessary

PROBLEM:
Maven multiproject:install takes a long time to run (30 mins on a slow PC)
Build fails with unsatisfied dependencies:
cp ../lib/jbpm/jars/jbpm-2.0-beta2.jar /opt/maven/repo/repository/jbpm/jars/
change version of httpunit.jar to 1.5.4 in these files:
exoplatform/test/webunit-suites/project.xml
exoplatform/test/webunit-framework/project.xml
Download httpunit from http://sourceforge.net/project/showfiles.php?group_id=6550
Copy httpunit.jar to /opt/maven/repo/repository/httpunit/jars/

Download common-fileupload from http://jakarta.apache.org/site/binindex.cgi#commons-fileupload
cp commons-fileupload-1.0/commons-fileupload-1.0.jar /opt/maven/repo/repository/commons-fileupload/jars/

Download aspectjtools-1.2.jar from http://www.ibiblio.org/maven/aspectj/jars/
(maybe not required if maven.repo.remote set correctly?

cp /home/Brian/exoplatform/lib/jaxrpc/jars/jaxrpc-1.0.jar /opt/maven/repo/repository/jaxrpc/jars/
cp /home/Brian/exoplatform/lib/saaj/jars/saaj-1.1.jar /opt/maven/repo/repository/saaj/jars/

PROBLEM:
Maven failed to download the following files, and the build failed because of related dependencies:
jsf-api-1.1.jar
jsf-impl-1.1.jar
jstl.jar
jstl_el.jar
jta-spec-1.0.1.jar
hsqldb.jar

Resolved by copying versions of these files from the exo-tomcat binary distribution into the following destination directories:
jsf-api-1.1.jar ==> /opt/maven/repo/repository/jsf/jars/
jsf-impl-1.1.jar ==> /opt/maven/repo/repository/jsf/jars/
jstl.jar ==> /opt/maven/repo/repository/jstl/jars/
jstl_el.jar ==> /opt/maven/repo/repository/jstl/jars/
jta-spec-1.0.1.jar ==> /opt/maven/repo/repository/misc/jars/
hsqldb.jar ==> /opt/maven/repo/repository/hsqldb/jars/

PROBLEM:
Maven failed to download the following files, and the build failed because of related dependencies:
exoplatform.commons-1.0.jar
exoplatform.jsf-components-1.0.jar
exoplatform.container-1.0.jar
exoplatform.services.common.api-1.0.jar
exoplatform.services.database.api-1.0.jar
exoplatform.services.resources.api-1.0.jar
exoplatform.services.portlet-container.api-1.0.jar
exoplatform.services.portlet-registry.api-1.0.jar
exoplatform.services.portal.api-1.0.jar
exoplatform.services.organization.api-1.0.jar
exoplatform.services.id-generator.api-1.0.jar
exoplatform.services.security.api-1.0.jar
exoplatform.test.framework-1.0.jar
exoplatform.test.webunit-framework-1.0.jar
exoplatform.services.id-generator.impl-1.0.jar
exoplatform.services.common.impl-1.0.jar
exoplatform.services.database.impl-1.0.jar
exoplatform.services.resources.impl-1.0.jar
exoplatform.services.portal.impl-1.0.jar
exoplatform.services.backup.api-1.0.jar
exoplatform.services.organization.impl-1.0.jar
exoplatform.services.backup.impl-1.0.jar
exoplatform.services.portlet-container.impl-1.0.jar
exoplatform.services.portlet-registry.impl-1.0.jar

Resolved by copying binaries from the exo-tomcat distribution into maven repository


File explorer

Problems:
1. Create new folder
2. Set default start folder
3. No tooltips or verification on action icons


1. Create new folder
Clicking the link does not seem to work. The screen refreshes, but that’s all.
I can create a folder in the file system under the content directory, but it only appears in the portlet display if I go into edit mode and back out, or if I log out and back in again.

2. Set default start folder
I want to allow portal users to create documents in a sub-folder but not to see the top-level ones (eg META-INF, WEB-INF, skin, etc). The options in the edit dialog appear to offer this possibility, but if I change the base-dir value, I get the following error:
The portlet has a fatal error. Click here to restart the portletClick

Can this be configured differently for different communities?

3. No tooltips or verification on action icons
The meaning of the icons is not obvious, and there is no verification step when deleting a file. It would be perfectly possible for a user who is experimenting to remove a file by accident.

Workflow

Creating the xml and java representations for realistic business process could be very time consuming. It doesn’t look too difficult, but there is a lot to go wrong. Added to this, I would need to work out a way of tapping into the group assignments of individual users in order to make the task assignments work properly. In the sample process definitions, there are a couple of dummy string entries which only work for the two hard-coded usernames (see below). For a class of 120+ where the roles are changing on a regular basis, a hard-coded solution would be infeasible.
public class BossAssignementHandler implements AssignmentHandler{

public String selectActor(AssignmentContext assignmentContext) {
System.out.println("In selectActor of BossAssignementHandler : ");
System.out.println(" --> Previous actor : " + assignmentContext.getPreviousActorId());
if("benj".equals(assignmentContext.getPreviousActorId())
"bossOfBenj".equals(assignmentContext.getPreviousActorId())){
System.out.println(" --> Next actor : bossOfBenj");
return "bossOfBenj";
}
return assignmentContext.getPreviousActorId();
}
}

This also means that I have not been able to test whether the task assignment portlet refreshes automatically or not – probably not judging by the others.


Demo portal

I am teaching a module about J2EE portals, and I am looking for an appropriate platform to use. My institution uses WebCT which is hopeless - not a portal, not even a nice web environment, although we are promised an upgrade - added to which, I would like to teach the material using the tools themselves. So far, I have had a go with uPortal, Liferay and eXo, and I have only just thought about putting the experience in the blog.

Thoughts so far?

uPortal
Seems quite simple to administer; somewhat restrictive in terms of layout options, though. I haven't spent much time with this one, but I didn't like the way that porlets take over the whole display space when active. Maybe this can be configured...

Liferay
Again relatively simple to install, but restrictive in terms of layout - I assume you can get down into the depths, but I don't have that kind of time. Seemed to come with a lot of portlets, including the ones I was particularly interested in using. However, some of the important ones didn't work (chat, instant message, meeting room). Refresh rate was a bit slow - default 15 mins - but again, I guess that could be changed...

eXo
This was as easy to install as the others in the first instance when I just got the binary distribution. However, I spent a long time trying to work out how to change the content of the default pages, and was about to give up in despair when I came across a little forum message saying that there was a bug in the current distribution. Thanks for making that obvious, guys! The soution required the building of the jars from scratch which proved to be a lot more difficult. This process first required the installation of Apache maven. This in itself proved difficult because of unsatisfied dependencies. The same sort of thing happened when trying to use maven to build eXo. I ended up scavenging the missing jars from the eXo src distribution (yet another download).
I persevered with eXo because its interface was the most attractive and flexible (in theory). However, a number of problem came up that made me look elsewhere. These and the dependency problems are documented in the next post.

The documentation for all of these systems is sketchy. The only way to really tell what functioanlity is included is to download it an try it out, and that takes a great deal of time. Also, there seems to be a dearth of information about JSR168-compliant portlets that are available to download. There is a project called GEMS at java.net which intends to build up a portlet collection, but there's not much there yet. Perhaps the developers at uPortal, Liferay and eXo could start posting their portlets there...?

I am currently looking at Zope/Plone which is not strictly speaking a J2EE portal, but may well be the easiest option for use in the module. More on this to follow...