DBVIEW
src/org/dbview/input_addons/AbstractConfiguration.java
00001 /*
00002         DbView - Graph Visualization
00003     Copyright (C) 2012  Denis BEURIVE
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 /**
00020  * @author Denis Beurive
00021  */
00022 
00023 package org.dbview.input_addons;
00024 
00025 import org.jdom.Element;
00026 import org.jdom.output.XMLOutputter;
00027 import java.util.ArrayList;
00028 
00029 /**
00030  * This class implements the database's configuration adaptor.
00031  * @author Denis Beurive
00032  */
00033 abstract public class AbstractConfiguration
00034 {
00035     /**
00036      * Name of the profile associated to this configuration.
00037      */
00038     private String __profile_name  = null;
00039 
00040     /**
00041      * The name of the add-on to which this adaptor is associated.
00042      */
00043     private String __addon = null;
00044 
00045     /**
00046      * Construct a configuration.
00047      */
00048     public AbstractConfiguration()
00049     {
00050         this.__addon = this._getAddOnName_();
00051     }
00052 
00053     /**
00054      * This method returns the name of the add-on associated to this adaptor.
00055      *
00056      * @return The method returns the name of the add-on associated to this adaptor.
00057      */
00058     public String getAddOnName()
00059     {
00060         return this.__addon;
00061     }
00062 
00063     /**
00064      * <p>This method initializes a configuration based on a given XML document.
00065      *    The structure of this (XML) document depends on the values of parameters "in_addon_name" and "in_profile_name".
00066      *    If these parameters are <b>NOT</b> given, then the XML document must be:</p> 
00067      *
00068      * <pre>
00069      *      &lt;configuration name=&quot;...&quot; target=&quot;...&quot;&gt;
00070      *         &lt;data&gt;
00071      *         ...
00072      *         &lt;/data&gt;
00073      *      &lt;/configuration&gt;
00074      * </pre>
00075      * 
00076      * <p>
00077      * Otherwise:
00078      * </p>
00079      *
00080      * <pre>
00081      *      &lt;data&gt;
00082      *      ...
00083      *      &lt;/data&gt;
00084      * </pre>
00085      *
00086      * @param in_xml
00087      *            XML document.
00088      * @param in_addon_name
00089      *            Name of the add-on to which this configuration is associated.
00090      *            This argument's value may be null.
00091      * @param in_profile_name
00092      *            Name of the profile. This argument's value may be null.
00093      * @throws ConfigurationException
00094      */
00095     public void fromXml(Element in_xml,
00096                         String in_addon_name,
00097                         String in_profile_name) throws ConfigurationException, Exception
00098     {
00099         if ((null == in_profile_name) ^ (null == in_addon_name))
00100         {
00101             throw new Exception("Unexpected error: this error should not happen unless you modify the code of the software. The parameters \"in_addon_name\" and \"in_profile_name\" must be defined, or undefined, simultaneously.");
00102         }
00103 
00104         // Get the configuration's name.
00105         if (null == in_profile_name)
00106         {
00107             this.__profile_name = in_xml.getAttributeValue("name");
00108             if (null == this.__profile_name)
00109             {
00110                 throw new ConfigurationException("XML representation of the configuration has no name!");
00111             }
00112         }
00113         else
00114         {
00115             this.__profile_name = in_profile_name;
00116         }
00117 
00118         // Get the configuration's type.
00119         if (null == in_addon_name)
00120         {
00121             this.__addon = in_xml.getAttributeValue("target");
00122             if (null == this.__addon)
00123             {
00124                 throw new ConfigurationException("XML representation of the configuration has no type!");
00125             }
00126         }
00127         else
00128         {
00129             this.__addon = in_addon_name;
00130         }
00131 
00132         // Extract data from the generic configuration's holder.
00133         Element specific = null;
00134         if (null == in_profile_name)
00135         {
00136             specific = in_xml.getChild("data");
00137         }
00138         else
00139         {
00140             specific = in_xml;
00141         }
00142         if (null == specific)
00143         {
00144             throw new ConfigurationException("XML representation of the configuration has no \"specific\" data container!");
00145         }
00146 
00147         try
00148         {
00149             this._fromXml_(specific);
00150         }
00151         catch (ConfigurationException e)
00152         {
00153             throw new ConfigurationException("The XML document provided from the CLI adaptor seems to be invalid. This error should not happen unless you modify the software. Did you call the method \"AbstractCli::getGetCont()\" with \"in_set_default=FALSE?\" " + e.getMessage());
00154         }
00155     }
00156 
00157     /**
00158      * <p>This method creates a XML document that represents a configuration.</p>
00159      * <p>The structure of the returned document is:</p>
00160      *
00161      * <pre>
00162      *      &lt;configuration name=&quot;...&quot; target=&quot;...&quot;&gt;
00163      *          &lt;data&gt;...&lt;/data&gt;
00164      *      &lt;/configuration&gt;
00165      * </pre>
00166      *
00167      * @return The method returns a XML element.
00168      */
00169     public Element toXml()
00170     {
00171         // Create the configuration.
00172         Element configuration = new Element("configuration");
00173         configuration.setAttribute("name", this.__profile_name);
00174         configuration.setAttribute("target", this.getAddOnName());
00175 
00176         // Add the generic and the specialized configuration.
00177         configuration.addContent(this.getData());
00178 
00179         return configuration;
00180     }
00181 
00182     /**
00183      * <p>This method returns the data part of the configuration.</p>
00184      * <p>The returned document is:</p>
00185      *
00186      * <pre>
00187      *      &lt;data&gt;...&lt;/data&gt;
00188      * </pre>
00189      *
00190      * @return The method returns the data part of the configuration.
00191      */
00192     public Element getData()
00193     {
00194         // Ask the generic configuration's holder to export the list of specific
00195         // configuration's data.
00196         ArrayList<Element> specific_data = this._toXml_();
00197 
00198         // Build the specific configuration.
00199         Element generic = new Element("data");
00200         for (int index = 0; index < specific_data.size(); index++)
00201         {
00202             generic.addContent(specific_data.get(index));
00203         }
00204 
00205         return generic;
00206     }
00207 
00208     /**
00209      * This method generates a literal representation of the XML document.
00210      *
00211      * @return The method returns a literal representation of the XML document.
00212      */
00213     public String printToXml()
00214     {
00215         XMLOutputter outputter = new XMLOutputter();
00216         outputter.setFormat(org.jdom.output.Format.getPrettyFormat());
00217         return outputter.outputString(this.toXml());
00218     }
00219 
00220     /**
00221      * This method returns a list of XML elements. These XML elements represent
00222      * the configuration for the specific add-on to which the configuration is
00223      * associated. These XML elements will be included in the configuration.
00224      *
00225      * @return The method returns a list of XML elements.
00226      * @note This method is used with the repository.
00227      */
00228     protected abstract ArrayList<Element> _toXml_();
00229 
00230     /**
00231      * This method initializes the configuration for the specific add-on to
00232      * which the configuration is associated. The initialization is done using
00233      * the content of a given XML element.
00234      *
00235      * @param in_xml
00236      *            Document XML.
00237      * @throws ConfigurationException
00238      * @note This method is used with the catalogue.
00239      */
00240     protected abstract void _fromXml_(Element in_xml) throws ConfigurationException;
00241 
00242     /**
00243      * This method returns the name of the specific add-on to
00244      * which the configuration is associated.
00245      *
00246      * @return The method returns the name of the specific add-on
00247      *         to which the configuration is associated.
00248      */
00249     protected abstract String _getAddOnName_();
00250 
00251     /**
00252      * This method returns a structure that can be sued to produce a literal
00253      * representation of the configuration. The returned structure is an array.
00254      * Each element of the returned array is an array that contains 2 strings.
00255      * <ul>
00256      *    <li>The first element of the array is the name of a configuration
00257      *        parameter.</li>
00258      *    <li>The second element of the array is the value of a
00259      *        configuration parameter.</li>
00260      * </ul>
00261      *
00262      * @return The method returns a structure that can be used to produce a
00263      *         literal representation of the configuration.
00264      */
00265     public abstract ArrayList<String[]> toStrings();
00266 
00267 }