1 10 package org.jgap.xml; 11 12 import java.io.*; 13 import java.lang.reflect.*; 14 import java.util.*; 15 import javax.xml.parsers.*; 16 import javax.xml.transform.*; 17 import javax.xml.transform.dom.*; 18 import javax.xml.transform.stream.*; 19 import junitx.util.PrivateAccessor; 20 21 import org.jgap.*; 22 import org.w3c.dom.*; 23 24 34 public class XMLManager { 35 36 37 private final static String CVS_REVISION = "$Revision: 1.19 $"; 38 39 42 private static final String GENOTYPE_TAG = "genotype"; 43 44 47 private static final String CHROMOSOME_TAG = "chromosome"; 48 49 52 private static final String GENES_TAG = "genes"; 53 54 57 private static final String GENE_TAG = "gene"; 58 59 private static final String ALLELE_TAG = "allele"; 60 61 65 private static final String SIZE_ATTRIBUTE = "size"; 66 67 71 private static final String CLASS_ATTRIBUTE = "class"; 72 73 77 private static final DocumentBuilder m_documentCreator; 78 79 82 private static final Object m_lock = new Object (); 83 84 88 static { 89 try { 90 m_documentCreator = 91 DocumentBuilderFactory.newInstance().newDocumentBuilder(); 92 } 93 catch (ParserConfigurationException parserError) { 94 throw new RuntimeException ( 95 "XMLManager: Unable to setup DocumentBuilder: " 96 + parserError.getMessage()); 97 } 98 } 99 100 104 private XMLManager() { 105 } 106 107 118 public static Document representChromosomeAsDocument(final IChromosome 119 a_subject) { 120 Document chromosomeDocument; 124 synchronized (m_lock) { 125 chromosomeDocument = m_documentCreator.newDocument(); 126 } 127 Element chromosomeElement = 128 representChromosomeAsElement(a_subject, chromosomeDocument); 129 chromosomeDocument.appendChild(chromosomeElement); 130 return chromosomeDocument; 131 } 132 133 144 public static Document representGenotypeAsDocument(final Genotype a_subject) { 145 Document genotypeDocument; 149 synchronized (m_lock) { 150 genotypeDocument = m_documentCreator.newDocument(); 151 } 152 Element genotypeElement = 153 representGenotypeAsElement(a_subject, genotypeDocument); 154 genotypeDocument.appendChild(genotypeElement); 155 return genotypeDocument; 156 } 157 158 172 public static Element representGenesAsElement(final Gene[] a_geneValues, 173 final Document a_xmlDocument) { 174 Element genesElement = a_xmlDocument.createElement(GENES_TAG); 177 Element geneElement; 180 for (int i = 0; i < a_geneValues.length; i++) { 181 geneElement = a_xmlDocument.createElement(GENE_TAG); 184 geneElement.setAttribute(CLASS_ATTRIBUTE, 188 a_geneValues[i].getClass().getName()); 189 Element alleleRepresentation = representAlleleAsElement(a_geneValues[i], 193 a_xmlDocument); 194 geneElement.appendChild(alleleRepresentation); 198 genesElement.appendChild(geneElement); 199 } 200 return genesElement; 201 } 202 203 212 private static Element representAlleleAsElement(final Gene a_gene, 213 final Document a_xmlDocument) { 214 Element alleleElement = a_xmlDocument.createElement(ALLELE_TAG); 215 alleleElement.setAttribute("class", a_gene.getClass().getName()); 216 alleleElement.setAttribute("value", a_gene.getPersistentRepresentation()); 217 return alleleElement; 218 } 219 220 237 public static Element representChromosomeAsElement(final IChromosome a_subject, 238 final Document a_xmlDocument) { 239 Element chromosomeElement = 243 a_xmlDocument.createElement(CHROMOSOME_TAG); 244 chromosomeElement.setAttribute(SIZE_ATTRIBUTE, 245 Integer.toString(a_subject.size())); 246 Element genesElement = representGenesAsElement(a_subject.getGenes(), 250 a_xmlDocument); 251 chromosomeElement.appendChild(genesElement); 255 return chromosomeElement; 256 } 257 258 276 public static Element representGenotypeAsElement(final Genotype a_subject, 277 final Document a_xmlDocument) { 278 Population population = a_subject.getPopulation(); 279 Element genotypeTag = a_xmlDocument.createElement(GENOTYPE_TAG); 284 genotypeTag.setAttribute(SIZE_ATTRIBUTE, 285 Integer.toString(population.size())); 286 for (int i = 0; i < population.size(); i++) { 290 Element chromosomeElement 291 = representChromosomeAsElement(population.getChromosome(i), 292 a_xmlDocument); 293 genotypeTag.appendChild(chromosomeElement); 294 } 295 return genotypeTag; 296 } 297 298 318 public static Gene[] getGenesFromElement( 319 Configuration a_activeConfiguration, Element a_xmlElement) 320 throws ImproperXMLException, UnsupportedRepresentationException, 321 GeneCreationException { 322 if (a_xmlElement == null || 326 ! (a_xmlElement.getTagName().equals(GENES_TAG))) { 327 throw new ImproperXMLException( 328 "Unable to build Chromosome instance from XML Element: " + 329 "given Element is not a 'genes' element."); 330 } 331 List genes = Collections.synchronizedList(new ArrayList()); 332 NodeList geneElements = a_xmlElement.getElementsByTagName(GENE_TAG); 335 if (geneElements == null) { 336 throw new ImproperXMLException( 337 "Unable to build Gene instances from XML Element: " + 338 "'" + GENE_TAG + "'" + 339 " sub-elements not found."); 340 } 341 int numberOfGeneNodes = geneElements.getLength(); 347 for (int i = 0; i < numberOfGeneNodes; i++) { 348 Element thisGeneElement = (Element) geneElements.item(i); 349 thisGeneElement.normalize(); 350 String geneClassName = 354 thisGeneElement.getAttribute(CLASS_ATTRIBUTE); 355 Gene thisGeneObject; 356 Class geneClass = null; 357 try { 358 geneClass = Class.forName(geneClassName); 359 try { 360 Constructor constr = geneClass.getConstructor(new Class [] { 361 Configuration.class}); 362 thisGeneObject = (Gene) constr.newInstance(new Object [] { 363 a_activeConfiguration}); 364 } 365 catch (NoSuchMethodException nsme) { 366 Constructor constr = geneClass.getConstructor(new Class [] {}); 369 thisGeneObject = (Gene) constr.newInstance(new Object [] {}); 370 thisGeneObject = (Gene) PrivateAccessor.invoke(thisGeneObject, 371 "newGeneInternal", new Class [] {}, new Object [] {}); 372 } 373 } 374 catch (Throwable e) { 375 throw new GeneCreationException(geneClass, e); 376 } 377 NodeList children = thisGeneElement.getChildNodes(); 381 int childrenSize = children.getLength(); 382 String alleleRepresentation = null; 383 for (int j = 0; j < childrenSize; j++) { 384 Element alleleElem = (Element) children.item(j); 385 if (alleleElem.getTagName().equals(ALLELE_TAG)) { 386 alleleRepresentation = alleleElem.getAttribute("value"); 387 } 388 if (children.item(j).getNodeType() == Node.TEXT_NODE) { 389 alleleRepresentation = children.item(j).getNodeValue(); 392 break; 393 } 394 } 395 if (alleleRepresentation == null) { 398 throw new ImproperXMLException( 399 "Unable to build Gene instance from XML Element: " + 400 "value (allele) is missing representation."); 401 } 402 try { 406 thisGeneObject.setValueFromPersistentRepresentation( 407 alleleRepresentation); 408 } 409 catch (UnsupportedOperationException e) { 410 throw new GeneCreationException( 411 "Unable to build Gene because it does not support the " + 412 "setValueFromPersistentRepresentation() method."); 413 } 414 genes.add(thisGeneObject); 417 } 418 return (Gene[]) genes.toArray(new Gene[genes.size()]); 419 } 420 421 444 public static Chromosome getChromosomeFromElement( 445 Configuration a_activeConfiguration, Element a_xmlElement) 446 throws ImproperXMLException, InvalidConfigurationException, 447 UnsupportedRepresentationException, GeneCreationException { 448 if (a_xmlElement == null || 452 ! (a_xmlElement.getTagName().equals(CHROMOSOME_TAG))) { 453 throw new ImproperXMLException( 454 "Unable to build Chromosome instance from XML Element: " + 455 "given Element is not a 'chromosome' element."); 456 } 457 Element genesElement = (Element) 460 a_xmlElement.getElementsByTagName(GENES_TAG).item(0); 461 if (genesElement == null) { 462 throw new ImproperXMLException( 463 "Unable to build Chromosome instance from XML Element: " + 464 "'genes' sub-element not found."); 465 } 466 Gene[] geneAlleles = getGenesFromElement(a_activeConfiguration, 469 genesElement); 470 return new Chromosome(a_activeConfiguration, geneAlleles); 473 } 474 475 501 public static Genotype getGenotypeFromElement( 502 Configuration a_activeConfiguration, Element a_xmlElement) 503 throws ImproperXMLException, InvalidConfigurationException, 504 UnsupportedRepresentationException, GeneCreationException { 505 506 if (a_xmlElement == null || 509 ! (a_xmlElement.getTagName().equals(GENOTYPE_TAG))) { 510 throw new ImproperXMLException( 511 "Unable to build Genotype instance from XML Element: " + 512 "given Element is not a 'genotype' element."); 513 } 514 NodeList chromosomes = 518 a_xmlElement.getElementsByTagName(CHROMOSOME_TAG); 519 int numChromosomes = chromosomes.getLength(); 520 Population population = new Population(a_activeConfiguration, numChromosomes); 521 for (int i = 0; i < numChromosomes; i++) { 522 population.addChromosome(getChromosomeFromElement(a_activeConfiguration, 523 (Element) chromosomes.item(i))); 524 } 525 return new Genotype(a_activeConfiguration, population); 528 } 529 530 555 public static Genotype getGenotypeFromDocument( 556 Configuration a_activeConfiguration, Document a_xmlDocument) 557 throws ImproperXMLException, InvalidConfigurationException, 558 UnsupportedRepresentationException, GeneCreationException { 559 Element rootElement = a_xmlDocument.getDocumentElement(); 565 if (rootElement == null || 566 ! (rootElement.getTagName().equals(GENOTYPE_TAG))) { 567 throw new ImproperXMLException( 568 "Unable to build Genotype from XML Document: " + 569 "'genotype' element must be at root of document."); 570 } 571 return getGenotypeFromElement(a_activeConfiguration, rootElement); 572 } 573 574 599 public static Chromosome getChromosomeFromDocument(Configuration 600 a_activeConfiguration, Document a_xmlDocument) 601 throws ImproperXMLException, InvalidConfigurationException, 602 UnsupportedRepresentationException, GeneCreationException { 603 Element rootElement = a_xmlDocument.getDocumentElement(); 609 if (rootElement == null || 610 ! (rootElement.getTagName().equals(CHROMOSOME_TAG))) { 611 throw new ImproperXMLException( 612 "Unable to build Chromosome instance from XML Document: " + 613 "'chromosome' element must be at root of Document."); 614 } 615 return getChromosomeFromElement(a_activeConfiguration, rootElement); 616 } 617 618 628 public static Document readFile(File file) 629 throws IOException, org.xml.sax.SAXException { 630 return m_documentCreator.parse(file); 631 } 632 633 642 public static void writeFile(Document doc, File file) 643 throws IOException { 644 TransformerFactory tFactory = 646 TransformerFactory.newInstance(); 647 Transformer transformer; 648 try { 649 transformer = tFactory.newTransformer(); 650 } 651 catch (TransformerConfigurationException tex) { 652 throw new IOException(tex.getMessage()); 653 } 654 DOMSource source = new DOMSource(doc); 655 FileOutputStream fos = new FileOutputStream(file); 656 StreamResult result = new StreamResult(fos); 657 try { 658 transformer.transform(source, result); 659 fos.close(); 660 } 661 catch (TransformerException tex) { 662 throw new IOException(tex.getMessage()); 663 } 664 } 665 } 666 | Popular Tags |