/* * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ /* * XMLSerializationMethodHandler.java * Copyright (C) 2004-2012 University of Waikato, Hamilton, New Zealand * */ package weka.core.xml; import java.lang.reflect.Method; import org.w3c.dom.Element; import weka.core.RevisionHandler; import weka.core.RevisionUtils; /** * This class handles relationships between display names of properties * (or classes) and Methods that are associated with them. It differentiates * between read and write methods. It automatically stores public methods that * have the same signature as the <code>readFromXML()</code> and * <code>writeToXML()</code> methods in the <code>XMLSerialization</code> * class. * * @see MethodHandler * @see XMLSerialization * * @author FracPete (fracpete at waikato dot ac dot nz) * @version $Revision: 8034 $ */ public class XMLSerializationMethodHandler implements RevisionHandler { /** for storing read methods */ protected MethodHandler m_ReadMethods = null; /** for storing write methods */ protected MethodHandler m_WriteMethods = null; /** the object to retrieve the methods from */ protected Object owner = null; /** * initializes the method handling, executes also <code>clear()</code>, which * adds initial methods automatically. * * @param owner the owner to retrieve the methods from * @throws Exception if initialization fails * @see #clear() */ public XMLSerializationMethodHandler(Object owner) throws Exception { super(); this.owner = owner; m_ReadMethods = new MethodHandler(); m_WriteMethods = new MethodHandler(); clear(); } /** * adds all methods that are like <code>template</code> to the method list * * @param handler the list to add fitting methods to * @param template the signature to check the given methods against * @param methods the methods to check */ protected void addMethods(MethodHandler handler, Method template, Method[] methods) { int i; int n; Method method; boolean equal; String name; for (i = 0; i < methods.length; i++) { method = methods[i]; // is it template? if (template.equals(method)) continue; // tests // 1. return type if (!template.getReturnType().equals(method.getReturnType())) continue; // 2. signature if (template.getParameterTypes().length != method.getParameterTypes().length) continue; equal = true; for (n = 0; n < template.getParameterTypes().length; n++) { if (!template.getParameterTypes()[n].equals(method.getParameterTypes()[n])) { equal = false; break; } } // add to list if (equal) { name = method.getName(); name = name.replaceAll("read|write", ""); name = name.substring(0, 1).toLowerCase() + name.substring(1); handler.add(name, method); } } } /** * automatically adds all fitting methods to the custom read/write lists, * it excludes only the generic ones. it is automatically called in * <code>clear()</code> * It only work with methods that apply to the naming rule "read" + property * name (same for "write") * * @throws Exception if retrieving of methods fails * @see #clear() */ protected void addMethods() throws Exception { Method method; Class[] params; // read params = new Class[1]; params[0] = Element.class; method = owner.getClass().getMethod("readFromXML", params); addMethods(m_ReadMethods, method, owner.getClass().getMethods()); // write params = new Class[3]; params[0] = Element.class; params[1] = Object.class; params[2] = String.class; method = owner.getClass().getMethod("writeToXML", params); addMethods(m_WriteMethods, method, owner.getClass().getMethods()); } /** * returns the method with the given name that has the same signature as * <code>readFromXML()</code> of the <code>XMLSerialiation</code> class. * simplifies the adding of custom methods. * * @param o the object to inspect * @param name the name of the method to return * @return either <code>null</code> if no method was found or a reference * @see XMLSerialization#readFromXML(Element) */ public static Method findReadMethod(Object o, String name) { Class[] params; Method result; result = null; params = new Class[1]; params[0] = Element.class; try { result = o.getClass().getMethod(name, params); } catch (Exception e) { result = null; } return result; } /** * returns the method with the given name that has the same signature as * <code>writeToXML()</code> of the <code>XMLSerialiation</code> class. * simplifies the adding of custom methods. * * @param o the object to inspect * @param name the name of the method to return * @return either <code>null</code> if no method was found or a reference * @see XMLSerialization#writeToXML(Element, Object, String) */ public static Method findWriteMethod(Object o, String name) { Class[] params; Method result; result = null; params = new Class[3]; params[0] = Element.class; params[1] = Object.class; params[2] = String.class; try { result = o.getClass().getMethod(name, params); } catch (Exception e) { result = null; } return result; } /** * removes all current methods and adds the methods according to the * */ public void clear() { m_ReadMethods.clear(); m_WriteMethods.clear(); try { addMethods(); } catch (Exception e) { e.printStackTrace(); } } /** * returns the handler for read methods * * @return the methodhandler for read methods */ public MethodHandler read() { return m_ReadMethods; } /** * returns the handler for write methods * * @return the methodhandler for read methods */ public MethodHandler write() { return m_WriteMethods; } /** * adds read and write methods for the given class, i.e., read&;lt;name> * and write<name> ("name" is prefixed by read and write) * * @param handler the handler class that contains the read and write method * @param cls the class to register the read and write method for * @param name the suffix of the read and write method */ public void register(Object handler, Class cls, String name) { read().add(cls, XMLSerializationMethodHandler.findReadMethod(handler, "read" + name)); write().add(cls, XMLSerializationMethodHandler.findWriteMethod(handler, "write" + name)); } /** * returns the read and write method handlers as string * * @return the read/write method handlers as string */ public String toString() { return "Read Methods:\n" + read() + "\n\n" + "Write Methods:\n" + write(); } /** * Returns the revision string. * * @return the revision */ public String getRevision() { return RevisionUtils.extract("$Revision: 8034 $"); } }