Has properties webscript

I did some other java based webscript. From portlet flash application I need to get information about some user's permissions on object specified by nodeRef. So firstly I tried to do this via JavaScript based webservice, but there are no tools to do this.

I did some other java based webscript. From portlet flash application I need to get information about some user's permissions on object specified by nodeRef. So firstly I tried to do this via JavaScript based webservice, but there are no tools to do this.

 First thing is to create description xml for this service:

 <webscript>
  <shortname>hasRights</shortname>
  <description>Returns some amazing info ;-)</description>
  <url>/archivace/hasrights?u={userName}&amp;s={nodeRef}&amp;p={permissionName}</url>
  <format default="xml"/>
  <authentication>user</authentication>
  <transaction>required</transaction>
</webscript>

As you can see, there are three parameters: u, which specifies userName of user, of which we want to get this information. Parameter  s, which specifies nodeRef of node and finally p, which is optional and specifies one of permissions. If not set, WriteContent permission is used.

Space permissions:

  • ReadProperties
  • ReadChildren
  • WriteProperties
  • DeleteNode
  • DeleteChildren
  • CreateCildren

Content permissions:

  • ReadContent
  • WriteContent
  • ReadProperties
  • WriteProperties
  • DeleteNode
  • ExecuteContent
  • SetOwner

You can find a complete list of all permisions in tomcat/webapps/alfresco/WEB-inf/classes/alfresco/model/permissionDefinitions.xml.

 Now let's write some javacode: I created a class HasRights, which extends AbstractWebScript. Let's have a look into that code

 public class HasRights extends AbstractWebScript{
    private AuthenticationComponent authenticationComponent;
    private PermissionService permissionService;

    public void execute(WebScriptRequest req, WebScriptResponse res)throws IOException {
        try{
            HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
            String spaceRef = "workspace://SpacesStore/" +
              (String)httpReq.getParameter("s");
            String userName = (String)httpReq.getParameter("u");
            String permission = (String)httpReq.getParameter("p");
            if(permission==null)
                permission = "WriteContent";

In case of this webScript is called method execute is the first to run (not exactly, setters of this class are called sooner – setAuthenticationComponent() and setPermissionService()) . In this method javax.servlet.http.HttpServletRequest is used for get parameters.

            NodeRef nodeRef = new NodeRef(spaceRef);
            Node noda = new Node(nodeRef);
            this.authenticationComponent.setCurrentUser(userName);

In those steps Node and nodeRef objects are created and currently logged user is setted to wanted user.

res.setContentType("text/xml");
res.getWriter().write("<hasRightsResponse>");
res.getWriter().write("<nodeName>"+noda.getName()+"</nodeName>");
res.getWriter().write("<nodeRef>"+nodeRef.toString()+"</nodeRef>");
res.getWriter().write("<userName>"+this.authenticationComponent.getCurrentUserName()+"</userName>");
res.getWriter().write("<permissionName>"+permission+"</permissionName>");
res.getWriter().write("<hasPermission>"+this.permissionService.hasPermission(nodeRef, permission)+"</hasPermission>");
res.getWriter().write("</hasRightsResponse>");

After all that a response is printed out. Example of output is following:

<hasRightsResponse>
    <nodeName>sezeni001.xml</nodeName>
    <nodeRef>workspace://SpacesStore/da5ad5b0-3bc4-4d4c-88fe-4f9cf4f349f5</nodeRef>
    <userName>pepik1</userName>
    <permissionName>WriteContent</permissionName>
    <hasPermission>DENIED</hasPermission>
</hasRightsResponse>

I forgot to mention the most importatn step – to define a bean with this webscript. So it looks like this (in web-scripts-application-context.xml):

 <bean id="webscript.org.alfresco.archivace.hasrights.get" class="cz.shmoula.webscripts.HasRights" parent="webscript">
      <property name="authenticationComponent" ref="AuthenticationComponent"/>
      <property name="permissionService" ref="PermissionService"/>
  </bean>

And that's it, pretty simple ;-).

Custom „modify content properties dialog“

There is this dialog present in Alfresco (edit-content-properties.jsp), but I wanted to write my own and also describe things I discovered during playing with browseBean.

There is this dialog present in Alfresco (edit-content-properties.jsp), but I wanted to write my own and also describe things I discovered during playing with browseBean.

Let's start with simple bean extending BaseDialogBean with just one getter (and also implementation of abstract methods, ie. getFinishButtonDisabled() or finishImpl()), which returns a Node (org.alfresco.web.bean.repository.Node).

public class ModifyContentProperties extends BaseDialogBean {

    public Node getNode(){
        return this.browseBean.getDocument();

   }
}

Our bean requies just one property – browseBean, so let's set it in faces config:

 <managed-bean>
       <managed-bean-name>ModifyContentProperties</managed-bean-name>
       <managed-bean-class>cz.shmoula.ModifyContentProperties</managed-bean-class>
       <managed-bean-scope>request</managed-bean-scope>
       <managed-property>
           <property-name>browseBean</property-name>
           <value>#{BrowseBean}</value>
       </managed-property>
   </managed-bean>

For successfully access to getDocument() method an action listener in web client config is needed. Without this listener (and parameter) the methodreturns null, which is really not expecting value :-). So you need to add that listener and parametr into action definition:

<action id="modify_content_properties">
    <label>Editovat vlastnosti</label>
    <image>/images/icons/edit_form.gif</image>
    <action>dialog:modifyContentProperties</action>
    <action-listener>#{BrowseBean.setupContentAction}</action-listener>
    <params>
        <param name="id">#{actionContext.id}</param>
    </params>
</action>

 A JSP page is very simple, just one component from repo.tld library – propertySheetGrid. More information about this componentcan be found in the alfresco devel wiki. I'm using a (default) externalConfig for describing which property to view or not. Information about config service should be found also in developer wiki, so check it out.

 <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<r:propertySheetGrid id="content-details-contents" value="#{ModifyContentProperties.node}"  externalConfig="true" />

This simple configuration opens a dialog with properties editing inputs, which are filled by information of opened document (or node, if you apply this config – add action – to a Node). BUT you can't save changes. We don't have an OK button method handled. How to get this stuff working? Very simple, Gavinc already wrote this code in org.alfresco.web.bean.content.EditContentPropertiesDialog, so all we need to do is to change a class, which our ModifyContentProperties extending and add overriding methods for default Cancel and OK buttons calls.

 import org.alfresco.web.bean.content.EditContentPropertiesDialog;

public class ModifyContentProperties extends EditContentPropertiesDialog {
    
    @Override
    protected String getDefaultCancelOutcome(){
      return super.getDefaultCancelOutcome() +
                 AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
                 "browse";
    }

    @Override
    protected String getDefaultFinishOutcome(){
       return super.getDefaultFinishOutcome() +
                 AlfrescoNavigationHandler.OUTCOME_SEPARATOR +
                 "browse";
    }

.  .  .

EditContentPropertiesDialog has an editableNode property, which is just a copy of original node, i which we can write our changes. So we need to assign this editableNode to our propertySheetGrid component.

<r:propertySheetGrid id="content-details-contents" value="#{ModifyContentProperties.editableNode}" externalConfig="true"/>

That is all, fast and simple … and now at one place, so you must not spent so much time to looking for how this works as me 🙂

Alfresco Quick upload

In Alfresco there is no simple way to modify uploading code. You can't just copy and customize org.alfresco.web.bean.content.AddConteneDialog class and /jsp/content/add-content-dialog.jsp ie you can use add-content-dialog.jsp and modify it, but when you try to use AddContentDialog class updated in your project, it doesn't work. I found somewhere on forums (sry, i can't find a link) that add-content-dialog.jsp is just a page snippet and when you coding your own dialog, you must write code for whole page and there is problem with r:upload component. So i'll try to describe my simple solution for QuickUpload content to Alfresco through a Servlet.

In Alfresco there is no simple way to modify uploading code. You can't just copy and customize org.alfresco.web.bean.content.AddConteneDialog class and /jsp/content/add-content-dialog.jsp ie you can use add-content-dialog.jsp and modify it, but when you try to use AddContentDialog class updated in your project, it doesn't work. I found somewhere on forums (sry, i can't find a link) that add-content-dialog.jsp is just a page snippet and when you coding your own dialog, you must write code for whole page and there is problem with r:upload component. So i'll try to describe my simple solution for QuickUpload content to Alfresco through a Servlet.

My servlet – UploadAnalysisFileServlet – extends javax.servlet.http.HttpServlet, i'm using both methods – GET and POST too. (If you don't know how servlets work, just look at this tutorial) I'm using asynchronous requests and iframe, which work "behind scene" and after success user can handle some more action. Actions are following:

  1. View page with select file input and upload button in a form 
  2. After file select and upload button press is AJAX Request fired and file and information are transfered between servlet and client
  3. If file is successfully loaded, iframe views a succesfully-uploaded-image.gif and ok button is enabled
  4. QuickUpload bean control is triggered – aspects and properties are added to new content
  5. File is succesfully uploaded and properties setted up, so back to space view

Simplified "action diagram":
 
 
Now let's look inside code snipets; firstly item one, View page with select file input and upload button in a form

<iframe id="dialog:dialog-body:upload_target" src="progress_anim.gif" style="visibility:hidden"></iframe>
<div id='dialog:dialog-body:fileDiv'>
      <h:inputHidden id="alfFileId" value="#{QuickUpload.fileId}" />
      <input type="file" id='dialog:dialog-body:alfFileInput' name="alfFileInput"/>
      <input type="button" value="upload" onclick="sendAjaxRequest();" id='dialog:dialog-body:uploadButton'/>
</div>

 This is just an hidden iframe with content of animation of progress icon and a simple form with upload input type and button, which triggers following JavaScript routine. Ajax calling is based on Prototype JavaScript Framework.
 function sendAjaxRequest(){
    var form = document.getElementById('dialog');
    document.getElementById('dialog:dialog-body:fileDiv').style.visibility = "hidden";

    form.action = '/alfresco/uploadAnalysisFileServlet';
    form.enctype= 'multipart/form-data';
    form.target = 'dialog:dialog-body:upload_target';

    var ifr = document.getElementById('dialog:dialog-body:upload_target');
    ifr.style.visibility = "visible";
    var doc = null;  
    if(ifr.contentDocument)  
      doc = ifr.contentDocument;  // note: this is varying for different browsers!

    var pars = "uploadid=" + document.getElementById("dialog:dialog-body:alfFileId").value;
    var myAjax = new Ajax.Request("/alfresco/uploadAnalysisFileServlet",
         { method: 'get', parameters: pars, onComplete: checkExists });

    form.submit();
    
    form.action = '/alfresco/faces/jsp/dialog/container.jsp';
    form.enctype= 'application/x-www-form-urlencoded';
    form.target = '';
}

First action is getting a form of dialog, then default action of this form is redirected to my servlet. After that is an ID sent through get method to servlet and a file is sent too, viapost metod, thanks to form.submit(). After this sending is dialog form redirected back to original value and onComplete method is called (it just reads a responseText and check, if it is true or false), which enables OK button.
 
How are post and get methods handled in servlet? A org.alfresco.web.bean.FileUploadBean class is used:
 
 public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{
       this.fileUploadBean = new FileUploadBean();
       this.uploadId = request.getParameter("uploadid");
       PrintWriter out = response.getWriter();
       out.println("uploadId = "+this.uploadId);
   }
A doGet method just creates a new FileUploadBean and sets and returns ID of file (I'm using this just for debugging and experimenting purposes, it can all be placed just in a Post method). Now let's handle post method data:
 
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{
       HttpSession session = request.getSession();
       ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
      
       List<FileItem> fileItems = upload.parseRequest(request);
       for (FileItem item : fileItems){
           if(item.getFieldName().equalsIgnoreCase("alfFileInput")){
               String filename = item.getName();
               filename = FilenameUtils.getName(filename);
               final File tempFile = TempFileProvider.createTempFile("alfresco", ".upload");
               item.write(tempFile);
               this.fileUploadBean.setFile(tempFile);
               this.fileUploadBean.setFileName(filename);
               this.fileUploadBean.setFilePath(tempFile.getAbsolutePath());
           }
       }
      
       session.setAttribute(FileUploadBean.getKey(uploadId), this.fileUploadBean);
       response.setContentType("text/html");
       PrintWriter out = response.getWriter();
       out.println("<img src="/alfresco/images/icons/deploy_successful.gif"/>");
   }
This snippet is hardly simplified, but idea is still readable: it reads all file items and if one of them is our file input (alfFileInput), temporary file is created and fileUploadBean properties are set. Then is set an attribute in a session – whole fileUploadBean and a response is sent back to JavaScript client – view of succesfull_upload inside iframe.
 
At this phase a user can do "OK", so QuickUpload's finishImpl method is triggered. It handles a uploaded file following simple way:
FacesContext ctx = FacesContext.getCurrentInstance();
FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap().
                                get(FileUploadBean.FILE_UPLOAD_BEAN_NAME.concat("-"+this.getFileId()));
       
if(fileBean != null){
    this.file = fileBean.getFile();
    this.fileName = fileBean.getFileName();
 
    NodeRef spaceRef = this.navigator.getCurrentNode().getNodeRef();
    FileInfo fileInfo = this.getFileFolderService().create(spaceRef, fileBean.getFileName(), ContentModel.TYPE_CONTENT);
    NodeRef fileNodeRef = fileInfo.getNodeRef();
               
    Map<QName, Serializable> fileDesc = new HashMap<QName, Serializable>(3, 1.0f);
    fileDesc.put(ContentModel.PROP_TITLE, this.fileName);
 
    ContentWriter writer = this.contentService.getWriter(fileNodeRef, ContentModel.PROP_CONTENT, true);
    writer.putContent(this.file);
}
Firstly a FileUploadBean is extracted back from SessionMap, then a content inside currentNode is created with specified parameters (it is also possible to add some aspects and properties there). After all that just "return outcome;" and hooray, we have simple working QuickUpload routine for Alfresco ;-).

iCal export implementation for Alfresco

For my vcf planning calendar, which is partially described in my Bachelor's thesis, I made function, which does export to iCal calendar format. I used Jav-backed WebScript at Alfresco side and iCal4j library for implementation of RFC 2445 standard – iCalendar.

For my vcf planning calendar, which is partially described in my Bachelor's thesis, I made function, which does export to iCal calendar format. I used Jav-backed WebScript at Alfresco side and iCal4j library for implementation of RFC 2445 standard – iCalendar.

The aim was to create service with parameter of node with planned sessions (ArchivaceSummary aspect) which exports iCal file with all sessions (ArchivaceSession aspect) in it. Simple data model scheme of aspects is at following picture. Those aspects are just flags of type of nodes, only ArchivaceSession aspect associates some properties – a date of begin and end of action. More informations are in my Bachelor's thesis.

Image Hosted by ImageShack.us

Due to use iCal4j library I needed to use Java-backed web script, because i can't see a simple way to create iCal file just with Freemarker, which is used as a rendering machine in "normal" web scripts. Java-backed web scripts are clearly described at Alfresco wiki pages, but when you try to write your own you discover that there is no library in SDK. This problem is reported as a bug, but there is still no solution. It's needed to download library (and source) alfresco-web-framework and include it to project, then it's all ok and it's possible to build Java-backed web scripts.

So, every webscript needs a description file, i put this one into WEB-INF/classes/alfresco/templates/webscripts/org/alfresco/archivace/ical.get.desc.xml

<webscript>
    <shortname>iCal Export</shortname>
    <description>Export kalendare z Archivacniho prostoru</description>
    <url>/archivace/ical?nodeRef={noderef}</url>
    <authentication>user</authentication>
    <transaction>required</transaction>
</webscript>

You can see from its name (ical.get.desc.xml) that this webscript implements get http method. You also need to specify that fact in bean identificator – as a postix, as you can see on next listing of part of web-scripts-application-context.xml.

 <bean id="webscript.org.alfresco.archivace.ical.get"
    class="cz.shmoula.webscripts.ICal"
    parent="webscript">
  </bean>

This postfix is picked up by the Web Script engine, also 'webscript.' prefix is picked up. Webscript prefix identifies that bean you are specifying is a webscript implementation.  Notice that url parameter in desc.xml and suffix of bean identificator  are corresponding: alfresco.archivace.ical.get   —  /archivace/ical.Second parameter, class, specifies class with implementation. My class implementation is based on AbstractWebScript class, which provides simplier development of WebScripts. Main method of this class is method public void execute(WebScriptRequest req, WebScriptResponse res), which is described on next listing.

public void execute(WebScriptRequest req, WebScriptResponse res)
            throws IOException {
        // getting request data
        HttpServletRequest httpReq = req.getHttpServletRequest();
        // opening specified node
        Node noda = new Node(NodeRef(httpReq.getParameter("noderef")));
        // creating new calendar object
        net.fortuna.ical4j.model.Calendar calendar = new net.fortuna.ical4j.model.Calendar();

        // cycling through node and reading data
        for (Iterator i = noda.getChildAssociations().values().iterator(); i
                .hasNext();) {
            . . .
            if (n.hasAspect(ArchivaceModel.archSession)) {
                // if type of child is what I want, just create data from provided info and add to calendar
                this.addEvent(n.getProperties());
            }
            . . .
        }
        // setting response and printing out a calendar
        res.setContentType("text/calendar");
        res.getWriter().write(this.calendar.toString());
    }

Pressty simple, huh? And the last task – calling this webscript. Either by specifying an url with required parameter (node reference), or in code. I'm using an ActionLink from Alfresco Tag Library called this way:

 <a:actionLink value="iCal export"
    image="/images/icons/calendar-16.gif"
    href="/service/archivace/ical?noderef=#{NavigationBean.currentNode.nodeRefAsString}"
/>

And that is it. I have a calendar export button on my page as you can see on following image.

Image and video hosting by TinyPic

 

Hacking Alfresco, III

In last article I wrote about defining custom actions in Alfresco, in this one i want to continue with simple custom dialog triggered by this action.

In last article I wrote about defining custom actions in Alfresco, in this one i want to continue with simple custom dialog triggered by this action.

So, like actions, dialogs are defined in web-client-config-custom.xml too. Definition is simple:

<dialogs>
<dialog name="createSession" page="/jsp/extension/create-session.jsp" managed-bean="CreateSessionDialog"
icon="/images/icons/add_content_large.gif" title="Create session"
description="Create a new user session" />
</dialogs>

Name is name of the dialog, referenced by action tag (<action>dialog:createSession</action>) in action definition. Page is a .jsp page with some content and managed-bean is an managed bean 🙂 defined in faces-config-beans.xml. So, lets add some bean to the session scope:

<managed-bean>
<managed-bean-name>CreateSessionDialog</managed-bean-name>
<managed-bean-class>cz.shmoula.CreateSessionDialog</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>retezec</property-name>
<value>bomdigibom :-)</value>
</managed-property>
</managed-bean>

Now we need to create cz.shmoula.CreateSessionDialog class, which extends the BaseDialogBean:

public class CreateSessionDialog extends BaseDialogBean{
protected String aspect;
protected String retezec;

@Override
protected String finishImpl(FacesContext context, String outcome) throws Exception{
return outcome;
}

@Override
public boolean getFinishButtonDisabled(){
return false;
}

public void setRetezec(String retezec){
this.retezec = retezec;
}

public String getRetezec(){
return this.retezec;
}
}

This bean implements two buttons (see Dialog Framework wiki): OK button action and visibility (ie isDisabled) of OK button, in this case it is not disabled, so it is possible to click it and ends this dialog without any intervention to system ;-).

The Retezec variable is set by bean definition to some funny string, so after creating a .jsp page and packing together all this stuff do following: In case of click on space_browse_menu it compares name of that space and if it equals with "Archivace" string, it displays "Create session" action link. After click on this link a custom dialog is opened, as you can see on image below.

Free Image Hosting at www.ImageShack.us

displayed simple dialog

 

.jsp page is very simple too, it doesn't need no headers due to viewing inside of Alfresco UI:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<h:outputText value="#{CreateSessionDialog.retezec} " />

Hacking Alfresco, II

My second try was to create some custom action in some menu or bar and to view a simple dialog in Alfresco UI triggered by this action. There are topics covering this theme in Alfresco wiki too (see Custom Action UI and Dialog Framework) for detailed informations. But i wanted to create a simple and working example to see if it really works :-).

My second try was to create some custom action in some menu or bar and to view a simple dialog in Alfresco UI triggered by this action. There are topics covering this theme in Alfresco wiki too (see Custom Action UI and Dialog Framework) for detailed informations. But i wanted to create a simple and working example to see if it really works :-).

So, lets start with some action ;-). Actions are defined in web-client-config-custom.xml configuration file like this:

<actions>
<action id="create_session">
<label>Create session</label>
<image>/images/icons/add.gif</image>
<action>dialog:createSession</action>
<evaluator>cz.shmoula.CreateSessionEvaluator</evaluator>
</action>

<action-group id="space_browse_menu">
<action idref="create_session" />
</action-group>

</actions>

Items are self explaining, i hope :-). Action is to create dialog, which is defined in dialogs section with name createSession and evaluator is class which implements ActionEvaluator and indicates that this action is viewed or not. In my CreateSessionEvaluator i have just a simple condition.

Id attribute of action-group tag specifies a place in which is this action (a link) viewed, in my example it is space_browse_menu, which is the context menu of space object. Action groups are defined in web-client-config-actions.xml. Examples of some action groups are at following pictures:

Free Image Hosting at www.ImageShack.us

space_browse_menu action group

 

Free Image Hosting at www.ImageShack.us

1 – add_content_menu, 2 – browse_actions_menu

An action link is viewed at first image – "Create session". If evaluator is specified, action is viewed just in case of true evaluation. My simple evaluator is following:

public class CreateSessionEvaluator implements ActionEvaluator{

public boolean evaluate(Node node){
if(node.getName().equals("Archivace"))
return true;
else
return false;
}
}

It just compares space name (in case of space_browse_menu action group) with some string, nothing more :-). So, if they correspond, "Create session" link is displayed.

Hacking Alfresco

There are many wiki pages at Alfresco dev sites, but no working simple excercises at all. At these days i'm playing with this CMS/DMS, so i'll try to collect some remarks about actions i'm doing, maybe it'll be helpful for someone. So, i'm experimenting with Content Metadata Extracters with intention to create some kind of Video Extracter (to save bitrate, resolution, codec… to metadata with that object).

There are many wiki pages at Alfresco dev sites, but no working simple excercises at all. At these days i'm playing with this CMS/DMS, so i'll try to collect some remarks about actions i'm doing, maybe it'll be helpful for someone. So, i'm experimenting with Content Metadata Extracters with intention to create some kind of Video Extracter (to save bitrate, resolution, codec… to metadata with that object).

There is a simple wiki page describing that problem, so if you want to know some background, you have to start there. If you dont (or if you prefer very simple way), let's continue. So, what Content Metadata Extracters (CME) are? Imagine following simple situation: you have repository with some multimedia document, let's say mp3 files. Every mp3 file has a header with some informations (id3), for example artist, album, music style, etc. And you want to your document system to create all needed metadata automaticaly, when user uploads his mp3 file. This is work of CME. In my following example I'm not going to extract data from anywhere to keep things simple, but there is also a source of MP3 Metadata Extracter and many more, all inside of the Alfresco SDK.

I'm going to try to "how this stuff works part by part", so i'm going to create an "empty extractor" which just creates some metadata. So, first thing to do is to add my own bean to content-services-context.xml. In Wiki there is a way through editing a custom-metadata-extrators-context.xml controller, but this way doesn't work for me, so i added my definition right into content-services-context.xml:

<bean id="extracter.ASD" class="cz.shmoula.ASDMetadataExtracter" parent="baseMetadataExtracter" />

So, id is identificator of created bean and class is my class in my package extending AbstractMappingMetadataExtracter. I chose name of ASDMetadataExtracter due to retaining of name convention of *MetadataExtrater and ASD due to my personaly liked phrase "asdfghj…" :-). And parent will automaticaly register this bean with metadataExtracterRegistry to handle mimetypes declared in my "Extractor".

Then i have to create some properties file with defined namespace prefixes and mappings on them. Alfresco for content model uses a namespace http://www.alfresco.org/model/content/1.0 and for lucidity there is a prefix cm binded with that. So my own ASDMetadataExtracter.properties file looks like this:

namespace.prefix.cm=http://www.alfresco.org/model/content/1.0

namespace.prefix.shm=http://www.shmoula.cz/model/content/asd

description=cm:description

pokus=shm:pokus

And last thing to do is to create a class, which fills in those metadata. I uploaded whole code to pastebin, so you can browse it online, its really simple, it has just 45 lines of code!!! But some snipets:

private static final String KEY_POKUS = "pokus"; // definitions of metadata names, binded with properties

… MimetypeMap.MIMETYPE_TEXT_PLAIN … // i'm using this "transformer" for text/plain mime

putRawValue(KEY_POKUS, Long.toString(size), rawProperties); // assigning of value to metadata

// TempFileProvider routines are provided just for testing purposes 😉

// Files uploaded (opened) with these routines are temporary saved in <tomcat>tempAlfresco*

So, that's all, folks :-). And what does it do? After upload of document of type text/plain it fills metadata binded. Now i'm going to solve how to view them, modify them and make a sorts based on them.

Image Hosted by ImageShack.us

Content type needs to correspond with predefined values in Extractor

 

Image Hosted by ImageShack.us

In column "popis" there is value defined through "putRawValue(KEY_DESCRIPTION,…"