Archive for the ‘IT & Programming’ Category

How to create an Alfresco Module Package (AMP)

Tuesday, April 14th, 2009

In this post I will set up the basic settings to create an Alfresco Module Package (AMP). Ant needs to be installed to make this work. This creates a skeleton AMP module that does nothing except being a module. So the first step is to create a new project in your favorite IDE.

In the Alfresco SDK there are some great examples, and one of them is named SDK Basic AMP. AMP’s have a specific directory structure that it’s wise to use. When deploying AMP’s the Module Management Tool (mmt) maps the files to specific locations in the alfresco tree. This can be a bit confusing when dealing with configuration files and if the SDK samples have solved a problem in a specific way, it’s wise to just follow that road.

1. Create a module.properties file containing these lines:
# Skeleton AMP Module
module.id=skeleton
module.title=Skeleton
module.description=Add a skeleton amp to Alfresco
module.version=1.0

This file contain module information and is to be located in the root of the amp. Usually the file is located in the IDE at config/alfresco/module/modulename/module.properties. (IDE) config/alfresco maps to alfresco_dir/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/.

2. Create a config/alfresco/module/skeleton/module.context file:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
</beans>

This is where one puts bean initializations, bootstrap resource bundles, adds webclient configuration files etc. when needed.

3. Place class files (if you have any) in source/java/my/namespace/*.java

4. Sample build.xml for ant:
<?xml version="1.0"?>

<project name="Skeleton" default="deploy-war" basedir=".">
<!-- Project directories, REPLACE WITH YOUR SETTINGS -->
<property name="project.dir" value="."/>
<property name="build.dir" value="${project.dir}/build"/>
<property name="jar.file" value="${build.dir}/lib/skeleton.jar" />
<property name="amp.file" value="${build.dir}/dist/skeleton.amp"/>
<property name="tomcat.dir" value="/opt/Alfresco/tomcat" />
<property name="war.file" value="${tomcat.dir}/webapps/alfresco.war"/>
<property name="lib.dir" value="/opt/alfresco-sdk2.9/lib/server" />

<!-- Path to essential libraries -->
<path id="class.path">
<dirset dir="${build.dir}" />
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>

<!-- Creates a build directory where the amp and jar files will be located -->
<target name="mkdirs">
<mkdir dir="${build.dir}/dist" />
<mkdir dir="${build.dir}/lib" />
</target>

<target name="package-jar" depends="compile">
<delete file="${jar.file}" />

<jar destfile="${jar.file}">
<fileset dir="${build.dir}" includes="**/faces-config.xml, **/*.class" />
</jar>
</target>

<target name="package-amp" depends="mkdirs, package-jar" description="Packages the amp">
<zip destfile="${amp.file}">
<fileset dir="${project.dir}/build" includes="lib/*.jar" />
<fileset dir="${project.dir}" includes="module.properties" />
<fileset dir="${project.dir}" includes="config/**/*.*" />
</zip>
</target>

<!-- Use when checking what deployment of an AMP will do without actually committing the deployment -->
<target name="preview-install">
<echo>Preview installation of AMP</echo>
<java dir="." fork="true" classname="org.alfresco.repo.module.tool.ModuleManagementTool">
<classpath refid="class.path" />
<arg line="install ${amp.file} ${war.file} -preview -force -verbose"/>
</java>
</target>

<!-- Deploys the war to Alfresco -->
<target name="deploy-war" depends="package-amp">
<java dir="." fork="true" classname="org.alfresco.repo.module.tool.ModuleManagementTool">
<classpath refid="class.path" />
<arg line="install ${amp.file} ${war.file} -force -verbose"/>
</java>
</target>

</project>

An AMP file is a zipped archive, so if you would like to know the content of the amp then:
unzip skeleton.amp

To view the content of a jar file:
jar -tvf skeleton.jar

SDK Basic AMP example – This is the basic AMP taken from the SDK.

Resources:
Alfresco Module Packages
Alfresco SDK
http://wiki.alfresco.com/wiki/Module_Management_Tool

How to remove DRM from ITunes music and videos

Sunday, April 12th, 2009

Requiem is an application that works on all platforms and it removes the DRM on (purchased) videos and music in ITunes. The application can be downloaded from this torrent. This is of course something Apple is not happy about, so therefore each version of ITunes works on a specific Requiem version. Thankfully the developer of Requiem updates the application to match changes made by Apple.

Now, the torrent link will soon be outdated as new versions of ITunes and Requiem is released, so therefore I also supply the search that will find the latest release of Requiem. Enjoy!

Alfresco: The first lessons learned

Wednesday, April 8th, 2009

The last couple of weeks I have learned some lessons the hard way.

1. When doing changes to faces-config(-custom).xml, put it in a jar-file.
This is stated in Developing an Alfresco Module, but it’s very easy to forget because so many places one can read about extending Alfresco using faces-config-custom.xml.

There are two options for making changes to faces-config:
- Add a faces-config-custom.xml in the AMP.
In an IDE it would typically ble places in web/WEB-INF/faces-config-custom.xml. When deploying the amp to Alfresco, it doesn’t overwrite the WEB-INF/faces-config-custom.xml on the server as one would expect, it’s as if the changes were never made. In reality Alfresco does some magic, and the changes are available in alfresco, but not in any extensions you have made. So if you try to create a managed bean and access it from within alfresco jsp-files, life is good. But in most cases, extending Alfresco is the best way to go and then the managed bean is suddenly not available. Therefore the next choice is the best way.

- Add faces-config.xml to the jar-file.
Yes, no need for a faces-config-custom.xml here, and the declarations are available all over alfresco, including any third-party extensions. Inside the jar the file is located at META-INF/faces-config.xml.

Alfresco is simply a bit touchy when dealing with faces-config files.

2. Use (unique) IDs on faces components no matter what
I came up in the situation that I had one jsp that only contained two lines:
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<r:webScript scriptUrl="/service/mwsearch" />

With just two lines to maintain, one would think it would be difficult to make mistakes… Wrong! It doesn’t matter that even the taglib documentation state that id isn’t required, because it’s simply not true. ID’s are required unless you want erratic behaviour – IllegalStateExceptions (like seen below) that occurs at random, but will definitly stop the show:

javax.faces.FacesException: java.lang.IllegalStateException: Client-id : _idJsp13 is duplicated in the faces tree. Component : browse:_idJsp13, path: {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId: /jsp/browse/browse.jsp][Class: javax.faces.component.html.HtmlForm,Id: browse][Class: org.alfresco.web.ui.common.component.UIPanel,Id: spaces-panel][Class: org.alfresco.web.ui.common.component.data.UIRichList,Id: spacesList][Class: org.alfresco.web.ui.common.component.data.UIColumn,Id: col1][Class: org.alfresco.web.ui.common.component.UIActionLink,Id: col1-act1][Class: javax.faces.component.UIParameter,Id: _idJsp13]}

3. Any files in the AMP will override files in the Data Dictionary
I had a webscript where I needed to make an url configurable. Now, configurations can be added in a modulename.get.config.xml as stated in the documentation. I removed the file from my AMP, and added the file in Alfresco DM –> Company Home –> Data Dictionary –> Web Scripts Extentions –> Modulefolder –> modulename.get.config.xml. And voila, my Freemarker templates caught on the config changes after a restart of Alfresco.

Hopefully this will have saved at least one person from hours of frustration.

Developer options for extending Alfresco

Thursday, March 19th, 2009

There are three ways of extending Alfresco:

  1. Put the code in the webapp folder (alfresco/tomcat/webapps/alfresco)
  2. Put the code in the alfresco repository
  3. Create an AMP file and add it to alfresco.war

There are different benefits and drawbacks to each method:

Put the code in the webapp folder
It’s an easy way to quickly test the changes one have made, but the moment the war-file is reloaded by tomcat, the added files and changes are lost.

Put the code in the alfresco repository
When logging into Alfresco Explorer as Admin, one get access to the Data Dictionary space located within Company Home. The data dictionary contains code used by Alfresco users like email and Freemarker templates which notifies users of an invitation to a space, RSS feeds, searches, scripts, web scripts and space templates. The data dictionary space can be used to create our own custom actions on documents, spaces etc.

This option is an easy way for most users to create their own actions and test them out without restarting Alfresco, but can be a bit of a hassle when one need to change the script, upload it and test it out.

Create an AMP (Alfresco Module Package) file and add it to alfresco.war
This is the recommended way for creating modules in Alfresco. Creating a package makes the deployment of modules easy, but when tomcat notices the alfresco war-file has changed then Alfresco is reloaded and all users are kicked out of their session. The bad part is that it usually takes about a minute to reload alfresco on a development machine. One minute for every change… well, it does hurt sometimes.

Another thing that hurts.. when writing this there are no way of uninstalling an amp. The way of uninstalling a module is to revert to the alfresco.war file that was saved as backup before installing the amp. So, if one installs other modules afterwards, then one have to revert to the backup war-file, then install all the other modules again…. Ridiculous! AND – after removing a module from alfresco, one get a nice warning text in the log about Alfresco not being able to find the module. I really hope Alfresco will add uninstall functionality in the near future to its Module Management Tool that installs the amps.

The good/bad part (you decide) is that once the amp is deployed, alfresco has reloaded and installed the module, one can edit the deployed files and alfresco *should* (add some grain of salt here) recognize changes made without any restart/reload. But then suddenly we are back into option number one.

Create new document type in Alfresco

Wednesday, March 18th, 2009

Alfresco have many options to extend their document management system and one of them is to create a new document type as seen in the picture below. The new document is a Whitepaper, but we could have added other document types like a functional specification, meeting minutes, risk matrix and whatever that tingles our needs.

All documents that are uploaded or created in alfresco is by default marked as “content”, a generic term that can encompass everything. To create a document type is an easy way of setting documents apart/a way of categorizing and structuring the content itself. A developer can add certain functionality/behavior to a document type like a doc type having certain metadata connected to it, workflow (review, acceptance, publish), add versioning, that certain people shall be notified of changes or add permission so that only specific people can create and edit the document. One can add advanced search capabilities like searching for a specific document type.

screenshot_003

So, down to the gritty details. First one have to define the document type (custom content model) (config/extension/model/whitepaper.xml):


<?xml version="1.0" encoding="UTF-8"?>

<!-- Definition of new Model -->
<model name="mb:mybusiness.whitepaper.model" xmlns="http://www.alfresco.org/model/dictionary/1.0">
    <description>My business Whitepaper</description>
    <author>Helene Klungvik</author>
    <version>1.0</version>

    <!--
		Imports are required to allow references to definitions in other
		models
	-->
	<imports>
		<!-- Import Alfresco System Definitions -->
		<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys"/>
		<!-- Import Alfresco Dictionary Definitions -->
		<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
		<!-- Import Alfresco Content Domain Model Definitions -->
		<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
	</imports>

	<namespaces>
		<namespace uri="mybusiness.whitepaper.model" prefix="mb" />
	</namespaces>

    <types>
		<type name="mb:doc">
			<title>Whitepaper</title>
			<parent>cm:content</parent>
		</type>
   </types>

</model>

Then create a spring bean that imports the whitepaper model (config/alfresco/extension/module-context.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<!--
    Document   : module-context.xml
    Created on : March 11, 2009, 10:00 AM
    Author     : Helene Klungvik
    Description:
        Define a new document type for whitepapers
-->

<beans>
    <bean id="mybusiness.dictionaryBootstrap"
        parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
        <property name="models">
            <list>
                <value>alfresco/extension/model/rwhitepaper.xml</value>
            </list>
        </property>
    </bean>
</beans>

And that’s it.

How to remove pdf borders in macosx

Saturday, January 17th, 2009

Many pdf’s comes with big white borders. This becomes a problem when reading pdf’s on ebook readers since the borders takes up a lot of space on an already small and challenged reading area. Or when one wants to save some trees when printing the document. Well, there’s a solution for this in macosx.

Open the pdf in Preview.
Open the sidebar: Preview Menu –> View –> Sidebar
Choose Thumbnail view: Preview Sidebar –> On the bottom left there is an icon, click and choose Thumbnails. Ensure that you have one of the pages selected/marked.
Select all the pages: Preview Menu –> Edit –> Select All
Choose the Select Tool: Preview Menu –> Tools –> Select Tool

Now you can mark the area of the page that you want to keep. Since you previously selected all the pages, the changes will occur on all the pages.

To remove the unmarked area: Preview Menu –> Tools –> Crop.

Now you can save the document.

This worked as a charm for me and the pdf’s ended up looking good in my iliad, though the font size is still a bit small (but still readable) in most cases.

ITunes: Convert mp3 to audiobooks

Friday, December 26th, 2008

When importing mp3 to ITunes, the files is automatically added to the music library. All it takes for making the mp3′s into audiobooks is the correct settings. Search up the files in question and mark them. Right click on the marked files –> Get Info –> Options –> Media kind –> Audiobook.

The files will automatically be transfered from the Music Library to Audiobooks when “OK” is pressed.

audiobooks