This is an old version of the Sling website, see the site conversion page for more info.
Apache
Apache Sling Website > Apache Sling > Documentation > Tutorials & How-Tos > Managing events

Apache Sling provides some mechanisms and support for managing events. This page describes ...

Sling makes a distinction between 2 types of events:

The event mechanism is leveraging the OSGi Event Admin Specification (OSGi Compendium 113).
The OSGi API is very simple and leightweight - sending an event is just generating the event object and calling the event admin. Receiving the event is implementing a single interface and declaring through properties which topics one is interested in. For more details please refer to the following javadocs:

You can learn more in the Eventing, Jobs and Scheduling section (http://sling.apache.org/site/eventing-and-jobs.html).

To get started with the Sling eventing API, you will implement here a service that listens to files posted to /tmp/dropbox and moves them to the appropriate locations depending on the mime-type:

To do that, you will implement 2 services. The first one, called OsgiDropBoxService:

Listening to OSGI Events

To listen to the specific osgi event resource added:

To get a list of possible events available in Sling (resource added, removed or changed), refer to the org.apache.sling.api.SlingConstants class in the Javadocs.

Sending a Job Event

To send a job event:

The first part of the code looks as follows:

/**
 * The <code>OsgiDropBoxService</code> is listening content added to /tmp/dropbox by using OSGI events
 * 
 * @scr.component  immediate="true"
 * @scr.service interface="org.osgi.service.event.EventHandler"
 * @scr.property name="event.topics" valueRef="org.apache.sling.api.SlingConstants.TOPIC_RESOURCE_ADDED"
 */
public class OsgiDropBoxService implements JobProcessor, EventHandler {

The Event Admin service is needed to send the job event:

	/** 
	 * The OSGI event admin used for sending events 
	 * @scr.reference
	 */
	private EventAdmin eventAdmin;

The job topic for dropbox job events needs to be defined:

    /** The job topic for dropbox job events. */
    public static final String JOB_TOPIC = "com/sling/eventing/dropbox/job";

The org.osgi.service.event.EventHandler#handleEvent(Event event) method needs to be implemented:

	public void handleEvent(Event event) {
	    if (EventUtil.isLocal(event)) {
	        EventUtil.processJob(event, this);
	    }
	}

The org.apache.sling.event.JobProcessor#process(Event event) method needs to be implemented.

The logic is as follows:

	public boolean process(Event event) {
		String propPath = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
		String propResType = (String) event.getProperty(SlingConstants.PROPERTY_RESOURCE_TYPE);
		// an event is sent if a file is added to /tmp/dropbox
		if (propPath.startsWith("/tmp/dropbox") && propResType.equals("nt:file")) {
    		final Dictionary<String, Object> props = new Hashtable<String, Object>();
            props.put(EventUtil.PROPERTY_JOB_TOPIC, JOB_TOPIC);
    		props.put("resourcePath", propPath);
    		Event dropboxJobEvent = new Event(EventUtil.TOPIC_JOB, props);
    		eventAdmin.sendEvent(dropboxJobEvent);
    		log.info("the dropbox job has been sent: {}", propPath);
		}
		return true;
	}

The whole service looks now as follows:
...

Now that you have a service that sends job events whenever a file is uploaded to /tmp/dropbox, you will create the service DropBoxEventHandler that listens to those job events and moves the files to a location corresponding to their mime-types.

Listening to Job Events

To listen to the job events that have been defined before:

To move the files:

The first part of the code looks as follows:

/**
 * @scr.component  immediate="true"
 * @scr.service interface="org.osgi.service.event.EventHandler"
 * @scr.property name="event.topics" valueRef="com.jck.sling.eventing.osgi.OsgiDropBoxService.JOB_TOPIC"
 */

public class DropBoxEventHandler implements JobProcessor, EventHandler {

Several class fields are defined:

   /** Default log. */
    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    private Session adminSession;
    
    /** @scr.reference */
    private SlingRepository repository;
    
    /**
     * @scr.reference
     */
    private JcrResourceResolverFactory resolverFactory;
    
    private final static String IMAGES_PATH = "/dropbox/images/";
    private final static String MUSIC_PATH = "/dropbox/music/";
    private final static String MOVIES_PATH = "/dropbox/movies/";
    private final static String OTHER_PATH = "/dropbox/other/";

Handling Job Events

The org.osgi.service.event.EventHandler#handleEvent(Event event) method needs to be implemented:

	public void handleEvent(Event event) {
	    if (EventUtil.isLocal(event)) {
	        EventUtil.processJob(event, this);
	    }
	}

The org.apache.sling.event.JobProcessor#process(Event event) method needs to be implemented.
The logic is as follows:

	public boolean process(Event event) {
		try {
			String resourcePath = (String) event.getProperty("resourcePath");
			String resourceName = resourcePath.substring(resourcePath.lastIndexOf("/") + 1);
        	adminSession = repository.loginAdministrative(null);
	        ResourceResolver resourceResolver = resolverFactory.getResourceResolver(adminSession);
	        Resource res = resourceResolver.getResource(resourcePath);
	        if (ResourceUtil.isA(res, "nt:file")) {
	        	String mimeType = res.getResourceMetadata().getContentType();
	        	String destDir;
	        	if (mimeType.equals("image/png")) {
	        		destDir = IMAGES_PATH;
	        	}
	        	else if (mimeType.equals("audio/mpeg")) {
	        		destDir = MUSIC_PATH;
	        	}
	        	else if (mimeType.equals("video/x-msvideo")) {
	        		destDir = MOVIES_PATH;
	        	}
	        	else {
	        		destDir = OTHER_PATH;
	        	}
        		adminSession.move(resourcePath, destDir + resourceName);
	        	adminSession.save();
	        	log.info("The file {} has been moved to {}", resourceName, destDir);
	        }
	        return true;
		} catch (RepositoryException e) {
			log.error("RepositoryException: " + e);
			return false;
        } finally {
            if (adminSession != null && adminSession.isLive()) {
            	adminSession.logout();
            	adminSession = null;
            }
        }
	}

The complete code for the service looks as follows:
...

Last modified by jck on Mon Aug 16 08:58:35 EDT 2010