Return-Path: Delivered-To: apmail-incubator-sling-commits-archive@locus.apache.org Received: (qmail 27266 invoked from network); 3 Sep 2008 07:57:56 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 3 Sep 2008 07:57:56 -0000 Received: (qmail 35530 invoked by uid 500); 3 Sep 2008 07:57:54 -0000 Delivered-To: apmail-incubator-sling-commits-archive@incubator.apache.org Received: (qmail 35499 invoked by uid 500); 3 Sep 2008 07:57:54 -0000 Mailing-List: contact sling-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sling-dev@incubator.apache.org Delivered-To: mailing list sling-commits@incubator.apache.org Received: (qmail 35489 invoked by uid 99); 3 Sep 2008 07:57:54 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Sep 2008 00:57:54 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Sep 2008 07:57:04 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 3B171238889D; Wed, 3 Sep 2008 00:57:05 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r691532 - in /incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event: TimedEventStatusProvider.java impl/TimedJobHandler.java Date: Wed, 03 Sep 2008 07:57:04 -0000 To: sling-commits@incubator.apache.org From: cziegeler@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080903075705.3B171238889D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: cziegeler Date: Wed Sep 3 00:57:04 2008 New Revision: 691532 URL: http://svn.apache.org/viewvc?rev=691532&view=rev Log: SLING-640 : Add status provider for timed events. Added: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java (with props) Modified: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java Added: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java?rev=691532&view=auto ============================================================================== --- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java (added) +++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java Wed Sep 3 00:57:04 2008 @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.event; + +import java.util.Collection; +import java.util.Map; + +import org.osgi.service.event.Event; + +/** + * This service provides the current timed events status. + */ +public interface TimedEventStatusProvider { + + /** + * Return a list of currently schedulded events. + * @param topic Topic can be used as a filter, if it is non-null, only jobs with this topic will be returned. + * @param filterProps A list of filter property maps. Each map acts like a template. The searched event + * must match the template (AND query). By providing several maps, different filters + * are possible (OR query). + * @return A non null collection. + */ + Collection getScheduledEvents(String topic, Map... filterProps); + + /** + * Return the scheduled event with the given id. + * @return The scheduled event or null. + */ + Event getScheduledEvent(String topic, String eventId); +} Propchange: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java ------------------------------------------------------------------------------ svn:keywords = author date id revision rev url Propchange: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/TimedEventStatusProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java?rev=691532&r1=691531&r2=691532&view=diff ============================================================================== --- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java (original) +++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java Wed Sep 3 00:57:04 2008 @@ -19,12 +19,16 @@ package org.apache.sling.event.impl; import java.io.Serializable; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.Date; import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; @@ -33,6 +37,7 @@ import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.Value; import javax.jcr.lock.Lock; import javax.jcr.lock.LockException; import javax.jcr.observation.EventIterator; @@ -44,6 +49,7 @@ import org.apache.sling.commons.scheduler.JobContext; import org.apache.sling.commons.scheduler.Scheduler; import org.apache.sling.event.EventUtil; +import org.apache.sling.event.TimedEventStatusProvider; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; @@ -52,6 +58,7 @@ * An event handler for timed events. * * @scr.component metatype="no" + * @scr.interface interface="TimedEventStatusProvider" * @scr.property name="event.topics" refValues="EventUtil.TOPIC_TIMED_EVENT" * values.updated="org/osgi/framework/BundleEvent/UPDATED" * values.started="org/osgi/framework/BundleEvent/STARTED" @@ -59,7 +66,7 @@ */ public class TimedJobHandler extends AbstractRepositoryEventHandler - implements Job { + implements Job, TimedEventStatusProvider { protected static final String JOB_TOPIC = "topic"; @@ -126,8 +133,8 @@ /** * Create a unique node name for this timed job. */ - protected String getNodeName(final ScheduleInfo info) { - return Text.escapeIllegalJcrChars(info.jobId); + private String getNodeName(final String jobId) { + return Text.escapeIllegalJcrChars(jobId); } /** @@ -187,7 +194,7 @@ try { // get parent node final Node parentNode = (Node)this.writerSession.getItem(this.repositoryPath); - final String nodeName = this.getNodeName(scheduleInfo); + final String nodeName = this.getNodeName(scheduleInfo.jobId); // is there already a node? final Node foundNode = parentNode.hasNode(nodeName) ? parentNode.getNode(nodeName) : null; Lock lock = null; @@ -459,7 +466,7 @@ try { s = this.createSession(); final Node parentNode = (Node)s.getItem(this.repositoryPath); - final String nodeName = this.getNodeName(info); + final String nodeName = this.getNodeName(info.jobId); final Node eventNode = parentNode.hasNode(nodeName) ? parentNode.getNode(nodeName) : null; if ( eventNode != null ) { try { @@ -592,7 +599,7 @@ String id = (String)event.getProperty(EventUtil.PROPERTY_TIMED_EVENT_ID); String jId = (String)event.getProperty(EventUtil.PROPERTY_JOB_ID); - this.jobId = "TimedEvent: " + topic + ':' + (id != null ? id : "") + ':' + (jId != null ? jId : ""); + this.jobId = getJobId(topic, id, jId); } private ScheduleInfo(String jobId) { @@ -609,5 +616,122 @@ public boolean isStopEvent() { return this.expression == null && this.period == null && this.date == null; } + + public static String getJobId(String topic, String timedEventId, String jobId) { + return "TimedEvent: " + topic + ':' + (timedEventId != null ? timedEventId : "") + ':' + (jobId != null ? jobId : ""); + } + } + + /** + * @see org.apache.sling.event.TimedEventStatusProvider#getScheduledEvent(java.lang.String, java.lang.String) + */ + public Event getScheduledEvent(String topic, String eventId) { + Session s = null; + try { + s = this.createSession(); + final Node parentNode = (Node)s.getItem(this.repositoryPath); + final String nodeName = this.getNodeName(ScheduleInfo.getJobId(topic, eventId, null)); + final Node eventNode = parentNode.hasNode(nodeName) ? parentNode.getNode(nodeName) : null; + if ( eventNode != null ) { + return this.readEvent(eventNode); + } + } catch (RepositoryException re) { + this.logger.error("Unable to create a session.", re); + } catch (ClassNotFoundException e) { + this.ignoreException(e); + } finally { + if ( s != null ) { + s.logout(); + } + } + return null; + } + + /** + * @see org.apache.sling.event.TimedEventStatusProvider#getScheduledEvents(java.lang.String, java.util.Map...) + */ + public Collection getScheduledEvents(String topic, Map... filterProps) { + // we create a new session + Session s = null; + final List jobs = new ArrayList(); + try { + s = this.createSession(); + final QueryManager qManager = s.getWorkspace().getQueryManager(); + final StringBuffer buffer = new StringBuffer("/jcr:root"); + buffer.append(this.repositoryPath); + if ( topic != null ) { + buffer.append('/'); + buffer.append(topic.replace('/', '.')); + } + buffer.append("//element(*, "); + buffer.append(this.getEventNodeType()); + buffer.append(") ["); + if ( topic != null ) { + buffer.append('@'); + buffer.append(EventHelper.NODE_PROPERTY_TOPIC); + buffer.append("='"); + buffer.append("'"); + } + if ( filterProps != null && filterProps.length > 0 ) { + buffer.append(" and ("); + int index = 0; + for (Map template : filterProps) { + if ( index > 0 ) { + buffer.append(" or "); + } + buffer.append('('); + final Iterator> i = template.entrySet().iterator(); + boolean first = true; + while ( i.hasNext() ) { + final Map.Entry current = i.next(); + // check prop name first + final String propName = EventUtil.getNodePropertyName(current.getKey()); + if ( propName != null ) { + // check value + final Value value = EventUtil.getNodePropertyValue(s.getValueFactory(), current.getValue()); + if ( value != null ) { + if ( first ) { + first = false; + buffer.append('@'); + } else { + buffer.append(" and @"); + } + buffer.append(propName); + buffer.append(" = '"); + buffer.append(current.getValue()); + buffer.append("'"); + } + } + } + buffer.append(')'); + index++; + } + buffer.append(')'); + } + buffer.append("]"); + final String queryString = buffer.toString(); + logger.debug("Executing job query {}.", queryString); + + final Query q = qManager.createQuery(queryString, Query.XPATH); + final NodeIterator iter = q.execute().getNodes(); + while ( iter.hasNext() ) { + final Node eventNode = iter.nextNode(); + try { + final Event event = this.readEvent(eventNode); + jobs.add(event); + } catch (ClassNotFoundException cnfe) { + // in the case of a class not found exception we just ignore the exception + this.ignoreException(cnfe); + } + } + } catch (RepositoryException e) { + // in the case of an error, we return an empty list + this.ignoreException(e); + } finally { + if ( s != null) { + s.logout(); + } + } + return jobs; } }