/* * * Copyright 1999-2004 Carnegie Mellon University. * Portions Copyright 2004 Sun Microsystems, Inc. * Portions Copyright 2004 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ package edu.cmu.sphinx.util.props; /** * Defines the interface that must be implemented by any configurable component in Sphinx-4. The life cycle of a * component is as follows: * <ul><li> <b>Class Parsing</b> The class file is parsed in order to determine all its configurable properties. These * are defined using <code>public static final String</code> fields which are annotated with one of the following * annotations: <ul> <li>S4Integer <li>S4Double <li>S4Boolean <li>S4Component <li>S4ComponentList </ul> Further * informations about property-specific fields can be found in the javadoc of the property-annotation-definitions. Only * names of annotated properties will be allowed by the configuration system later on. * <li> <b>Construction</b> - The (empty) component constructor is called in order to instantiate the component. * Typically the constructor does little, if any work, since the component has not been configured yet. * <li> <b> Configuration</b> - Shortly after instantiation, the component's <code>newProperties</code> method is * called. This method is called with a <code>PropertySheet</code> containing the properties (usually taken from an * external configuration file). The component should extract the properties from the property sheet. If some properties * defined for a component does not fulfill the property definition given by the annotation (type, range, etc.) a * <code>PropertyException</code> is thrown. Typically, once a component gets its configuration data via the * <code>newData</code> method, the component will initialize itself. * <p> * Note: In most cases <code>newProperties</code> is called only once as a result of system configuration during * startup. But nevertheless it is possible (and sometimes necessary) to reconfigure a component while it's running. * Therefore, a well behaved component should react properly to multiple <code>newProperties</code> calls. </ul> * <p> * <b>Connecting to other components</b> * <p> Components often need to interact with other components in the system. * One of the design goals of Sphinx-4 is that it allows for very flexible hook up of components in the system. * Therefore, it is *not* considered good S4 style to hardcode which subcomponents a particular subcomponent is * interacting with. Instead, the component should use the configuration manager to provide the hook up to another * component. * <p> * For example, if a component needs to interact with a Linguist. Instead of explicitly setting which linguist is to be * used via a constructor or via a <code>setLinguist</code> call, the component should instead define a configuration * property for the linguist. This would be done like so: * <code> * \@S4Component(type=Linguist.class) * public static String PROP_LINGUIST = "linguist"; * </code> * <p> The linguist is made available in the <code>newProperties</code> method, like so: <p> * <code> * public void newProperties(PropertySheet propertySheet) { * linguist = (Linguist) propertySheet.getComponent(PROP_LINGUIST); * } * </code> * This <code>getComponent</code> call will find the proper linguist based upon the configuration data. Thus, if the * configuration for this component had the 'linguist' defined to be 'dynamicLexTreeLinguist', then the configuration * manager will look up and return a linguist with that name, creating and configuring it as necessary. Of course, the * dynamicLexTreeLinguist itself may have a number of sub-components that will be created and configured as a result. If * the component doesn't exist (but was defined to mandatory) and no configuration information is found in the config * file for it, or if it is of the wrong type, a <code>PropertyException</code> will be thrown. */ public interface Configurable { /** * This method is called when this configurable component needs to be reconfigured. * * @param ps a property sheet holding the new data * @throws PropertyException if there is a problem with the properties. */ public void newProperties(PropertySheet ps) throws PropertyException; }