Skip to Content
I was recently looking for information about how to get information about portal repositories activity. This information should be easy to understand because potential users won’t have very strong technical skills.

The solution to get an easy report about document usage was expose by Detlev Beutner in SDN forums and it’s based on developing a repository service which counts documents hits.

These are the steps to get this functionality:

  • Creating a custom property which registers documents hits in those repositories you want to control.
  • Developing a repository service which reponds when a document is read and increment the new property.
  • Activating the new service in repositories.

Step 1: Creating a custom property: hitscount

Creating a new property is easy in Enterprise Portal.
Go to
System Administration/System configuration/Knowledge Management/Configuration/Content Management/Global Services/Property Metadata/Properties
and create a new property with the following attributes:

Description = Hit Counter
Unique ID = hitscount
Property ID = hitscount
Namespace alias = default
Type = Integer
Group = default
Mandatory = deactivated
Multi-Valued = deactivated
Read Only = activated
Maintainable = activated
Indexable = activated
Default Value = 0
Allowed Values (csv) = empty
Key for Label = hitscount
Meta Data Extension = Not set
Folder Validity Patterns (csv) = empty
Document Validity Patterns (csv) = repository list
Resource Types (csv) = empty
Mime Types (csv) = empty
Default Sorting = Ascending
Label icon = empty
Hidden = deactivated
Dependencies = deactivated
Additional Metadata (csv) = empty
Property Renderer = integer
Virtual = deactivated
Composed of = none selected
Comparator Class = empty

Now, every documents in the repository list will have this new property (upload a new document and look in its details page, inside Miscellaneous tab!).

Step 2: Developing a repository service

Once we have created this new property we need a repository service which control it increasing his value in each document access.

To develop it we have used SAP Netweaver Developer Studio 2.0.12 with Repository Framework 7.1.5.
Substeps are:

  • Create a new Portal Application Project
  • Create a new Repository Service using whe wizard

Now, you must have three classes in your project structure: IRFServiceWrapper, RFServiceWrapper and one class with the name you gave in creation, in our case: SampleService.

  • Fill theKEY attribute inside IRFServiceWrapper. Tipically with a string like “com.mycompany.SampleService”.

Copy and paste the following code into SampleService class. You can take a quick look at this code to know what is it doing. We are subscribing to GET_TEMPLATE event.

package com.mycompany;

import java.util.Collection;
import java.util.Iterator;

import com.sapportals.wcm.WcmException;
import com.sapportals.wcm.crt.component.IReconfigurable;
import com.sapportals.wcm.crt.component.StartupException;
import com.sapportals.wcm.crt.configuration.ConfigurationException;
import com.sapportals.wcm.crt.configuration.IConfiguration;
import com.sapportals.wcm.repository.IProperty;
import com.sapportals.wcm.repository.IResource;
import com.sapportals.wcm.repository.Property;
import com.sapportals.wcm.repository.PropertyName;
import com.sapportals.wcm.repository.ResourceException;
import com.sapportals.wcm.repository.manager.IRepositoryManager;
import com.sapportals.wcm.repository.manager.IResourceEvent;
import com.sapportals.wcm.repository.manager.IResourceEventReceiver;
import com.sapportals.wcm.repository.manager.ResourceEvent;
import com.sapportals.wcm.repository.service.AbstractRepositoryService;
import com.sapportals.wcm.repository.service.ServiceNotAvailableException;
import com.sapportals.wcm.util.events.IEvent;

public class SampleService extends AbstractRepositoryService implements IResourceEventReceiver, IReconfigurable {

private static final String TYPE = "com.mycompany.kmservice.SampleService";
private Collection repositoryManagers;

public SampleService() {
  super();
}

public String getServiceType() {
  return SampleService.TYPE;
}

protected void startUpImpl(Collection repositoryManagers) throws ConfigurationException, StartupException {

  this.repositoryManagers = repositoryManagers;
  Iterator it = repositoryManagers.iterator();
  while (it.hasNext()){
    try {
      addRepositoryAssignment((IRepositoryManager) it.next());
    } catch (ServiceNotAvailableException e) {
      e.printStackTrace();
    }
  }
}

protected void shutDownImpl() {
  Iterator it = repositoryManagers.iterator();
  while (it.hasNext()){
    try {
      removeRepositoryAssignment((IRepositoryManager) it.next());
    } catch (WcmException e) {
      e.printStackTrace();
    }
  }
}

protected void addRepositoryAssignment(IRepositoryManager mgr) throws ServiceNotAvailableException {
  try {
    mgr.getEventBroker().register(this, ResourceEvent.GET_TEMPLATE);
  } catch (WcmException e) {
    e.printStackTrace();
  }
}

protected void removeRepositoryAssignment(IRepositoryManager mgr) throws WcmException {
  mgr.getEventBroker().unregister(this, ResourceEvent.GET_TEMPLATE);
}

public void received(IEvent event) {
  IResourceEvent myEvent = (IResourceEvent) event;
  try {

    IResource res = myEvent.getResource();
    
    PropertyName propertyNameHitCount = new PropertyName("http://sapportals.com/xmlns/cm","hitscount");
    Property propHitCount = new Property(propertyNameHitCount,new Integer(0));

    // We increase hitscount property value
    if (res.getProperty(propertyNameHitCount)!=null) {
      IProperty oldHitCount = res.getProperty(propertyNameHitCount);
      String sOldHitCount = oldHitCount.getValueAsString();
      int iOldHitCount = Integer.parseInt(sOldHitCount);
      iOldHitCount++;
      propHitCount = new Property(propertyNameHitCount,new Integer(iOldHitCount));
      res.setProperty(propHitCount);
    }

  } catch (ResourceException e) {
    e.printStackTrace();
  }
}

public void reconfigure(IConfiguration arg0) throws ConfigurationException {
}
}

Step 3: Activating the new service

The new service must be activated in those repositories that you want to control.

To do this you can go to
System Administration/System configuration/Knowledge Management/Configuration/Content Management/Repository Managers/CM Repository
and check the repositories to control.

Is important to restart servlet engine.

In Summary

This is a easy solution to know how many users have read one document in knowledge management.

To report this post you need to login first.

14 Comments

You must be Logged on to comment or reply to a post.

  1. Detlev Beutner
    Hi,
    nice to see the results of forum discussions again as weblogs, thank that you gave the source for the ideas (others are not that fair at their weblog games…). Some remarks:
    With these settings, it might be that documents under a versioned folder could get new versions when the property is updated via the RepService (did you check that?). For an alternative see /thread/51095 [original link is broken] – with a programmatically created application property and if it’s needed to display the counter within the PropStructure, you can create a dummy property (to provide the value a metadataextension might be useful, too).
    Some remarks about the settings: Why did you activate “Maintainable”? “Indexable” might be senseful, as given, if one searches for documents read at least x times. The “Key for Label” does not make sense if no resource bundle is provided. The “repository list” as value for the document validity must be of the form “/YOUR_REPOSITORY/**” (or more rep’s comma seperated) if it should work for the whole structure under the repositories root. The “Property Renderer” can be emtpy, in standard cases (as it is the case here) the renderer is determined dynamically (and “integer” will be chosen).
    At TechEd, an example for such an implementation was given by Thilo Brandt, including a KM report to get an overview over documents and their hits. This is an additional idea how to analyse these results.
    Best regards, Detlev
    (0) 
    1. Damian Reyes Diaz Post author
      Thanks for your remarks,

      First of all, this weblog is about a simple solution to control repository activity.

      In fact, it needs modifications to work under a versioned folder. I was testing this solution under a folder containing xmlform documents using NewsExplorer/NewsBrowser layouts and I didn’t get the behaviour I expected.

      About settings: I was testing this solution in NW04SP12 and NW04SP09. I used differents configuration because in NW04SP12 I used “Maintainable” deactivated and it works fine but when I was testing the same solution in NW04SP09 I had to use “Maintainable” activated (the property wasn’t visible). I couldn’t check exactly why.

      About “Key for Label” you are right, I was using a resource bundle but it’s not a must.

      About “Repository list” I was using “/documents/**”. Each one should use his own repository list.

      About “Repository Renderer” yout are right again. Thanks for your comments.

      I hope in future weblogs someone can improve this solution.

      Best regards, Damian

      (0) 
  2. Reinhard Dürr
    Hello,

    and first of all thanks a lot for this nice weblog. After a long and hard fight with my IDE (the KM-Plugins provided with EP6.02 are not working with patch 35) I got the service to work.

    One question remains open: All the reporting does only work for new documents, as the old ones don’t have the hitscount property. Is it possible to fill the property of the existing documents somehow?

    Thanks in advance,

    Reinhard

    (0) 
    1. shi zi
      That’s right,I have the same problem.It does not work for the documents that already exist in my folder, and also the number of hitcount can not increase if the user don’t have “write” permission for the document.

      How can I solve the two problems above.
      Best Regard!

      (0) 
      1. Detlev Beutner
        Hi Reinhard, hi Shi Zi,
        On the one hand, of course you can add properties to existing documents, at least via setProperties. On the other hand, please read my old remark below, that the property approach is dangerous concerning versions. As with application properties the resource itself isn’t touched, I don’t expect the permissions problem with that approach, either. With the property approach, you still could use a different IResourceContext with some system principal (like the ICE-Service-User) – but this leads to the changedBy property set to that user (same problem as with the versions – you really modify the resource!).
        Hope it helps to get on the right track,
        Detlev
        (0) 
  3. chinnadurai R
    Hi,

       Thanks for this weblog.  I have followed the steps what you have listed above.  I have deployed the service and i have assigned this service to repository(ie. documents).  After restarting the server KM goes down(Showing the error like item not found when i try to open KM content).  Please help in this regard.

    Regards,
    Chinnadurai.R

    (0) 
  4. Piyush Bhurangi
    i have done almost as you have said in the blog. Upto the activation part, it has been perfect but from there i am not able to view the folders or tell me how to link the folders under that service , am not sure how this service will work for the folders , pls guide…
    (0) 
  5. Christian Hoffmann
    Hi,

    this hitcounter works fine but only with uploaded files, html-files or text-files.

    What about links?
    Is it possible to count the hits on links?
    Someone know any solution to do that?

    Thanks in advance for your help.

    (0) 
  6. Julien Mallet
    Hello,

    Thank you for the weblog!
    I had a little problem that I solved, I post it here, maybe it can help someone else.

    I had set the default value to 0.
    I could see the property in Details >> Misc.., but the hitscount field was empty and not updated when I opened the document.

    I fixed this problem, adding this ‘else block’ under the ‘if block’ in the method ‘received’ in order to fill the hitscount field :

    else
    {
         propHitCount = new Property propertyNameHitCount,new Integer(1));
         res.setProperty(propHitCount);
    }

    Now that the field is initialized, the value is correctly updated when I open a km document.

    Thanks again for the blog!

    Best regards,
    Julien Mallet.

    (0) 
  7. Deepak Jaju
    Hi

    I followed the procedure described in the blog and was able to increment the count.

    The problem is that – After I click on the file for the first time, the count gets incremented (as expected);however it keeps on incrementing by 3 or 4 each second even without clicking it second time.

    Please help me to solve this.

    Thanks
    Deepak

    (0) 
  8. Victor Capi
    Hi expert,

    I create this property in my portal, but… when the trex is active, this property growth too, is it possible avoid it?

    Thanks in advance,
    Regards,

    (0) 
  9. Victor Capi
    Hi experts,

    I copy this code, but i have a problem; if i only have permission for read, the counter don´t work… How can avoid it?

    Thanks in advance,
    Regards,

    (0) 

Leave a Reply