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 }