📄 xmlmanager.java
字号:
/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licencing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package org.jgap.xml;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import junitx.util.PrivateAccessor;
import org.jgap.*;
import org.w3c.dom.*;
/**
* The XMLManager performs marshalling of genetic entity instances
* (such as Chromosomes and Genotypes) to XML representations of those
* entities, as well as unmarshalling. All of the methods in this class are
* static, so no construction is required (or allowed).
*
* @author Neil Rotstan
* @author Klaus Meffert
* @since 1.0
*/
public class XMLManager {
/** String containing the CVS revision. Read out via reflection!*/
private final static String CVS_REVISION = "$Revision: 1.20 $";
/**
* Constant representing the name of the genotype XML element tag.
*/
private static final String GENOTYPE_TAG = "genotype";
/**
* Constant representing the name of the chromosome XML element tag.
*/
private static final String CHROMOSOME_TAG = "chromosome";
/**
* Constant representing the name of the gene XML element tag.
*/
private static final String GENES_TAG = "genes";
/**
* Constant representing the name of the gene XML element tag.
*/
private static final String GENE_TAG = "gene";
private static final String ALLELE_TAG = "allele";
/**
* Constant representing the name of the size XML attribute that is
* added to genotype and chromosome elements to describe their size.
*/
private static final String SIZE_ATTRIBUTE = "size";
/**
* Constant representing the fully-qualified name of the concrete
* Gene class that was marshalled.
*/
private static final String CLASS_ATTRIBUTE = "class";
/**
* Shared DocumentBuilder, which is used to create new DOM Document
* instances.
*/
private static final DocumentBuilder m_documentCreator;
/**
* Shared lock object used for synchronization purposes.
*/
private static final Object m_lock = new Object();
/**
* @author Neil Rotstan
* @since 1.0
*/
static {
try {
m_documentCreator =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
catch (ParserConfigurationException parserError) {
throw new RuntimeException(
"XMLManager: Unable to setup DocumentBuilder: "
+ parserError.getMessage());
}
}
/**
* Private constructor. All methods in this class are static, so no
* construction is allowed.
*/
private XMLManager() {
}
/**
* Marshall a Chromosome instance to an XML Document representation,
* including its contained Gene instances.
*
* @param a_subject the chromosome to represent as an XML document
* @return a Document object representing the given Chromosome
*
* @author Neil Rotstan
* @since 1.0
* @deprecated use XMLDocumentBuilder instead
*/
public static Document representChromosomeAsDocument(final IChromosome
a_subject) {
// DocumentBuilders do not have to be thread safe, so we have to
// protect creation of the Document with a synchronized block.
// -------------------------------------------------------------
Document chromosomeDocument;
synchronized (m_lock) {
chromosomeDocument = m_documentCreator.newDocument();
}
Element chromosomeElement =
representChromosomeAsElement(a_subject, chromosomeDocument);
chromosomeDocument.appendChild(chromosomeElement);
return chromosomeDocument;
}
/**
* Marshall a Genotype to an XML Document representation, including its
* population of Chromosome instances.
*
* @param a_subject the genotype to represent as an XML document
* @return a Document object representing the given Genotype
*
* @author Neil Rotstan
* @since 1.0
* @deprecated use XMLDocumentBuilder instead
*/
public static Document representGenotypeAsDocument(final Genotype a_subject) {
// DocumentBuilders do not have to be thread safe, so we have to
// protect creation of the Document with a synchronized block.
// -------------------------------------------------------------
Document genotypeDocument;
synchronized (m_lock) {
genotypeDocument = m_documentCreator.newDocument();
}
Element genotypeElement =
representGenotypeAsElement(a_subject, genotypeDocument);
genotypeDocument.appendChild(genotypeElement);
return genotypeDocument;
}
/**
* Marshall an array of Genes to an XML Element representation.
*
* @param a_geneValues the genes to represent as an XML element
* @param a_xmlDocument a Document instance that will be used to create
* the Element instance. Note that the element will NOT be added to the
* document by this method
* @return an Element object representing the given genes
*
* @author Neil Rotstan
* @author Klaus Meffert
* @since 1.0
* @deprecated use XMLDocumentBuilder instead
*/
public static Element representGenesAsElement(final Gene[] a_geneValues,
final Document a_xmlDocument) {
// Create the parent genes element.
// --------------------------------
Element genesElement = a_xmlDocument.createElement(GENES_TAG);
// Now add gene sub-elements for each gene in the given array.
// -----------------------------------------------------------
Element geneElement;
for (int i = 0; i < a_geneValues.length; i++) {
// Create the allele element for this gene.
// ----------------------------------------
geneElement = a_xmlDocument.createElement(GENE_TAG);
// Add the class attribute and set its value to the class
// name of the concrete class representing the current Gene.
// ---------------------------------------------------------
geneElement.setAttribute(CLASS_ATTRIBUTE,
a_geneValues[i].getClass().getName());
// Create a text node to contain the string representation of
// the gene's value (allele).
// ----------------------------------------------------------
Element alleleRepresentation = representAlleleAsElement(a_geneValues[i],
a_xmlDocument);
// And now add the text node to the gene element, and then
// add the gene element to the genes element.
// -------------------------------------------------------
geneElement.appendChild(alleleRepresentation);
genesElement.appendChild(geneElement);
}
return genesElement;
}
/**
*
* @param a_gene Gene
* @param a_xmlDocument Document
* @return Element
*
* @author Klaus Meffert
* @since 2.0
*/
private static Element representAlleleAsElement(final Gene a_gene,
final Document a_xmlDocument) {
Element alleleElement = a_xmlDocument.createElement(ALLELE_TAG);
alleleElement.setAttribute("class", a_gene.getClass().getName());
alleleElement.setAttribute("value", a_gene.getPersistentRepresentation());
return alleleElement;
}
/**
* Marshall a Chromosome instance to an XML Element representation,
* including its contained Genes as sub-elements. This may be useful in
* scenarios where representation as an entire Document is undesirable,
* such as when the representation of this Chromosome is to be combined
* with other elements in a single Document.
*
* @param a_subject the chromosome to represent as an XML element
* @param a_xmlDocument a Document instance that will be used to create
* the Element instance. Note that the element will NOT be added to the
* document by this method
* @return an Element object representing the given Chromosome
*
* @author Neil Rotstan
* @since 1.0
* @deprecated use XMLDocumentBuilder instead
*/
public static Element representChromosomeAsElement(final IChromosome a_subject,
final Document a_xmlDocument) {
// Start by creating an element for the chromosome and its size
// attribute, which represents the number of genes in the chromosome.
// ------------------------------------------------------------------
Element chromosomeElement =
a_xmlDocument.createElement(CHROMOSOME_TAG);
chromosomeElement.setAttribute(SIZE_ATTRIBUTE,
Integer.toString(a_subject.size()));
// Next create the genes element with its nested gene elements,
// which will contain string representations of the alleles.
// --------------------------------------------------------------
Element genesElement = representGenesAsElement(a_subject.getGenes(),
a_xmlDocument);
// Add the new genes element to the chromosome element and then
// return the chromosome element.
// -------------------------------------------------------------
chromosomeElement.appendChild(genesElement);
return chromosomeElement;
}
/**
* Marshall a Genotype instance into an XML Element representation,
* including its population of Chromosome instances as sub-elements.
* This may be useful in scenarios where representation as an
* entire Document is undesirable, such as when the representation
* of this Genotype is to be combined with other elements in a
* single Document.
*
* @param a_subject the genotype to represent as an XML element
* @param a_xmlDocument a Document instance that will be used to create
* the Element instance. Note that the element will NOT be added to the
* document by this method
* @return an Element object representing the given Genotype
*
* @author Neil Rotstan
* @since 1.0
* @deprecated use XMLDocumentBuilder instead
*/
public static Element representGenotypeAsElement(final Genotype a_subject,
final Document a_xmlDocument) {
Population population = a_subject.getPopulation();
// Start by creating the genotype element and its size attribute,
// which represents the number of chromosomes present in the
// genotype.
// --------------------------------------------------------------
Element genotypeTag = a_xmlDocument.createElement(GENOTYPE_TAG);
genotypeTag.setAttribute(SIZE_ATTRIBUTE,
Integer.toString(population.size()));
// Next, add nested elements for each of the chromosomes in the
// genotype.
// ------------------------------------------------------------
for (int i = 0; i < population.size(); i++) {
Element chromosomeElement
= representChromosomeAsElement(population.getChromosome(i),
a_xmlDocument);
genotypeTag.appendChild(chromosomeElement);
}
return genotypeTag;
}
/**
* Unmarshall a Chromosome instance from a given XML Element
* representation.
*
* @param a_activeConfiguration current Configuration object
* @param a_xmlElement the XML Element representation of the Chromosome
* @return a new Chromosome instance setup with the data from the XML Element
* representation
*
* @throws ImproperXMLException if the given Element is improperly
* structured or missing data
* @throws UnsupportedRepresentationException if the actively configured
* Gene implementation does not support the string representation of the
* alleles used in the given XML document
* @throws GeneCreationException if there is a problem creating or populating
* a Gene instance
*
* @author Neil Rotstan
* @since 1.0
*/
public static Gene[] getGenesFromElement(
Configuration a_activeConfiguration, Element a_xmlElement)
throws ImproperXMLException, UnsupportedRepresentationException,
GeneCreationException {
// Do some sanity checking. Make sure the XML Element isn't null and
// that it in fact represents a set of genes.
// -----------------------------------------------------------------
if (a_xmlElement == null ||
! (a_xmlElement.getTagName().equals(GENES_TAG))) {
throw new ImproperXMLException(
"Unable to build Chromosome instance from XML Element: " +
"given Element is not a 'genes' element.");
}
List genes = Collections.synchronizedList(new ArrayList());
// Extract the nested gene elements.
// ---------------------------------
NodeList geneElements = a_xmlElement.getElementsByTagName(GENE_TAG);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -