View Javadoc

1   /* This file is part of COPAL (COntext Provisioning for All).
2    *
3    * COPAL is a part of SM4All (Smart hoMes for All) project.
4    *
5    * COPAL is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * COPAL is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with COPAL. If not, see <http://www.gnu.org/licenses/>.
17   */
18  package at.ac.tuwien.infosys.sm4all.copal.esper.internal;
19  
20  import java.util.concurrent.locks.ReadWriteLock;
21  import java.util.concurrent.locks.ReentrantReadWriteLock;
22  import org.apache.log4j.Level;
23  import org.apache.log4j.Logger;
24  import org.w3c.dom.Document;
25  import at.ac.tuwien.infosys.sm4all.copal.api.event.ContextEvent;
26  import at.ac.tuwien.infosys.sm4all.copal.api.event.ContextEventType;
27  import at.ac.tuwien.infosys.sm4all.copal.api.event.MalformedDocumentException;
28  import at.ac.tuwien.infosys.sm4all.copal.api.event.XMLContextEvent;
29  import at.ac.tuwien.infosys.sm4all.copal.api.event.XMLContextEventType;
30  import at.ac.tuwien.infosys.sm4all.copal.api.osgi.GenericActivator;
31  import at.ac.tuwien.infosys.sm4all.copal.api.service.ContextEventTypeRegistry;
32  import at.ac.tuwien.infosys.sm4all.copal.api.service.DeadLetterChannel;
33  import com.espertech.esper.client.EPRuntime;
34  import com.espertech.esper.client.EPServiceProvider;
35  import com.espertech.esper.client.EventBean;
36  import com.espertech.esper.client.UnmatchedListener;
37  
38  /**
39   * Esper's UnmatchedListener which helps transform Esper's events to
40   * {@link ContextEvent}s understood by {@link DeadLetterChannel}.
41   * 
42   * @author sanjin
43   */
44  public class DeadLetterListener extends GenericActivator implements
45          UnmatchedListener {
46  
47      private static final Logger LOGGER = Logger.getLogger(DeadLetterListener.class);
48  
49      private final ReadWriteLock lock = new ReentrantReadWriteLock();
50      private final EPRuntime runtime;
51      private ContextEventTypeRegistry registry;
52      private DeadLetterChannel channel;
53  
54      /**
55       * Creates an instance of the {@link UnmatchedListener} for the
56       * {@link DeadLetterChannel} with specified {@link EPServiceProvider}.
57       * 
58       * @param serviceProvider the {@link EPServiceProvider}.
59       */
60      public DeadLetterListener(final EPServiceProvider serviceProvider) {
61          super(ContextEventTypeRegistry.class.getName(),
62                  DeadLetterChannel.class.getName());
63  
64          this.runtime = serviceProvider.getEPRuntime();
65      }
66  
67      @Override
68      protected void start() {
69          this.lock.writeLock().lock();
70          try {
71              this.registry = getDependency(ContextEventTypeRegistry.class.getName());
72              this.channel = getDependency(DeadLetterChannel.class.getName());
73  
74              this.runtime.setUnmatchedListener(this);
75          } finally {
76              this.lock.writeLock().unlock();
77          }
78      }
79  
80      @Override
81      protected void stop() {
82          this.lock.writeLock().lock();
83          try {
84              this.runtime.setUnmatchedListener(null);
85  
86              this.registry = null;
87              this.channel = null;
88          } finally {
89              this.lock.writeLock().unlock();
90          }
91      }
92  
93      @Override
94      public void update(final EventBean eventBean) {
95          final Object event = eventBean.get("*");
96  
97          this.lock.readLock().lock();
98          try {
99              if (event instanceof Document) {
100                 final Document document = (Document) event;
101                 final ContextEventType eventType = this.registry.get(XMLContextEvent.getProperty(
102                         document, XMLContextEvent.TYPE));
103                 if (eventType instanceof XMLContextEventType) {
104                     this.channel.onEvent(new XMLContextEvent(
105                             (XMLContextEventType) eventType, document));
106                 } else {
107                     if (LOGGER.isEnabledFor(Level.WARN)) {
108                         LOGGER.warn("Recieved non-XML event! Dropping it.");
109                     }
110                 }
111             } else {
112                 if (LOGGER.isEnabledFor(Level.WARN)) {
113                     LOGGER.warn("Recieved non-XML event! Dropping it.");
114                 }
115             }
116         } catch (final MalformedDocumentException ex) {
117             if (LOGGER.isEnabledFor(Level.ERROR)) {
118                 LOGGER.error("Received XML event is malformed! Dropping it.",
119                         ex);
120             }
121         } finally {
122             this.lock.readLock().unlock();
123         }
124     }
125 }