1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.tomgibara.pronto.control;
19
20 import com.tomgibara.pronto.core.ProntoException;
21 import com.tomgibara.pronto.core.impl.StaticProperties;
22 import com.tomgibara.pronto.state.StateEngine;
23 import com.tomgibara.pronto.util.FactoryHelper;
24
25 /**
26 * <p>
27 * Instances of this class are responsible for creating <code>Controller</code>
28 * objects from <code>ControllerSettings</code> interface.
29 * </p>
30 *
31 * <p>
32 * Only one instance of a ControlFactory is available through the
33 * <code>getInstance()</code> method. The default implementation returned by
34 * this static method can be changed by assigning the system property
35 * <code>com.tomgibara.pronto.control.factory</code> the name of a class which
36 * extends this abstract base class.
37 * </p>
38 *
39 * @author Tom Gibara
40 */
41
42 public abstract class ControlFactory {
43
44 /** The default factory class name. */
45 private static final String CLASS = StaticProperties.getString("pronto.control.factory-class");
46
47 /** The property name from which a different class name can be obtained. */
48 private static final String PROPERTY = StaticProperties.getString("pronto.control.factory-property");
49
50 /** A factory helper object which does the work of instantiating the class. */
51 private static final FactoryHelper<ControlFactory> HELPER = new FactoryHelper<ControlFactory>(CLASS, null, PROPERTY);
52
53 /**
54 * Should be called to obtain a <code>ConfigFactory</code> instance. This
55 * method is the single entry-point to configuration functionality in the
56 * pronto framework.
57 *
58 * @return the single instance of this factory
59 *
60 * @throws ProntoException
61 * if the factory instance could not be created
62 */
63
64 public static ControlFactory getInstance() throws ProntoException {
65 try {
66 return HELPER.getInstance();
67 } catch (Exception e) {
68 throw new ProntoException("previously recorded exception: " + e.getMessage(), e);
69 }
70 }
71
72
73
74 /**
75 * Indicates whether the interface supplied is recognized by this factory.
76 * Implementations of recognized interfaces may be passed to the
77 * <code>newController</code> method to create <code>Controller</code>
78 * objects.
79 *
80 * @param iface
81 * an interface whose instances may be used to create a new
82 * controller
83 *
84 * @return whether the factory can generate a controller from the supplied
85 * interface
86 *
87 */
88
89 public abstract boolean isSettingsIfaceSupported(Class<? extends ControllerSettings> iface);
90
91 /**
92 * Constructs a new controller.
93 *
94 * @param settings
95 * the settings that define the new controller.
96 * @param engine
97 * the engine that will be operated by the controller.
98 * @param adapter
99 * the adapter that mediates external data and the state graph
100 *
101 * @param <S>
102 * the engine's state type
103 * @param <L>
104 * the engine's label type
105 * @param <P>
106 * the engine's parameter type
107 *
108 * @return a new controller, the operation of which is defined by the
109 * supplied settings.
110 *
111 * @throws IllegalArgumentException
112 * if the type of settings is not recognized by this factory
113 * @throws ProntoControlException
114 * if the settings supplied were invalid
115 */
116
117 public abstract <S, L, P> Controller<S, L, P> newController(ControllerSettings settings,
118 StateEngine<S, L, P> engine, EngineControlAdapter<S, L, P> adapter) throws IllegalArgumentException,
119 ProntoControlException;
120
121 }