View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  
16  package org.fourthline.cling.model;
17  
18  import org.fourthline.cling.model.meta.LocalService;
19  import org.fourthline.cling.model.state.StateVariableValue;
20  
21  import java.beans.PropertyChangeSupport;
22  import java.util.Collection;
23  
24  /**
25   * Binds the metadata of a service to a service implementation, unified interface for accessing local services.
26   * <p>
27   * The UPnP core will always access a local service implementation through
28   * this manager, available with {@link org.fourthline.cling.model.meta.LocalService#getManager()}:
29   * </p>
30   * <ul>
31   * <li>
32   * The {@link org.fourthline.cling.model.action.ActionExecutor}s use the manager to process
33   * UPnP control invocations. It's the service manager's job to translate
34   * such an action invocation into an actual method invocation, or any other procedure
35   * that satisfies the requirements. The {@link org.fourthline.cling.model.action.ActionExecutor}
36   * works together with the manager, for example, the
37   * {@link org.fourthline.cling.model.action.MethodActionExecutor} expects that an action
38   * method can be invoked through reflection on the instance returned by the manager's
39   * {@link #getImplementation()} method. This is possible with the
40   * the {@link org.fourthline.cling.model.DefaultServiceManager}. A different service manager
41   * might require a different set of action executors, and vice versa.
42   * </li>
43   * <li>
44   * The {@link org.fourthline.cling.model.state.StateVariableAccessor}s use the manager
45   * to process UPnP state variable queries and GENA eventing. It's the service manager's
46   * job to return an actual value when a state variable has to be read. The
47   * {@link org.fourthline.cling.model.state.StateVariableAccessor} works together with
48   * the service manager, for example, the {@link org.fourthline.cling.model.state.FieldStateVariableAccessor}
49   * expects that a state variable value can be read through reflection on a field, of
50   * the instance returned by {@link #getImplementation()}. This is possible with the
51   * {@link org.fourthline.cling.model.DefaultServiceManager}. A different service manager
52   * might require a different set of state variable accessors, and vice versa.
53   * </li>
54   * <li>
55   * A service manager has to notify the UPnP core, and especially the GENA eventing system,
56   * whenever the state of any evented UPnP state variable changes. For new subscriptions
57   * GENA also has to read the current state of the service manually, when the subscription
58   * has been established and an initial event message has to be send to the subscriber.
59   * </li>
60   * </ul>
61   * <p>
62   * A service manager can implement these concerns in any way imaginable. It has to
63   * be thread-safe.
64   * </p>
65   *
66   * @param <T> The interface expected by the
67   *            bound {@link org.fourthline.cling.model.action.ActionExecutor}s
68   *            and {@link org.fourthline.cling.model.state.StateVariableAccessor}s.
69   *
70   * @author Christian Bauer
71   */
72  public interface ServiceManager<T> {
73  
74      /**
75       * Use this property name when propagating change events that affect any evented UPnP
76       * state variable. This name is detected by the GENA subsystem.
77       */
78      public static final String EVENTED_STATE_VARIABLES = "_EventedStateVariables";
79  
80      /**
81       * @return The metadata of the service to which this manager is assigned.
82       */
83      public LocalService<T> getService();
84  
85      /**
86       * @return An instance with the interface expected by the
87       *         bound {@link org.fourthline.cling.model.action.ActionExecutor}s
88      *          and {@link org.fourthline.cling.model.state.StateVariableAccessor}s.
89       */
90      public T getImplementation();
91  
92      /**
93       * Double-dispatch of arbitrary commands, used by action executors and state variable accessors.
94       * <p>
95       * The service manager will execute the given {@link org.fourthline.cling.model.Command} and it
96       * might decorate the execution, for example, by locking/unlocking access to a shared service
97       * implementation before and after the execution.
98       * </p>
99       * @param cmd The command to execute.
100      * @throws Exception Any exception, without wrapping, as thrown by {@link org.fourthline.cling.model.Command#execute(ServiceManager)}
101      */
102     public void execute(Command<T> cmd) throws Exception;
103 
104     /**
105      * Provides the capability to monitor the service for state changes.
106      * <p>
107      * The GENA subsystem expects that this adapter will notify its listeners whenever
108      * <em>any</em> evented UPnP state variable of the service has changed its state. The
109      * following change event is expected:
110      * </p>
111      * <ul>
112      * <li>The property name is the constant {@link #EVENTED_STATE_VARIABLES}.</li>
113      * <li>The "old value" can be <code>null</code>, only the current state has to be included.</li>
114      * <li>The "new value" is a <code>Collection</code> of {@link org.fourthline.cling.model.state.StateVariableValue},
115      *     representing the current state of the service after the change.</li>
116      * </ul>
117      * <p>
118      * The collection has to include values for <em>all</em> state variables, no
119      * matter what state variable was updated. Any other event is ignored (e.g. individual property
120      * changes).
121      * </p>
122      *
123      * @return An adapter that will notify its listeners whenever any evented state variable changes.
124      */
125     public PropertyChangeSupport getPropertyChangeSupport();
126 
127     /**
128      * Reading the state of a service manually.
129      *
130      * @return A <code>Collection</code> of {@link org.fourthline.cling.model.state.StateVariableValue}, representing
131      *         the current state of the service, that is, all evented state variable values.
132      * @throws Exception Any error that occurred when the service's state was accessed.
133      */
134     public Collection<StateVariableValue> getCurrentState() throws Exception;
135 
136 }