/* * This file is part of INDI for Java Client. * * INDI for Java Client is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * INDI for Java Client is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with INDI for Java Client. If not, see * <http://www.gnu.org/licenses/>. */ package laazotea.indi.client; import java.util.ArrayList; import laazotea.indi.INDIException; import org.w3c.dom.Element; /** * A class representing a INDI Element. The subclasses * <code>INDIBLOBElement</code>, * <code>INDILightElement</code>, * <code>INDINumberElement</code>, * <code>INDISwitchElement</code> and * <code>INDITextElement</code> define the basic Elements that a INDI Property * may contain according to the INDI protocol. <p> It implements a listener * mechanism to notify changes in its value. * * @author S. Alonso (Zerjillo) [zerjioi at ugr.es] * @version 1.32, February 4, 2013 */ public abstract class INDIElement { /** * The property to which this Element belongs */ private INDIProperty property; /** * The name of the Element */ private String name; /** * The label of the Element */ private String label; /** * The list of listeners of this Element */ private ArrayList<INDIElementListener> listeners; /** * Constructs an instance of * <code>INDIElement</code>. Called by its sub-classes. * <code>INDIElement</code>s are not usually directly instantiated. Usually * used by * <code>INDIProperty</code>. * * @param xml A XML Element * <code><defXXX></code> describing the Element. * @param property The * <code>INDIProperty</code> to which this Element belongs. * @throws IllegalArgumentException if the XML Element is not well formed * (does not contain a * <code>name</code> attribute). */ protected INDIElement(Element xml, INDIProperty property) throws IllegalArgumentException { this.property = property; name = xml.getAttribute("name").trim(); if (name.length() == 0) { throw new IllegalArgumentException("No name for Element"); } label = xml.getAttribute("label"); if (label.length() == 0) { // If empty we use the name label = name; } listeners = new ArrayList<INDIElementListener>(); } /** * Adds a new listener that will be notified on this Element value changes. * * @param listener The listener to add. */ public void addINDIElementListener(INDIElementListener listener) { listeners.add(listener); } /** * Removes a listener from the listeners list. This listener will no longer be * notified of changes of this Element. * * @param listener The listener to remove. */ public void removeINDIElementListener(INDIElementListener listener) { listeners.remove(listener); } /** * Notifies the listeners about changes of the value of the Element */ protected void notifyListeners() { ArrayList<INDIElementListener> lCopy = (ArrayList<INDIElementListener>) listeners.clone(); for (int i = 0; i < lCopy.size(); i++) { INDIElementListener l = lCopy.get(i); l.elementChanged(this); } } /** * Gets the label of the Element. * * @return The label of the Element. */ public String getLabel() { return label; } /** * Gets the name of the Element. * * @return The name of the Element. */ public String getName() { return name; } /** * Gets the Property to which this Element belongs. * * @return The property to which this Element belongs. */ public INDIProperty getProperty() { return property; } /** * Gets the current value of the Element. * * @return The current value of the Element. */ public abstract Object getValue(); /** * Gets the current value of the Element as a String. * * @return The current value of the Element as a String. */ public abstract String getValueAsString(); /** * Sets the current value of the Element. It is assummed that the XML Element * is really describing the new value for this particular Element. <p> This * method will notify the change of the value to the listeners. * * @param xml A XML Element <oneXXX> describing the Element. * @throws IllegalArgumentException if the * <code>xml</code> is not well formed. */ protected abstract void setValue(Element xml) throws IllegalArgumentException; /** * Gets the desired value of the Element. * * @return The current desiredvalue of the Element. * <code>null</code> if it is not setted. */ public abstract Object getDesiredValue(); /** * Sets the desired value of the Element to * <code>desiredValue</code> * * @param desiredValue The desired value for the property. * @throws INDIValueException if the * <code>desiredValue</code> is not of the correct type for the Element. */ public abstract void setDesiredValue(Object desiredValue) throws INDIValueException; /** * Returns * <code>true</code> if the * <code>desiredValue</code> has been setted (and thus if it should be send to * the Driver). * * @return * <code>true</code> if the desiredValue has been setted. * <code>false</code> otherwise. */ public abstract boolean isChanged(); /** * Gets a default UI component to handle the repesentation and control of this * Element. The panel is registered as a listener of this Element. Please note * that the UI class must implement INDIElementListener. The component will be * chosen depending on the loaded UI libraries (I4JClientUI, I4JAndroid, etc). * Note that a casting of the returned value must be done. If a previous UI * element has been asked, it will be discarded and de-registered as listener. * So, only one default UI element will be active. * * @return A UI component that handles this Element. */ public abstract INDIElementListener getDefaultUIComponent() throws INDIException; /** * Checks if a desired value would be correct to be applied to the Element * according to its definition and limits. * * @param desiredValue The value to be checked. * @return * <code>true</code> if the * <code>desiredValue</code> would be acceptable to be applied to the element. * <code>false</code> otherwise. * @throws INDIValueException if the desiredValue is not correct. */ public abstract boolean checkCorrectValue(Object desiredValue) throws INDIValueException; /** * Returns the XML code <oneXXX> representing this Element with a new * desired value). The desired value is reseted. * * @return the XML code * <code><oneXXX></code> representing the Element with a new value. * @see #setDesiredValue */ protected abstract String getXMLOneElementNewValue(); /** * Gets the name of the element and its current value * * @return a String with the name of the Element and Its Value */ public abstract String getNameAndValueAsString(); }